Skip to content

Commit

Permalink
Fix bug with set_boundary() and clipping (Fixes SciTools#1620)
Browse files Browse the repository at this point in the history
We weren't set up to be able to update the transform and have that
propagate downstream because other parts of matplotlib grab a reference
to the Axes.patch transform. Therefore, use a TransformWrapper so we can
update.
  • Loading branch information
dopplershift committed Aug 22, 2020
1 parent 4d158c9 commit ea81f52
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 1 deletion.
13 changes: 12 additions & 1 deletion lib/cartopy/mpl/geoaxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,14 +235,25 @@ def __init__(self, axes, **kwargs):
super().__init__(self._original_path, **kwargs)
self._axes = axes

# We need to use a TransformWrapper as our transform so that we can
# update the transform without breaking others' references to this one.
self._trans_wrap = mtransforms.TransformWrapper(self.get_transform())

def set_transform(self, transform):
self._trans_wrap.set(transform)
super().set_transform(self._trans_wrap)

def set_boundary(self, path, transform):
self._original_path = path
self.set_transform(transform)
self.stale = True

def _adjust_location(self):
if self.stale:
self._path = self._original_path.clip_to_bbox(self.axes.viewLim)
self.set_path(self._original_path.clip_to_bbox(self.axes.viewLim))
# Some places in matplotlib's tranform stack cache the actual
# path so we trigger an update by invalidating the transform.
self._trans_wrap.invalidate()

@matplotlib.artist.allow_rasterization
def draw(self, renderer, *args, **kwargs):
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions lib/cartopy/tests/mpl/test_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,21 @@ def test_geoaxes_no_subslice():
lats = np.linspace(35, 37, num_points)
lons = np.linspace(-117, -115, num_points)
ax.plot(lons, lats, transform=ccrs.PlateCarree())


@ImageTesting(['geoaxes_set_boundary_clipping'])
def test_geoaxes_set_boundary_clipping():
"""Test that setting the boundary works properly for clipping #1620."""
lon, lat = np.meshgrid(np.linspace(-180., 180., 361),
np.linspace(-90., -60., 31))
fig = plt.figure()
ax1 = fig.add_subplot(1, 1, 1, projection=ccrs.SouthPolarStereo())

# Limit the map to -60 degrees latitude and below.
ax1.set_extent([-180, 180, -90, -60], ccrs.PlateCarree())
ax1.gridlines()

ax1.contourf(lon, lat, lat, transform=ccrs.PlateCarree())

ax1.set_boundary(mpath.Path.circle(center=(0.5, 0.5), radius=0.5),
transform=ax1.transAxes)

0 comments on commit ea81f52

Please sign in to comment.