Skip to content

Commit 9fba5a5

Browse files
committed
fix warping of curvilinear grid cells for datagrid
1 parent 73b8bde commit 9fba5a5

1 file changed

Lines changed: 40 additions & 6 deletions

File tree

psy_maps/plotters.py

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1679,6 +1679,10 @@ def _polycolor(self):
16791679
# However, in order to wrap the boundaries correctly, we have to
16801680
# identify the corresponding grid cells and then use the standard
16811681
# matplotlib transform.
1682+
if xb.ndim > 2:
1683+
xb = xb.reshape((-1, xb.shape[-1]))
1684+
yb = yb.reshape((-1, yb.shape[-1]))
1685+
arr = arr.reshape(-1)
16821686
if isinstance(t, wrap_proj_types) and 'lon_0' in proj.proj4_params:
16831687
# We adopt and copy some code from the methodology of cartopy
16841688
# _pcolormesh_patched method of the geoaxes. As such, we
@@ -1717,9 +1721,6 @@ def _polycolor(self):
17171721
yb_wrap = yb[mask]
17181722
xb = xb[~mask]
17191723
yb = yb[~mask]
1720-
if xb.ndim > 2:
1721-
xb = xb.reshape((-1, xb.shape[-1]))
1722-
yb = yb.reshape((-1, yb.shape[-1]))
17231724
self.logger.debug('Making plot with %i cells', arr.size)
17241725
transformed = proj.transform_points(
17251726
t, xb.ravel(), yb.ravel())[..., :2].reshape(xb.shape + (2,))
@@ -1791,6 +1792,11 @@ def update(self, value):
17911792
proj = self.ax.projection
17921793
# HACK: We remove the cells at the boundary of the map projection
17931794
xb_wrap = None
1795+
1796+
if xb.ndim > 2:
1797+
xb = xb.reshape((-1, xb.shape[-1]))
1798+
yb = yb.reshape((-1, yb.shape[-1]))
1799+
17941800
if isinstance(t, wrap_proj_types) and 'lon_0' in proj.proj4_params:
17951801
# See the :meth:`MapPlot2D._polycolor` method for a documentation
17961802
# of the steps
@@ -1822,20 +1828,48 @@ def update(self, value):
18221828
transformed = proj.transform_points(t, xb.ravel(), yb.ravel())
18231829
xb = transformed[..., 0].reshape(orig_shape)
18241830
yb = transformed[..., 1].reshape(orig_shape)
1825-
if xb.ndim > 2:
1826-
xb = xb.reshape((-1, xb.shape[-1]))
1827-
yb = yb.reshape((-1, yb.shape[-1]))
18281831
# We insert nan values in the flattened edges arrays rather than
18291832
# plotting the grid cells separately as it considerably speeds-up code
18301833
# execution.
18311834
n = len(xb)
18321835
xb = np.c_[xb, xb[:, :1], [[np.nan]] * n].ravel()
18331836
yb = np.c_[yb, yb[:, :1], [[np.nan]] * n].ravel()
1837+
18341838
if isinstance(value, dict):
18351839
self._artists = self.ax.plot(xb, yb, **value)
18361840
else:
18371841
self._artists = self.ax.plot(xb, yb, value)
1842+
18381843
if xb_wrap is not None:
1844+
# first we drop all grid cells that have any NaN in their bounds
1845+
# as we do not know, how to handle these
1846+
valid = (~np.isnan(xb_wrap).any(-1)) & (~np.isnan(yb_wrap).any(-1))
1847+
xb_wrap = xb_wrap[valid]
1848+
yb_wrap = yb_wrap[valid]
1849+
1850+
if isinstance(t, ccrs.PlateCarree):
1851+
1852+
# identify the grid cells at the boundary
1853+
xdiff2min = xb_wrap - xb_wrap.min(axis=-1, keepdims=True)
1854+
cross_world_mask = np.any(np.abs(xdiff2min) > 180, -1)
1855+
if cross_world_mask.any():
1856+
cross_world_x = xb_wrap[cross_world_mask]
1857+
cross_world_y = yb_wrap[cross_world_mask]
1858+
cross_world_diff = xdiff2min[cross_world_mask]
1859+
xdiff2max = cross_world_x - cross_world_x.max(
1860+
axis=-1, keepdims=True)
1861+
1862+
leftx = cross_world_x.copy()
1863+
leftx[cross_world_diff > 180] -= 360
1864+
1865+
rightx = cross_world_x.copy()
1866+
rightx[xdiff2max < -180] += 360
1867+
1868+
xb_wrap = np.r_[xb_wrap[~cross_world_mask], leftx, rightx]
1869+
yb_wrap = np.r_[
1870+
yb_wrap[~cross_world_mask], cross_world_y, cross_world_y
1871+
]
1872+
18391873
n = len(xb_wrap)
18401874
xb_wrap = np.c_[xb_wrap, xb_wrap[:, :1], [[np.nan]] * n].ravel()
18411875
yb_wrap = np.c_[yb_wrap, yb_wrap[:, :1], [[np.nan]] * n].ravel()

0 commit comments

Comments
 (0)