How to Save UGRID Data#
This guide covers exporting xugrid data to various formats while preserving UGRID conventions.
Saving to NetCDF#
NetCDF is the standard format for UGRID data:
import xugrid as xu
uda = xu.data.elevation_nl()
# Save UgridDataArray
uda.ugrid.to_netcdf("elevation.nc")
# Save UgridDataset
uds = xu.open_dataset("model.nc")
uds.ugrid.to_netcdf("output.nc")
The output file will include all UGRID topology variables and CF-compliant metadata.
Saving to Zarr#
Zarr is preferred for large datasets and cloud storage:
# Save to local Zarr store
uda.ugrid.to_zarr("elevation.zarr")
# Save to cloud storage (requires fsspec/s3fs)
uda.ugrid.to_zarr("s3://bucket/elevation.zarr")
# Append to existing store (e.g., for time series)
uda.ugrid.to_zarr("timeseries.zarr", mode="a", append_dim="time")
Zarr supports chunked, compressed storage suitable for parallel access.
Converting to Xarray Dataset#
To get a standard xarray Dataset (for custom I/O or further processing):
# Convert UgridDataArray to Dataset
ds = uda.ugrid.to_dataset()
# Convert UgridDataset to Dataset
ds = uds.ugrid.to_dataset()
# Now you can use any xarray export method
ds.to_netcdf("custom.nc", encoding={...})
Exporting to GeoDataFrame#
For GIS workflows, export to geopandas:
import geopandas as gpd
# Export faces as polygons
gdf = uda.ugrid.to_geodataframe()
# Export to various GIS formats
gdf.to_file("output.gpkg", driver="GPKG")
gdf.to_file("output.shp")
gdf.to_parquet("output.parquet")
You can also export specific grid elements:
# Access the grid
grid = uda.ugrid.grid
# Export nodes as points
gdf_nodes = gpd.GeoDataFrame(
geometry=gpd.points_from_xy(grid.node_x, grid.node_y)
)
# Export edges as lines
gdf_edges = grid.to_geodataframe(dim=grid.edge_dimension)
Saving Regridder Weights#
Regridder weights can be saved for reuse:
# Create and use a regridder
regridder = xu.OverlapRegridder(source=uda, target=target_grid)
result = regridder.regrid(uda)
# Save weights to Dataset
weights_ds = regridder.to_dataset()
weights_ds.to_netcdf("regridder_weights.nc")
# Later, reload the regridder
weights_ds = xr.open_dataset("regridder_weights.nc")
regridder = xu.OverlapRegridder.from_dataset(weights_ds)
Controlling Output Encoding#
For fine-grained control over the output format:
# Get xarray Dataset first
ds = uda.ugrid.to_dataset()
# Define encoding (compression, chunking, etc.)
encoding = {
"elevation": {
"dtype": "float32",
"zlib": True,
"complevel": 4,
}
}
# Save with custom encoding
ds.to_netcdf("compressed.nc", encoding=encoding)
For Zarr with specific chunks:
ds = uds.ugrid.to_dataset()
encoding = {
"temperature": {"chunks": {"time": 10, "mesh2d_nFaces": 10000}},
}
ds.to_zarr("chunked.zarr", encoding=encoding)
Best Practices#
Use Zarr for large datasets - Better parallel read/write performance
Preserve CRS information - Set CRS before saving:
uda.ugrid.set_crs("EPSG:28992")Use compression for NetCDF - Reduces file size significantly
Choose appropriate chunks for Zarr - Balance between chunk size and access patterns
Include metadata - Add attributes to document your data:
uda.attrs["source"] = "Model simulation v2.0"
uda.attrs["units"] = "meters"
uda.ugrid.to_netcdf("documented.nc")