Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b511bb2

Browse files
authored
Merge pull request #10133 from jklymak/fix-image-scaling
FIX: Image scaling for large dynamic range ints
2 parents e8c57c5 + 9ba75dc commit b511bb2

File tree

3 files changed

+32
-8
lines changed

3 files changed

+32
-8
lines changed

lib/matplotlib/image.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -364,17 +364,25 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
364364

365365
# TODO slice input array first
366366
inp_dtype = A.dtype
367-
if inp_dtype.kind == 'f':
368-
scaled_dtype = A.dtype
369-
else:
370-
scaled_dtype = np.float32
371-
372367
a_min = A.min()
368+
a_max = A.max()
369+
# figure out the type we should scale to. For floats,
370+
# leave as is. For integers cast to an appropriate-sized
371+
# float. Small integers get smaller floats in an attempt
372+
# to keep the memory footprint reasonable.
373373
if a_min is np.ma.masked:
374-
a_min, a_max = 0, 1 # all masked, so values don't matter
374+
# all masked, so values don't matter
375+
a_min, a_max = np.int32(0), np.int32(1)
376+
if inp_dtype.kind == 'f':
377+
scaled_dtype = A.dtype
375378
else:
376-
a_min = a_min.astype(scaled_dtype)
377-
a_max = A.max().astype(scaled_dtype)
379+
# probably an integer of some type.
380+
da = a_max.astype(np.float64) - a_min.astype(np.float64)
381+
if da > 1e8:
382+
# give more breathing room if a big dynamic range
383+
scaled_dtype = np.float64
384+
else:
385+
scaled_dtype = np.float32
378386

379387
# scale the input data to [.1, .9]. The Agg
380388
# interpolators clip to [0, 1] internally, use a
@@ -386,6 +394,9 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
386394
A_scaled = np.empty(A.shape, dtype=scaled_dtype)
387395
A_scaled[:] = A
388396
A_scaled -= a_min
397+
a_min = a_min.astype(scaled_dtype)
398+
a_max = a_max.astype(scaled_dtype)
399+
389400
if a_min != a_max:
390401
A_scaled /= ((a_max - a_min) / 0.8)
391402
A_scaled += 0.1

lib/matplotlib/tests/test_image.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,19 @@ def test_imshow_flatfield():
804804
im.set_clim(.5, 1.5)
805805

806806

807+
@image_comparison(baseline_images=['imshow_bignumbers'],
808+
remove_text=True, style='mpl20',
809+
extensions=['png'])
810+
def test_imshow_bignumbers():
811+
# putting a big number in an array of integers shouldn't
812+
# ruin the dynamic range of the resolved bits.
813+
fig, ax = plt.subplots()
814+
img = np.array([[1, 2, 1e12],[3, 1, 4]], dtype=np.uint64)
815+
pc = ax.imshow(img)
816+
pc.set_clim(0, 5)
817+
plt.show()
818+
819+
807820
@pytest.mark.parametrize(
808821
"make_norm",
809822
[colors.Normalize,

0 commit comments

Comments
 (0)