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

Skip to content

Commit 067f9b6

Browse files
authored
Merge pull request #8024 from tacaswell/fix_ishow_masked_interpolation
Fix imshow masked interpolation
2 parents 200c455 + 1a7c4ef commit 067f9b6

7 files changed

Lines changed: 266 additions & 10 deletions

File tree

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ before_install:
7575

7676
install:
7777
- ccache -s
78+
- git describe
7879
# Upgrade pip and setuptools. Mock has issues with the default version of
7980
# setuptools
8081
- |

lib/matplotlib/image.py

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -375,9 +375,20 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
375375
# this is to work around spurious warnings coming
376376
# out of masked arrays.
377377
with np.errstate(invalid='ignore'):
378-
rgba[..., 1] = A < 0 # under data
379-
rgba[..., 2] = A > 1 # over data
380-
rgba[..., 3] = ~A.mask # bad data
378+
rgba[..., 1] = np.where(A < 0, np.nan, 1) # under data
379+
rgba[..., 2] = np.where(A > 1, np.nan, 1) # over data
380+
# Have to invert mask, Agg knows what alpha means
381+
# so if you put this in as 0 for 'good' points, they
382+
# all get zeroed out
383+
rgba[..., 3] = 1
384+
if A.mask.shape == A.shape:
385+
# this is the case of a nontrivial mask
386+
mask = np.where(A.mask, np.nan, 1)
387+
else:
388+
# this is the case that the mask is a
389+
# numpy.bool_ of False
390+
mask = A.mask
391+
# ~A.mask # masked data
381392
A = rgba
382393
output = np.zeros((out_height, out_width, 4),
383394
dtype=A.dtype)
@@ -418,12 +429,37 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
418429
# Convert back to a masked greyscale array so
419430
# colormapping works correctly
420431
hid_output = output
432+
# any pixel where the a masked pixel is included
433+
# in the kernel (pulling this down from 1) needs to
434+
# be masked in the output
435+
if len(mask.shape) == 2:
436+
out_mask = np.empty((out_height, out_width),
437+
dtype=mask.dtype)
438+
_image.resample(mask, out_mask, t,
439+
_interpd_[self.get_interpolation()],
440+
True, 1,
441+
self.get_filternorm() or 0.0,
442+
self.get_filterrad() or 0.0)
443+
out_mask = np.isnan(out_mask)
444+
else:
445+
out_mask = mask
446+
# we need to mask both pixels which came in as masked
447+
# and the pixels that Agg is telling us to ignore (relavent
448+
# to non-affine transforms)
449+
# Use half alpha as the threshold for pixels to mask.
450+
out_mask = out_mask | (hid_output[..., 3] < .5)
421451
output = np.ma.masked_array(
422-
hid_output[..., 0], hid_output[..., 3] < 0.5)
423-
# relabel under data
424-
output[hid_output[..., 1] > .5] = -1
452+
hid_output[..., 0],
453+
out_mask)
454+
# 'unshare' the mask array to
455+
# needed to suppress numpy warning
456+
del out_mask
457+
invalid_mask = ~output.mask * ~np.isnan(output.data)
458+
# relabel under data. If any of the input data for
459+
# the pixel has input out of the norm bounds,
460+
output[np.isnan(hid_output[..., 1]) * invalid_mask] = -1
425461
# relabel over data
426-
output[hid_output[..., 2] > .5] = 2
462+
output[np.isnan(hid_output[..., 2]) * invalid_mask] = 2
427463

428464
output = self.to_rgba(output, bytes=True, norm=False)
429465

Binary file not shown.
18.8 KB
Loading

lib/matplotlib/tests/baseline_images/test_image/imshow_masked_interpolation.svg

Lines changed: 185 additions & 0 deletions
Loading
36 Bytes
Loading

lib/matplotlib/tests/test_image.py

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,8 @@
2626
from matplotlib.testing.noseclasses import KnownFailureTest
2727
from copy import copy
2828
from numpy import ma
29+
import matplotlib.image as mimage
2930
import matplotlib.colors as colors
30-
import matplotlib.pyplot as plt
31-
import matplotlib.mlab as mlab
32-
import numpy as np
3331

3432
import nose
3533
import nose.tools
@@ -61,6 +59,7 @@ def test_image_interps():
6159
ax3.imshow(X, interpolation='bicubic')
6260
ax3.set_ylabel('bicubic')
6361

62+
6463
@image_comparison(baseline_images=['interp_nearest_vs_none'],
6564
extensions=['pdf', 'svg'], remove_text=True)
6665
def test_interp_nearest_vs_none():
@@ -758,6 +757,41 @@ def test_imshow_endianess():
758757
ax2.imshow(Z.astype('>f8'), **kwargs)
759758

760759

760+
@image_comparison(baseline_images=['imshow_masked_interpolation'],
761+
remove_text=True, style='default')
762+
def test_imshow_masked_interpolation():
763+
764+
cm = copy(plt.get_cmap('viridis'))
765+
cm.set_over('r')
766+
cm.set_under('b')
767+
cm.set_bad('k')
768+
769+
N = 20
770+
n = colors.Normalize(vmin=0, vmax=N*N-1)
771+
772+
# data = np.random.random((N, N))*N*N
773+
data = np.arange(N*N, dtype='float').reshape(N, N)
774+
775+
data[5, 5] = -1
776+
777+
data[15, 5] = 1e5
778+
779+
# data[3, 3] = np.nan
780+
781+
data[15, 15] = np.inf
782+
783+
mask = np.zeros_like(data).astype('bool')
784+
mask[5, 15] = True
785+
786+
data = np.ma.masked_array(data, mask)
787+
788+
fig, ax_grid = plt.subplots(3, 6)
789+
for interp, ax in zip(sorted(mimage._interpd_), ax_grid.ravel()):
790+
ax.set_title(interp)
791+
ax.imshow(data, norm=n, cmap=cm, interpolation=interp)
792+
ax.axis('off')
793+
794+
761795
@cleanup
762796
def test_imshow_no_warn_invalid():
763797
with warnings.catch_warnings(record=True) as warns:

0 commit comments

Comments
 (0)