From 913f1724fff8fb84825e7c5127e670a3cc0a0e42 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Sat, 3 Mar 2018 16:23:13 -0500 Subject: [PATCH] Backport PR #10613: FIX: resolution of imshow for floats and 2-D greyscale PIL images --- lib/matplotlib/image.py | 28 +++++++++++++++++- .../test_image/imshow_bignumbers_real.png | Bin 0 -> 3312 bytes lib/matplotlib/tests/test_image.py | 25 +++++++++++++++- 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 lib/matplotlib/tests/baseline_images/test_image/imshow_bignumbers_real.png diff --git a/lib/matplotlib/image.py b/lib/matplotlib/image.py index de87c2afaa44..f2a7280af553 100644 --- a/lib/matplotlib/image.py +++ b/lib/matplotlib/image.py @@ -396,6 +396,28 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0, # scaled data A_scaled = np.empty(A.shape, dtype=scaled_dtype) A_scaled[:] = A + # clip scaled data around norm if necessary. + # This is necessary for big numbers at the edge of + # float64's ability to represent changes. Applying + # a norm first would be good, but ruins the interpolation + # of over numbers. + if self.norm.vmin is not None and self.norm.vmax is not None: + dv = (np.float64(self.norm.vmax) - + np.float64(self.norm.vmin)) + vmid = self.norm.vmin + dv / 2 + newmin = vmid - dv * 1.e7 + if newmin < a_min: + newmin = None + else: + a_min = np.float64(newmin) + newmax = vmid + dv * 1.e7 + if newmax > a_max: + newmax = None + else: + a_max = np.float64(newmax) + if newmax is not None or newmin is not None: + A_scaled = np.clip(A_scaled, newmin, newmax) + A_scaled -= a_min # a_min and a_max might be ndarray subclasses so use # asscalar to ensure they are scalars to avoid errors @@ -614,7 +636,11 @@ def set_data(self, A): """ # check if data is PIL Image without importing Image if hasattr(A, 'getpixel'): - self._A = pil_to_array(A) + if A.mode == 'L': + # greyscale image, but our logic assumes rgba: + self._A = pil_to_array(A.convert('RGBA')) + else: + self._A = pil_to_array(A) else: self._A = cbook.safe_masked_invalid(A, copy=True) diff --git a/lib/matplotlib/tests/baseline_images/test_image/imshow_bignumbers_real.png b/lib/matplotlib/tests/baseline_images/test_image/imshow_bignumbers_real.png new file mode 100644 index 0000000000000000000000000000000000000000..ce3404488ebb88daece7f11dc5ba9519bccb6766 GIT binary patch literal 3312 zcmeH~ZA_C_6vt1yrYpt@lO?F-r3t$Ed$Rz@k*QajT^TRMeO+U~(G`?3$)M>bA!b8}Db z$<00a-TyiF@^Q`w#7#Rk0RS=mNZLmLSOoxPmVie+aZe0$=!7dxO+P_EO+v_TK-WRS zBfL_8;M}!=`Ig;PfI3fz4xJKxjGPx$OG*onA~J)@pwdh7 zVyHr-RK$p*Q}g-d^!EfY^jQ7@Ml2(jLcSmp2@`3wzhbFKiGb!m8LI}^%t%i=ctYGU zKXvfCGx{2hDf(rczV6PCIpf3q`N9@r{?B=|uj&UCkxN@X+4=|h_?2<`v2i@(D89y6 zbEEiC;mNyG^T*z=+K$^hzGG+RUdigRG|Dg{z2MYiZbVs+awAbgue_Zr2nLwd>;ep& z!;vAS5pdA(jshSC8v^9RfQ1Ky6i{r#5FjLaW7EG&!B5k6O!LEg-FavAHm^)aPbNRcrX7FJ7fveU{ysXLU!mRjUP z7VfTf!-3&Zr1SHew#27pgG1TWw#yd*j8{o-Quu7XTrW`1=#)6P^#vGah0I2`MY6Bcy%Q9VBv@k(ueFz= zwQombeju(Nq5E6FQJTd`OFi9*aTZx=|DTvDN)5;X3CH8!u2?_`I>(6qNvAAS`~JiT(x+{|~vl+nzid!_$}D zv{gyfXQ-ii6joBaf)w7Y>7API*2&OH83Z}|G5sSZ;Wn$=v(mxonrs0$;6|DMj{vT- zy0hheb%1?w>wv}UP`4*zjLwxQwoVC%*e93!?ys6mxr^5-l}Vq;mq>#WPl;g$t$i3U z42NY)Vpv|g3RQs+1!>iZcmDc)rg?(Pj>wjIENGbwZA+G+HN?K;El#{X=C8t0T6bzr?Vm7^lmP$$ literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/test_image.py b/lib/matplotlib/tests/test_image.py index 16be520e325f..26e3b4a7ea26 100644 --- a/lib/matplotlib/tests/test_image.py +++ b/lib/matplotlib/tests/test_image.py @@ -511,6 +511,18 @@ def test_nonuniformimage_setnorm(): im.set_norm(plt.Normalize()) +@needs_pillow +def test_jpeg_2d(): + # smoke test that mode-L pillow images work. + imd = np.ones((10, 10), dtype='uint8') + for i in range(10): + imd[i, :] = np.linspace(0.0, 1.0, 10) * 255 + im = Image.new('L', (10, 10)) + im.putdata(imd.flatten()) + fig, ax = plt.subplots() + ax.imshow(im) + + @needs_pillow def test_jpeg_alpha(): plt.figure(figsize=(1, 1), dpi=300) @@ -855,7 +867,18 @@ def test_imshow_bignumbers(): img = np.array([[1, 2, 1e12],[3, 1, 4]], dtype=np.uint64) pc = ax.imshow(img) pc.set_clim(0, 5) - plt.show() + + +@image_comparison(baseline_images=['imshow_bignumbers_real'], + remove_text=True, style='mpl20', + extensions=['png']) +def test_imshow_bignumbers_real(): + # putting a big number in an array of integers shouldn't + # ruin the dynamic range of the resolved bits. + fig, ax = plt.subplots() + img = np.array([[2., 1., 1.e22],[4., 1., 3.]]) + pc = ax.imshow(img) + pc.set_clim(0, 5) @pytest.mark.parametrize( pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy