Skip to content

Add xugrid extension for TriMesh plots from unstructured grid data#1724

Open
rsignell wants to merge 7 commits into
holoviz:mainfrom
OpenScienceComputing:xugrid
Open

Add xugrid extension for TriMesh plots from unstructured grid data#1724
rsignell wants to merge 7 commits into
holoviz:mainfrom
OpenScienceComputing:xugrid

Conversation

@rsignell
Copy link
Copy Markdown

@rsignell rsignell commented May 12, 2026

Holoviz folks, as you can tell, I made this with Claude Code, and I've been using it for the past few months for many applications. But I have no idea how well it's coded.

@Huite did give it a quick look and didn't raise any red flags.

There is discussion on the xugrid repo here: Deltares/xugrid#204 (comment)

Please let me know if there is anything else I can do -- I'd love to see trimesh supported by hvplot!

Summary

  • Adds hvplot/xugrid.py — registers .hvplot on xugrid.UgridDataArray and xugrid.UgridDataset, enabling uda.hvplot.trimesh() for unstructured triangular mesh plots
  • Extends HoloViewsConverter (converter.py) with a trimesh() method that supports rasterize=True, geo=True, tiles=, cmap=, etc.
  • Extends hvPlot in plotting/core.py with the hvPlotXugrid subclass; _get_converter() extracts mesh topology (node coords, face-node connectivity) and stores it in kwds
  • Defers face-to-node interpolation until after groupby slicing, so extra dimensions (time, sigma layers) become interactive widgets rather than requiring explicit selection
  • Adds hvplot/tests/testxugrid.py with 243 lines of tests covering node-data, face-data, time/depth groupby, geo projection, and rasterization
  • Includes two example notebooks (FVCOM_xugrid.ipynb, STOFS_xugrid.ipynb) demonstrating real-world FVCOM and STOFS coastal ocean model output

Usage

import hvplot.xugrid

# UgridDataArray with node data
uda.hvplot.trimesh(clim=(0, 2), cmap='viridis', rasterize=True, tiles='OSM', geo=True)

# Face data with time/depth sliders (auto groupby)
uda_3d.hvplot.trimesh(rasterize=True)  # sliders for time + siglay

Test plan

  • pytest hvplot/tests/testxugrid.py — all tests pass
  • Manual verification with FVCOM/STOFS example notebooks
  • Confirm import hvplot.xugrid is a no-op (clean ImportError) when xugrid is not installed

🤖 Generated with Claude Code

rsignell and others added 6 commits May 12, 2026 07:42
Add hvplot.xugrid module that patches .hvplot onto xu.UgridDataArray and
xu.UgridDataset, enabling users to create TriMesh plots directly from
xugrid objects (e.g. uda.hvplot.trimesh()). Supports rasterize, geo/tiles,
face-to-node averaging, quad mesh triangulation, and extra dimension reduction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use isel for integer values and sel only for non-integer values like
time strings, so dimensions like FVCOM's siglay that lack a simple
1D index are handled correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…t selection

Extra dimensions (time, siglay, etc.) now automatically become interactive
slider widgets, matching standard hvplot behavior. Users can still fix a
dimension by passing it explicitly (e.g. siglay=0). The xugrid data is
passed as xarray to the converter so its existing groupby/DynamicMap
machinery handles widget creation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Only include proper 1D dimension coordinates when building the xarray
Dataset for the converter. 2D coords like FVCOM's siglay(siglay, node)
were being copied through, breaking the groupby slider machinery.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously, face data (e.g. u-velocity) was converted to nodes via
to_node().mean() on the full multi-dimensional array before the groupby
machinery sliced by time/level, causing hangs on large datasets like FVCOM.
Now the conversion is deferred to the converter's trimesh() method where
the data has already been reduced to a single slice.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Covers node data, face data (with face-to-node interpolation), extra
time dimensions creating DynamicMap groupby sliders, and UgridDataset inputs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ahuang11
Copy link
Copy Markdown
Collaborator

Looks awesome! Took a quick glance at the code and maybe https://holoviz-dev.github.io/holoviz-skills/contributing-to-holoviz/cleanup/ could help clean it up (imports)

I think pixi dev may need updating to run these tests in CI.

This does increase maintenance burden for a fairly niche library, but I think it's worth having, if this is the one package for reading and parsing unstructured grid? However, I vaguely recall xarray natively supporting unstructured grids too with its new refactor of indexing?

Alternatively, could maybe use https://github.com/panel-extensions/copier-template-panel-extension to create an hvplot-extension as well and put this there under hvplot-xugrid.

- Move pandas import to module level in testxugrid.py (required dep, was scattered in 4 places)
- Remove WHAT-explaining comments; keep only non-obvious WHY comments
- Simplify over-verbose docstring in _make_simple_node_uda

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@rsignell
Copy link
Copy Markdown
Author

Thanks @ahuang11 for taking a look!

Since xugrid follows the same integration pattern as hvplot's other data backends (xarray, geopandas, etc.) and this is the canonical Python package for unstructured mesh data, I'd prefer to keep it as a PR to hvplot if you're open to it.

On xarray advanced indexing — it'll help xugrid work more efficiently, but it won't replace the need for a package that understands how to subset unstructured meshes, interpolate face data to nodes, and so on -- xugrid is that package!

I have updated the PR after telling Claude to run the "cleanup". Hope this looks better!

@ahuang11
Copy link
Copy Markdown
Collaborator

It sounds fine to me, but I'll defer to @maximlt for his suggestions!

@ahuang11 ahuang11 requested a review from maximlt May 20, 2026 15:46
@rsignell
Copy link
Copy Markdown
Author

rsignell commented Jun 1, 2026

@maximlt , just a note here that I'm still very interested in this -- we would love to share this capability with users in the CoastPredict project that does a lot of work with the SHYFEM triangular mesh coastal ocean model.

@maximlt
Copy link
Copy Markdown
Member

maximlt commented Jun 1, 2026

Noted @rsignell, I'll review this week and get a release soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants