Skip to content

Commit

Permalink
Merge pull request #1958 from greglucas/pcolormesh-bbox
Browse files Browse the repository at this point in the history
FIX: Calculate bbox for pcolormesh
  • Loading branch information
dopplershift authored Dec 13, 2021
2 parents 55b7b5f + 3d82245 commit 64ac172
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 6 deletions.
25 changes: 19 additions & 6 deletions lib/cartopy/mpl/geoaxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1794,10 +1794,6 @@ def _wrap_quadmesh(self, collection, **kwargs):
cross the boundary of the projection.
"""
t = kwargs.get('transform', None)
if not (getattr(t, '_wrappable', False) and
getattr(self.projection, '_wrappable', False)):
# Nothing to do
return collection

# Get the quadmesh data coordinates
coords = collection._coordinates
Expand Down Expand Up @@ -1833,8 +1829,25 @@ def _wrap_quadmesh(self, collection, **kwargs):
np.isnan(diagonal1_lengths) |
(diagonal1_lengths > size_limit))

if not np.any(mask):
# No wrapping needed
# Update the data limits based on the corners of the mesh
# in transformed coordinates, ignoring nan values
with warnings.catch_warnings():
warnings.filterwarnings('ignore', 'All-NaN slice encountered')
# If we have all nans, that is OK and will be handled by the
# Bbox calculations later, so suppress that warning from the user
corners = ((np.nanmin(xs), np.nanmin(ys)),
(np.nanmax(xs), np.nanmax(ys)))
collection._corners = mtransforms.Bbox(corners)
self.update_datalim(collection._corners)

# We need to keep the transform/projection check after
# update_datalim to make sure we are getting the proper
# datalims on the returned collection
if (not (getattr(t, '_wrappable', False) and
getattr(self.projection, '_wrappable', False)) or
not np.any(mask)):
# If both projections are unwrappable
# or if there aren't any points to wrap
return collection

# Wrapping with gouraud shading is error-prone. We will do our best,
Expand Down
5 changes: 5 additions & 0 deletions lib/cartopy/mpl/geocollection.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,8 @@ def set_clim(self, vmin=None, vmax=None):

# Update color limits for the rest of the cells.
super().set_clim(vmin, vmax)

def get_datalim(self, transData):
# Return the corners that were calculated in
# the pcolormesh routine.
return self._corners
43 changes: 43 additions & 0 deletions lib/cartopy/tests/mpl/test_pseudo_color.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,46 @@ def test_pcolormesh_arg_interpolation():
[2, 20],
[4, 20]]])
np.testing.assert_array_almost_equal(expected, coll._coordinates)


def test_pcolormesh_datalim():
# Test that wrapping the coordinates still produces proper data limits
x = [359, 1, 3]
y = [-10, 10]

xs, ys = np.meshgrid(x, y)
# Z with the same shape as X/Y to force the interpolation
z = np.zeros(xs.shape)

ax = plt.subplot(2, 1, 1, projection=ccrs.PlateCarree())
coll = ax.pcolormesh(xs, ys, z, shading='auto',
transform=ccrs.PlateCarree())

coll_bbox = coll.get_datalim(ax.transData)
np.testing.assert_array_equal(coll_bbox, [[-2, -20], [4, 20]])

# Non-wrapped coordinates
x = [-80, 0, 80]
y = [-10, 10]

xs, ys = np.meshgrid(x, y)
ax = plt.subplot(2, 1, 1, projection=ccrs.PlateCarree())
coll = ax.pcolormesh(xs, ys, z, shading='auto',
transform=ccrs.PlateCarree())

coll_bbox = coll.get_datalim(ax.transData)
np.testing.assert_array_equal(coll_bbox, [[-120, -20], [120, 20]])

# A projection that doesn't support wrapping
x = [-10, 0, 10]
y = [-10, 10]

xs, ys = np.meshgrid(x, y)
ax = plt.subplot(2, 1, 1, projection=ccrs.Orthographic())
coll = ax.pcolormesh(xs, ys, z, shading='auto',
transform=ccrs.PlateCarree())

coll_bbox = coll.get_datalim(ax.transData)
expected = [[-1650783.327873, -2181451.330891],
[1650783.327873, 2181451.330891]]
np.testing.assert_array_almost_equal(coll_bbox, expected)

0 comments on commit 64ac172

Please sign in to comment.