diff --git a/test/test_plot.py b/test/test_plot.py index c04fea9b1..62bcf08f6 100644 --- a/test/test_plot.py +++ b/test/test_plot.py @@ -46,8 +46,8 @@ def test_face_centered_data(self): uxds = ux.open_dataset(gridfile_mpas, gridfile_mpas) for backend in ['matplotlib', 'bokeh']: - assert(isinstance(uxds['bottomDepth'].plot(backend=backend), hv.DynamicMap)) - assert(isinstance(uxds['bottomDepth'].plot.polygons(backend=backend), hv.DynamicMap)) + assert(isinstance(uxds['bottomDepth'].plot(backend=backend, dynamic=True), hv.DynamicMap)) + assert(isinstance(uxds['bottomDepth'].plot.polygons(backend=backend, dynamic=True), hv.DynamicMap)) assert(isinstance(uxds['bottomDepth'].plot.points(backend=backend), hv.Points)) def test_face_centered_remapped_dim(self): @@ -56,8 +56,8 @@ def test_face_centered_remapped_dim(self): uxds = ux.open_dataset(gridfile_ne30, datafile_ne30) for backend in ['matplotlib', 'bokeh']: - assert(isinstance(uxds['psi'].plot(backend=backend), hv.DynamicMap)) - assert(isinstance(uxds['psi'].plot.polygons(backend=backend), hv.DynamicMap)) + assert(isinstance(uxds['psi'].plot(backend=backend, dynamic=True), hv.DynamicMap)) + assert(isinstance(uxds['psi'].plot.polygons(backend=backend, dynamic=True), hv.DynamicMap)) assert(isinstance(uxds['psi'].plot.points(backend=backend), hv.Points)) @@ -71,7 +71,7 @@ def test_node_centered_data(self): assert(isinstance(uxds['v1'][0][0].plot.points(backend=backend), hv.Points)) - assert(isinstance(uxds['v1'][0][0].topological_mean(destination='face').plot.polygons(backend=backend), hv.DynamicMap)) + assert(isinstance(uxds['v1'][0][0].topological_mean(destination='face').plot.polygons(backend=backend, dynamic=True), hv.DynamicMap)) @@ -85,8 +85,8 @@ def test_clabel(self): def test_engine(self): uxds = ux.open_dataset(gridfile_mpas, gridfile_mpas) - _plot_sp = uxds['bottomDepth'].plot.polygons(rasterize=True, engine='spatialpandas') - _plot_gp = uxds['bottomDepth'].plot.polygons(rasterize=True, engine='geopandas') + _plot_sp = uxds['bottomDepth'].plot.polygons(rasterize=True, dynamic=True, engine='spatialpandas') + _plot_gp = uxds['bottomDepth'].plot.polygons(rasterize=True, dynamic=True, engine='geopandas') assert isinstance(_plot_sp, hv.DynamicMap) assert isinstance(_plot_gp, hv.DynamicMap) diff --git a/uxarray/plot/accessor.py b/uxarray/plot/accessor.py index 214022119..47cc5c9d7 100644 --- a/uxarray/plot/accessor.py +++ b/uxarray/plot/accessor.py @@ -345,9 +345,14 @@ def __getattr__(self, name: str) -> Any: def polygons( self, - periodic_elements="exclude", - backend=None, - engine="spatialpandas", + periodic_elements: Optional[str] = "exclude", + backend: Optional[str] = None, + engine: Optional[str] = "spatialpandas", + rasterize: Optional[bool] = True, + dynamic: Optional[bool] = False, + projection: Optional[ccrs.Projection] = None, + xlabel: Optional[str] = "Longitude", + ylabel: Optional[str] = "Latitude", *args, **kwargs, ): @@ -370,15 +375,14 @@ def polygons( Plotting backend to use. One of ['matplotlib', 'bokeh']. Equivalent to running holoviews.extension(backend) engine: str, optional Engine to use for GeoDataFrame construction. One of ['spatialpandas', 'geopandas'] + rasterize: bool, optional + Whether to rasterize the plot (default: True) + projection: ccrs.Projection, optional + The map projection to use. *args : tuple Additional positional arguments to be passed to `hvplot.polygons`. **kwargs : dict - Additional keyword arguments passed to `hvplot.polygons`. These can include: - - "rasterize" (bool): Whether to rasterize the plot (default: True), - - "projection" (ccrs.Projection): The map projection to use (default: `ccrs.PlateCarree()`), - - "clabel" (str): Label for the colorbar, defaulting to the name of the data array (`_uxda.name`), - - "crs" (ccrs.Projection): Coordinate reference system for the plot (default: `ccrs.PlateCarree()`). - For additional customization, please refer to https://hvplot.holoviz.org/user_guide/Customization.html + Additional keyword arguments passed to `hvplot.polygons`. For additional customization, please refer to https://hvplot.holoviz.org/user_guide/Customization.html Returns ------- @@ -387,18 +391,22 @@ def polygons( """ uxarray.plot.utils.backend.assign(backend) - if "rasterize" not in kwargs: - kwargs["rasterize"] = True - if "projection" not in kwargs: - kwargs["projection"] = ccrs.PlateCarree() + if dynamic and (projection is not None or kwargs.get("geo", None) is True): + warnings.warn( + "Projections with dynamic plots may display incorrectly or update improperly. " + "Consider using static plots instead. See: github.com/holoviz/geoviews/issues/762" + ) + + if projection is not None: + kwargs["projection"] = projection + print("Hello") + kwargs["geo"] = True + if "crs" not in kwargs: + central_longitude = projection.proj4_params["lon_0"] + kwargs["crs"] = ccrs.PlateCarree(central_longitude=central_longitude) + if "clabel" not in kwargs and self._uxda.name is not None: kwargs["clabel"] = self._uxda.name - if "crs" not in kwargs: - if "projection" in kwargs: - central_longitude = kwargs["projection"].proj4_params["lon_0"] - else: - central_longitude = 0.0 - kwargs["crs"] = ccrs.PlateCarree(central_longitude=central_longitude) gdf = self._uxda.to_geodataframe( periodic_elements=periodic_elements, @@ -409,7 +417,10 @@ def polygons( return gdf.hvplot.polygons( c=self._uxda.name if self._uxda.name is not None else "var", - geo=True, + rasterize=rasterize, + dynamic=dynamic, + xlabel=xlabel, + ylabel=ylabel, *args, **kwargs, )