Skip to content

Commit f49c7b3

Browse files
authored
Merge pull request #10768 from jinshifen33/bugfix-for-issue-10342
Fix crash when imshow encounters longdouble data
2 parents 7fdc831 + 809353c commit f49c7b3

File tree

3 files changed

+13
-8
lines changed

3 files changed

+13
-8
lines changed

lib/matplotlib/colors.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -954,11 +954,6 @@ def __call__(self, value, clip=None):
954954
resdat -= vmin
955955
resdat /= (vmax - vmin)
956956
result = np.ma.array(resdat, mask=result.mask, copy=False)
957-
# Agg cannot handle float128. We actually only need 32-bit of
958-
# precision, but on Windows, `np.dtype(np.longdouble) == np.float64`,
959-
# so casting to float32 would lose precision on float64s as well.
960-
if result.dtype == np.longdouble:
961-
result = result.astype(np.float64)
962957
if is_scalar:
963958
result = result[0]
964959
return result

lib/matplotlib/image.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from math import ceil
1313
import os
1414
import logging
15+
import warnings
1516

1617
import numpy as np
1718

@@ -264,8 +265,8 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
264265
and magnified by the magnification factor.
265266
266267
`A` may be a greyscale image (MxN) with a dtype of `float32`,
267-
`float64`, `uint16` or `uint8`, or an RGBA image (MxNx4) with
268-
a dtype of `float32`, `float64`, or `uint8`.
268+
`float64`, `float128`, `uint16` or `uint8`, or an RGBA image (MxNx4)
269+
with a dtype of `float32`, `float64`, `float128`, or `uint8`.
269270
270271
If `unsampled` is True, the image will not be scaled, but an
271272
appropriate affine transformation will be returned instead.
@@ -361,6 +362,13 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
361362
a_min, a_max = np.int32(0), np.int32(1)
362363
if inp_dtype.kind == 'f':
363364
scaled_dtype = A.dtype
365+
# Cast to float64
366+
if A.dtype not in (np.float32, np.float16):
367+
if A.dtype != np.float64:
368+
warnings.warn(
369+
"Casting input data from '{0}' to 'float64'"
370+
"for imshow".format(A.dtype))
371+
scaled_dtype = np.float64
364372
else:
365373
# probably an integer of some type.
366374
da = a_max.astype(np.float64) - a_min.astype(np.float64)
@@ -386,7 +394,7 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
386394
# of over numbers.
387395
if self.norm.vmin is not None and self.norm.vmax is not None:
388396
dv = (np.float64(self.norm.vmax) -
389-
np.float64(self.norm.vmin))
397+
np.float64(self.norm.vmin))
390398
vmid = self.norm.vmin + dv / 2
391399
newmin = vmid - dv * 1.e7
392400
if newmin < a_min:

lib/matplotlib/tests/test_image.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,8 @@ def test_empty_imshow(make_norm):
903903
def test_imshow_float128():
904904
fig, ax = plt.subplots()
905905
ax.imshow(np.zeros((3, 3), dtype=np.longdouble))
906+
# Ensure that drawing doesn't cause crash
907+
fig.canvas.draw()
906908

907909

908910
def test_imshow_bool():

0 commit comments

Comments
 (0)