Skip to content

Commit 95fe2ad

Browse files
committed
add grid polygons, support geodetic crs
1 parent a13ddca commit 95fe2ad

2 files changed

Lines changed: 62 additions & 25 deletions

File tree

uxarray/plot/accessor.py

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
import cartopy.crs as ccrs
88
import hvplot.pandas
99
import hvplot.xarray
10+
import numpy as np
1011
import pandas as pd
1112

1213
import uxarray.plot.dataarray_plot as dataarray_plot
1314
import uxarray.plot.utils
15+
from uxarray.plot.utils import check_crs
1416

1517
if TYPE_CHECKING:
1618
from uxarray.core.dataarray import UxDataArray
@@ -169,6 +171,9 @@ def edges(
169171
periodic_elements="exclude",
170172
backend=None,
171173
engine="spatialpandas",
174+
rasterize=False,
175+
geo=True,
176+
clabel="edges",
172177
**kwargs,
173178
):
174179
"""Plots the edges of a Grid.
@@ -203,36 +208,57 @@ def edges(
203208
-------
204209
gdf.hvplot.paths : hvplot.paths
205210
A paths plot of the edges of the unstructured grid
211+
:param rasterize:
206212
"""
207213
uxarray.plot.utils.backend.assign(backend)
208214

209-
if "rasterize" not in kwargs:
210-
kwargs["rasterize"] = False
211-
if "projection" not in kwargs:
212-
kwargs["projection"] = ccrs.PlateCarree()
213-
if "clabel" not in kwargs:
214-
kwargs["clabel"] = "edges"
215-
if "crs" not in kwargs:
216-
if "projection" in kwargs:
217-
central_longitude = kwargs["projection"].proj4_params["lon_0"]
218-
else:
219-
central_longitude = 0.0
220-
kwargs["crs"] = ccrs.PlateCarree(central_longitude=central_longitude)
215+
kwargs, periodic_elements = check_crs(kwargs, periodic_elements)
221216

222217
gdf = self._uxgrid.to_geodataframe(
223218
periodic_elements=periodic_elements,
224-
projection=kwargs.get("projection"),
219+
projection=kwargs.get("projection", ccrs.PlateCarree()),
225220
engine=engine,
226221
project=False,
227222
)
228223

229-
return gdf.hvplot.paths(geo=True, **kwargs)
224+
return gdf.hvplot.paths(rasterize=rasterize, geo=geo, clabel=clabel, **kwargs)
230225

231-
def mesh(self, periodic_elements="exclude", backend=None, **kwargs):
232-
return self.edges(periodic_elements, backend, **kwargs)
226+
def mesh(self, *args, **kwargs):
227+
return self.edges(*args, **kwargs)
233228

234229
mesh.__doc__ = edges.__doc__
235230

231+
def polygons(
232+
self,
233+
periodic_elements="exclude",
234+
backend=None,
235+
engine="spatialpandas",
236+
rasterize=False,
237+
geo=True,
238+
clabel="face index",
239+
cmap="viridis",
240+
**kwargs,
241+
):
242+
"""Plots the faces of the grid as polygons, shaded by their index."""
243+
uxarray.plot.utils.backend.assign(backend)
244+
245+
kwargs, periodic_elements = check_crs(kwargs, periodic_elements)
246+
247+
gdf = self._uxgrid.to_geodataframe(
248+
periodic_elements=periodic_elements,
249+
projection=kwargs.get("projection", ccrs.PlateCarree()),
250+
engine=engine,
251+
project=False,
252+
)
253+
254+
# Use the index of each face as its color
255+
data = np.arange(self._uxgrid.n_face)
256+
gdf = gdf.assign(data=data)
257+
258+
return gdf.hvplot.polygons(
259+
c="data", cmap=cmap, rasterize=rasterize, geo=geo, clabel=clabel, **kwargs
260+
)
261+
236262
def face_degree_distribution(
237263
self,
238264
backend=None,
@@ -351,7 +377,6 @@ def polygons(
351377
engine: Optional[str] = "spatialpandas",
352378
rasterize: Optional[bool] = True,
353379
dynamic: Optional[bool] = False,
354-
projection: Optional[ccrs.Projection] = None,
355380
xlabel: Optional[str] = "Longitude",
356381
ylabel: Optional[str] = "Latitude",
357382
*args,
@@ -392,18 +417,15 @@ def polygons(
392417
"""
393418
uxarray.plot.utils.backend.assign(backend)
394419

395-
if dynamic and (projection is not None or kwargs.get("geo", None) is True):
420+
if dynamic and (
421+
kwargs.get("projection", None) is not None
422+
or kwargs.get("geo", None) is True
423+
):
396424
warnings.warn(
397425
"Projections with dynamic plots may display incorrectly or update improperly. "
398426
"Consider using static plots instead. See: github.com/holoviz/geoviews/issues/762"
399427
)
400-
401-
if projection is not None:
402-
kwargs["projection"] = projection
403-
kwargs["geo"] = True
404-
if "crs" not in kwargs:
405-
central_longitude = projection.proj4_params["lon_0"]
406-
kwargs["crs"] = ccrs.PlateCarree(central_longitude=central_longitude)
428+
kwargs, periodic_elements = check_crs(kwargs, periodic_elements)
407429

408430
if "clabel" not in kwargs and self._uxda.name is not None:
409431
kwargs["clabel"] = self._uxda.name

uxarray/plot/utils.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,22 @@
1+
import cartopy.crs as ccrs
12
import holoviews as hv
23
import matplotlib as mpl
34

45

6+
def check_crs(kwargs, periodic_elements="exclude"):
7+
"""Sets default parameters based off the crs that is passed in."""
8+
if "crs" in kwargs:
9+
if kwargs["crs"] == ccrs.Geodetic():
10+
kwargs["projection"] = kwargs.get("projection", ccrs.PlateCarree())
11+
kwargs["project"] = True
12+
# Allows geodetic crs to handle antimeridian wrapping
13+
periodic_elements = "ignore"
14+
else:
15+
kwargs["crs"] = ccrs.PlateCarree()
16+
17+
return kwargs, periodic_elements
18+
19+
520
class HoloviewsBackend:
621
"""Utility class to compare and set a HoloViews plotting backend for
722
visualization."""

0 commit comments

Comments
 (0)