Fix imshow edges#8300
Conversation
- add a cleanup decorator out of paranoia - deepcopy rather than copy colormaps that we mutate
Only mask out as 'bad' pixels which have alpha == 0
a23a397 to
44b4097
Compare
|
This does not seem to fix the problem 😞 |
|
@QuLogic We are going to unblock this for 2.0.1 to prevent the perfect from becoming the enemy of the good. |
|
So I've had a chance to confirm that this PR does not correct the issue with Cartopy. Is there hope for pursuing an amendment to this PR or do you think a completely different approach is needed? |
|
I am not sure, still suspect that this is the right general direction, but it will depend on exactly what cartopy is feeding in (which I could not dig through the layers to sort out). |
|
I extracted the data and outline path used by Cartopy and put it into a gist here that uses only Matplotlib. Here's the blue image with 2.0.0: |
|
On a bit deeper inspection I am not sure if this is something that can / should be fixed on the matplotlib side. Tweaking the example a bit I think the issue is that the data / mask are a few pixel too small. Marking the bad pixels as pink and zooming in gives (ignoring the non-clipping of the patch) and eroding the mask (because high is the pixels to exclude) by 2 gives import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import matplotlib.path as mpath
import os
import scipy.ndimage.morphology
import matplotlib.cm as mcm
plt.style.use('classic')
# os.chdir('/tmp/b8ebfd6e1bfc304d39487750bc2a48be')
data = np.load('cp-data.npz')
path = mpath.Path(vertices=data['verts'], codes=data['codes'],
_interpolation_steps=data['steps'], readonly=data['ro'])
imshow_kwargs = {
'vmin': None,
'vmax': None,
'resample': None,
'filterrad': 4.0,
'alpha': None,
'filternorm': 1,
'aspect': None,
'interpolation': 'none',
'cmap': None,
'data': None,
'url': None,
'shape': None,
'extent': [-20037508.342789244, 20037508.342789244,
-8683259.716434667, 8683259.716434667],
'norm': None,
'imlim': None,
'origin': 'lower'
}
for color in ['fc', 'red', 'green', 'blue']:
mask = data[color + '_mask']
# mask = scipy.ndimage.morphology.binary_erosion(mark, iterations=2)
img = np.ma.MaskedArray(data[color + '_data'], mask)
fig, ax = plt.subplots(figsize=(10, 5))
background = mpatches.PathPatch(path, edgecolor='none', facecolor='red',
zorder=-1, clip_on=False,
transform=ax.transData)
ax.add_patch(background)
outline = mpatches.PathPatch(path, edgecolor='black', facecolor='none',
zorder=2.5, clip_on=False,
transform=ax.transData)
ax.add_patch(outline)
# Not necessary?
ax.patch = background
if color != 'fc':
cmap = mcm.get_cmap(color.title() + 's')
cmap.set_bad('pink')
imshow_kwargs['cmap'] = cmap
else:
imshow_kwargs['cmap'] = None
ax.imshow(img, **imshow_kwargs)
ax.set_title('%s %s' % (color, mpl.__version__))
fig.savefig('result-' + color + '.png')
plt.show() |
|
From what I can tell, Cartopy determines the mask from the points that don't transform back to a valid point in the source domain. But since this is |
|
Super-sceded by #8966 |




attn @QuLogic