Deltares / xugrid

Xarray and unstructured grids
https://deltares.github.io/xugrid/
MIT License
64 stars 8 forks source link

Holoviews / Datashader integration #204

Open Huite opened 8 months ago

Huite commented 8 months ago

Holoviews and Datashader supports TriMesh/trimesh (resp.): https://datashader.org/user_guide/Trimesh.html

This is obviously useful, especially for larger grids.

Althought not every 2D grid is triangular, it can be easily triangulated (which is done for a number of plotting methods, since matplotlib can will only draw contours for triangles e.g.).

The following suffices for Ugrid2d topologies in the _PlotMethods accessor:


    def to_holoviews(self):
        import holoviews
        import pandas as pd

        grid = self.grid
        da = self.darray
        (_, _, triangles), index = grid.triangulation
        name = getattr(da, "name", "data")

        vertices = pd.DataFrame(
            data=grid.node_coordinates,
            columns=("x", "y"),
        )
        triangles = pd.DataFrame(
            data=triangles,
            columns=("v0", "v1", "v2"),
        )

        dim = get_ugrid_dim(grid, da)
        if dim == NODE:
            vertices[name] = da
        elif dim == FACE:
            triangles[name] = da.isel({grid.face_dimension: index})
        else:
            raise ValueError("only supports data on nodes or faces")

        return holoviews.TriMesh((triangles, vertices))

Then, to draw something:

import holoviews as hv
from datashader import rasterize

hv.extension("matplotlib")
rasterize(uda.to_holoviews()).opts(colorbar=True)

What makes it not totally trivial:

Having to call rasterize yourself is a bit annoying. Something like .ugrid.holoviews.plot() could be an option but:

Secondly, there's a package called hvplot: https://hvplot.holoviz.org/ It adds an hvplot and interactive accessor to dataframes and xarray objects. This seems like it's more work, because it actually does data selection.