Skip to content

Commit cc55f83

Browse files
authored
Merge pull request #10664 from matplotlib/auto-backport-of-pr-10613
Backport PR #10613 on branch v2.2.x
2 parents 037b176 + 913f172 commit cc55f83

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed

lib/matplotlib/image.py

+27-1
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,28 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
396396
# scaled data
397397
A_scaled = np.empty(A.shape, dtype=scaled_dtype)
398398
A_scaled[:] = A
399+
# clip scaled data around norm if necessary.
400+
# This is necessary for big numbers at the edge of
401+
# float64's ability to represent changes. Applying
402+
# a norm first would be good, but ruins the interpolation
403+
# of over numbers.
404+
if self.norm.vmin is not None and self.norm.vmax is not None:
405+
dv = (np.float64(self.norm.vmax) -
406+
np.float64(self.norm.vmin))
407+
vmid = self.norm.vmin + dv / 2
408+
newmin = vmid - dv * 1.e7
409+
if newmin < a_min:
410+
newmin = None
411+
else:
412+
a_min = np.float64(newmin)
413+
newmax = vmid + dv * 1.e7
414+
if newmax > a_max:
415+
newmax = None
416+
else:
417+
a_max = np.float64(newmax)
418+
if newmax is not None or newmin is not None:
419+
A_scaled = np.clip(A_scaled, newmin, newmax)
420+
399421
A_scaled -= a_min
400422
# a_min and a_max might be ndarray subclasses so use
401423
# asscalar to ensure they are scalars to avoid errors
@@ -614,7 +636,11 @@ def set_data(self, A):
614636
"""
615637
# check if data is PIL Image without importing Image
616638
if hasattr(A, 'getpixel'):
617-
self._A = pil_to_array(A)
639+
if A.mode == 'L':
640+
# greyscale image, but our logic assumes rgba:
641+
self._A = pil_to_array(A.convert('RGBA'))
642+
else:
643+
self._A = pil_to_array(A)
618644
else:
619645
self._A = cbook.safe_masked_invalid(A, copy=True)
620646

lib/matplotlib/tests/test_image.py

+24-1
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,18 @@ def test_nonuniformimage_setnorm():
511511
im.set_norm(plt.Normalize())
512512

513513

514+
@needs_pillow
515+
def test_jpeg_2d():
516+
# smoke test that mode-L pillow images work.
517+
imd = np.ones((10, 10), dtype='uint8')
518+
for i in range(10):
519+
imd[i, :] = np.linspace(0.0, 1.0, 10) * 255
520+
im = Image.new('L', (10, 10))
521+
im.putdata(imd.flatten())
522+
fig, ax = plt.subplots()
523+
ax.imshow(im)
524+
525+
514526
@needs_pillow
515527
def test_jpeg_alpha():
516528
plt.figure(figsize=(1, 1), dpi=300)
@@ -855,7 +867,18 @@ def test_imshow_bignumbers():
855867
img = np.array([[1, 2, 1e12],[3, 1, 4]], dtype=np.uint64)
856868
pc = ax.imshow(img)
857869
pc.set_clim(0, 5)
858-
plt.show()
870+
871+
872+
@image_comparison(baseline_images=['imshow_bignumbers_real'],
873+
remove_text=True, style='mpl20',
874+
extensions=['png'])
875+
def test_imshow_bignumbers_real():
876+
# putting a big number in an array of integers shouldn't
877+
# ruin the dynamic range of the resolved bits.
878+
fig, ax = plt.subplots()
879+
img = np.array([[2., 1., 1.e22],[4., 1., 3.]])
880+
pc = ax.imshow(img)
881+
pc.set_clim(0, 5)
859882

860883

861884
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)