MPAS/Voronoi grid

This example shows how to draw the edges of an MPAS Voronoi mesh with easyclimate.plot.mpas.plot_voronoi_grid.

The same mesh can be displayed on a plain Matplotlib axes or on Cartopy map projections. Longitude wrapping and dateline-crossing mesh edges are handled by the plotting helper.

import xarray as xr
import numpy as np
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import easyclimate as ecl

from easyclimate.plot.mpas import plot_voronoi_grid

Open a sample MPAS mesh dataset. The grid file contains MPAS connectivity variables such as verticesOnEdge as well as vertex coordinates.

x1_2562_grid.nc ━━━━━━━━━━━━━━━━━━━━━━ 100.0% • 1.6/1.6 MB • 25.8 MB/s • 0:00:00
<xarray.Dataset> Size: 4MB
Dimensions:            (nCells: 2562, nVertices: 5120, nEdges: 7680,
                        maxEdges: 10, vertexDegree: 3, TWO: 2, maxEdges2: 20)
Dimensions without coordinates: nCells, nVertices, nEdges, maxEdges,
                                vertexDegree, TWO, maxEdges2
Data variables: (12/36)
    indexToCellID      (nCells) int32 10kB ...
    latCell            (nCells) float64 20kB ...
    lonCell            (nCells) float64 20kB ...
    xCell              (nCells) float64 20kB ...
    yCell              (nCells) float64 20kB ...
    zCell              (nCells) float64 20kB ...
    ...                 ...
    kiteAreasOnVertex  (nVertices, vertexDegree) float64 123kB ...
    dvEdge             (nEdges) float64 61kB ...
    dcEdge             (nEdges) float64 61kB ...
    angleEdge          (nEdges) float64 61kB ...
    weightsOnEdge      (nEdges, maxEdges2) float64 1MB ...
    meshDensity        (nCells) float64 20kB ...
Attributes:
    CDI:            Climate Data Interface version 2.4.4 (https://mpimet.mpg....
    Conventions:    CF-1.6
    mesh_spec:      1.1
    on_a_sphere:    YES
    sphere_radius:  1.0
    is_periodic:    NO
    x_period:       0.0
    y_period:       0.0
    file_id:        5d483ba2
    history:        Sat May 30 20:04:37 2026: cdo -f nc4 -z zip5 copy x1.2562...
    CDO:            Climate Data Operators version 2.4.4 (https://mpimet.mpg....


Draw the mesh directly on the current axes.

plot voronoi grid
<matplotlib.collections.LineCollection object at 0x74c41a2b4830>

Plot the global mesh on a PlateCarree map. When the target axes is a Cartopy GeoAxes, the helper automatically supplies a PlateCarree transform unless a different transform is passed explicitly.

fig = plt.figure(figsize=(12, 6))
ax = plt.axes(projection=ccrs.PlateCarree(180))
ax.coastlines(resolution="110m", linewidth=0.6)

plot_voronoi_grid(data, ax = ax, transform=ccrs.PlateCarree());
ax.set_global()
ax.gridlines(draw_labels=True, alpha = 0)

ax.set_title("Global MPAS mesh 1")
Global MPAS mesh 1
Text(0.5, 1.0453342943342954, 'Global MPAS mesh 1')

The same MPAS mesh can be displayed with another global projection.

fig = plt.figure(figsize=(12, 6))
ax = plt.axes(projection=ccrs.Robinson(0))
ax.coastlines(resolution="110m", linewidth=0.6)

plot_voronoi_grid(data, ax = ax, transform=ccrs.PlateCarree());
ax.set_global()
ax.gridlines(draw_labels=True, alpha = 0)

ax.set_title("Global MPAS mesh 2")
Global MPAS mesh 2
Text(0.5, 1.0453342943342951, 'Global MPAS mesh 2')

Orthographic projection is useful for inspecting a regional portion of the global unstructured grid.

fig = plt.figure(figsize=(12, 6))
ax = plt.axes(projection=ccrs.Orthographic(central_longitude=110.0, central_latitude=70.0))
ax.coastlines(resolution="110m", linewidth=0.6)

plot_voronoi_grid(data, ax = ax, transform=ccrs.PlateCarree())
ax.set_global()
ax.gridlines(draw_labels=True, alpha = 0)

ax.set_global()
ax.set_title("Global MPAS mesh 3")
Global MPAS mesh 3
Text(0.5, 1.0381854681723834, 'Global MPAS mesh 3')

Total running time of the script: (0 minutes 31.039 seconds)