Skip to content

Plotting#

For a worked, example-driven walkthrough see the Plotting NetCDF data tutorial. This page is the API reference (signature table + the auto-generated Selectors / ColourOpts / FacetSpec docs).

NetCDF.plot has its own, xarray-aligned plotting surface — it does not inherit the GeoTIFF / Sentinel-imagery semantics of Dataset.plot. You pick a variable, slice along the non-spatial dimensions, and pass colour / faceting / coordinate options through small grouped, frozen dataclasses (Selectors, ColourOpts, FacetSpec) re-exported from pyramids.netcdf.

from pyramids.netcdf import NetCDF, Selectors, ColourOpts, FacetSpec

nc = NetCDF.read_file("era5.nc")

# pick a variable, select along non-spatial dims, xarray-style colour kwargs
nc.plot("t2m", selectors=Selectors(time="2020-01-01", level=850),
        colour=ColourOpts(cmap="coolwarm", robust=True))

# curvilinear (WRF) grid -> pcolormesh, faceted over time
nc.plot("T2", coords=(XLONG, XLAT), kind="pcolormesh",
        facet=FacetSpec(col="time", col_wrap=4))

# animate over a dimension with lazy, per-frame reads ([lazy] extra)
nc.plot("t2m", animate="time", chunks={"time": 1})

Signature#

NetCDF.plot(variable=None, *, selectors=None, colour=None, facet=None, coords=None, kind="auto", animate=None, chunks=None, basemap=None, exclude_value=None, title=None, ax=None, figsize=None, **kwargs)

Parameter Type Notes
variable str, optional Variable to plot; defaults to the dataset's single / active variable.
selectors Selectors, optional Slice along non-spatial dimensions — time=, level=, member=, plus generic sel= / isel=.
colour ColourOpts, optional Colour mapping — cmap, vmin, vmax, robust, levels, norm, center, extend, add_colorbar, cbar_kwargs.
facet FacetSpec, optional Small-multiples grid — col=, row=, col_wrap=.
coords tuple[ndarray, ndarray], optional Curvilinear (x_2d, y_2d) coordinates -> pcolormesh. Auto-detected from CF coordinates / WRF / ROMS / NEMO conventions when omitted.
kind str, optional "auto", "imshow", "pcolormesh", "contour", "contourf".
animate bool or str, optional Animate over a dimension (its name, or True for the leading non-spatial dimension).
chunks dict, optional Dask chunking — switches to a lazy read; only the rendered slice / frame is materialised. Requires the [lazy] extra.
basemap bool or str, optional Overlay a web-tile basemap (provider name as a string, e.g. "CartoDB.Positron"). Requires the [viz] extra.
**kwargs Forwarded to cleopatra's ArrayGlyph for figure / colour-bar styling, color_scale, etc.

The GeoTIFF-only kwargs band, rgb, surface_reflectance, cutoff, percentile, overview, and overview_index are not accepted on NetCDF.plot — passing any of them raises TypeError with a hint pointing at the replacement above (use selectors= to pick a slice, colour= for the colour scale, and so on).

Internally NetCDF.plot is a thin facade over pyramids.netcdf._plot.NetCDFPlot, which shares the pyramids.dataset._plot_helpers.render_array rendering core with Dataset.plot and DatasetCollection.plot (and mesh_render with UgridDataset.plot). The full rendered method signature and docstring are on the NetCDF Class reference page.

Option dataclasses#

pyramids.netcdf.Selectors dataclass #

Dimension selectors for :meth:NetCDF.plot.

Groups the label-based dimension selectors that pin a multi-dim NetCDF variable to a single 2-D slice. All fields are optional; pass only the dims that need pinning. Convenience aliases (time / level / member) auto-detect the matching band dim name; raw sel / isel dicts take the dim name verbatim.

Attributes:

Name Type Description
time Any

Convenience label selector for the time dim. Equivalent to sel={<time-dim-name>: time}. Defaults to None.

level Any

Convenience label selector for the vertical dim (auto-detected as the first of pressure_level / depth / height / z present on the variable's band dims). Defaults to None.

member Any

Convenience label selector for the ensemble dim (member / realization / ensemble). Defaults to None.

sel dict[str, Any] | None

Raw label selectors forwarded directly to :meth:NetCDF.sel. Keys must be valid band-dim names of the variable. Defaults to None.

isel dict[str, int] | None

Positional selectors keyed by dim name. Each int is converted to the corresponding coord value via the variable's band-dim coord map; dims without coord values receive the int unchanged. Defaults to None.

Examples:

  • The default constructor produces an all-None instance that is safe to forward to plot unchanged:

    >>> from pyramids.netcdf.plot_options import Selectors
    >>> empty = Selectors()
    >>> empty.time is None
    True
    >>> empty.sel is None
    True
    
  • Pin both the time and pressure-level dims of a 4-D variable:

    >>> from pyramids.netcdf.plot_options import Selectors
    >>> sel = Selectors(time=12, level=500)
    >>> sel.time
    12
    >>> sel.level
    500
    
  • Frozen instances reject attribute assignment so the option bag stays stable after construction:

    >>> from dataclasses import FrozenInstanceError
    >>> from pyramids.netcdf.plot_options import Selectors
    >>> sel = Selectors(time=0)
    >>> try:
    ...     sel.time = 1
    ... except FrozenInstanceError:
    ...     print("frozen")
    frozen
    
Source code in src/pyramids/netcdf/plot_options.py
@dataclass(frozen=True)
class Selectors:
    """Dimension selectors for :meth:`NetCDF.plot`.

    Groups the label-based dimension selectors that pin a multi-dim
    NetCDF variable to a single 2-D slice. All fields are optional;
    pass only the dims that need pinning. Convenience aliases
    (``time`` / ``level`` / ``member``) auto-detect the matching band
    dim name; raw ``sel`` / ``isel`` dicts take the dim name verbatim.

    Attributes:
        time: Convenience label selector for the time dim. Equivalent
            to ``sel={<time-dim-name>: time}``. Defaults to None.
        level: Convenience label selector for the vertical dim
            (auto-detected as the first of
            ``pressure_level`` / ``depth`` / ``height`` / ``z`` present
            on the variable's band dims). Defaults to None.
        member: Convenience label selector for the ensemble dim
            (``member`` / ``realization`` / ``ensemble``). Defaults to
            None.
        sel: Raw label selectors forwarded directly to
            :meth:`NetCDF.sel`. Keys must be valid band-dim names of
            the variable. Defaults to None.
        isel: Positional selectors keyed by dim name. Each int is
            converted to the corresponding coord value via the
            variable's band-dim coord map; dims without coord values
            receive the int unchanged. Defaults to None.

    Examples:
        - The default constructor produces an all-``None`` instance
          that is safe to forward to ``plot`` unchanged:

            ```python
            >>> from pyramids.netcdf.plot_options import Selectors
            >>> empty = Selectors()
            >>> empty.time is None
            True
            >>> empty.sel is None
            True

            ```

        - Pin both the time and pressure-level dims of a 4-D variable:

            ```python
            >>> from pyramids.netcdf.plot_options import Selectors
            >>> sel = Selectors(time=12, level=500)
            >>> sel.time
            12
            >>> sel.level
            500

            ```

        - Frozen instances reject attribute assignment so the option
          bag stays stable after construction:

            ```python
            >>> from dataclasses import FrozenInstanceError
            >>> from pyramids.netcdf.plot_options import Selectors
            >>> sel = Selectors(time=0)
            >>> try:
            ...     sel.time = 1
            ... except FrozenInstanceError:
            ...     print("frozen")
            frozen

            ```
    """

    time: Any = None
    level: Any = None
    member: Any = None
    sel: dict[str, Any] | None = None
    isel: dict[str, int] | None = None

pyramids.netcdf.ColourOpts dataclass #

Xarray-aligned colour controls for :meth:NetCDF.plot.

Mirrors the kwargs xarray's plotting accessor accepts. All fields are optional. Non-None values are forwarded verbatim to cleopatra's :class:~cleopatra.array_glyph.ArrayGlyph; the add_colorbar switch is applied post-render on the pyramids side because cleopatra does not accept the kwarg today.

Attributes:

Name Type Description
cmap str | None

Matplotlib colormap name. Defaults to None.

vmin float | None

Lower colour limit. Defaults to None.

vmax float | None

Upper colour limit. Defaults to None.

robust bool

When True, clip colour limits to the 2nd / 98th percentile. Defaults to False.

levels int | list[float] | None

int (number of discrete levels) or explicit edge list. Defaults to None.

norm Any | None

Custom matplotlib :class:~matplotlib.colors.Normalize instance. Defaults to None.

center float | None

Diverging-cmap centre value (for example 0.0 for anomaly maps). Defaults to None.

extend str | None

Colorbar arrow extension — one of "neither" / "both" / "min" / "max". Defaults to None.

add_colorbar bool

When False, drop the colorbar from the rendered result. Defaults to True.

cbar_kwargs dict | None

Extra dict forwarded to :meth:Figure.colorbar. Defaults to None.

Examples:

  • The default constructor is a no-op forward — every colour control is left at its cleopatra default:

    >>> from pyramids.netcdf.plot_options import ColourOpts
    >>> opts = ColourOpts()
    >>> opts.cmap is None
    True
    >>> opts.add_colorbar
    True
    
  • Build a robust (percentile-based) colormap with a diverging centre at zero:

    >>> from pyramids.netcdf.plot_options import ColourOpts
    >>> opts = ColourOpts(cmap="RdBu_r", robust=True, center=0.0)
    >>> opts.cmap
    'RdBu_r'
    >>> opts.robust
    True
    >>> opts.center
    0.0
    
  • Disable the colorbar — the facade removes it post-render:

    >>> from pyramids.netcdf.plot_options import ColourOpts
    >>> opts = ColourOpts(add_colorbar=False)
    >>> opts.add_colorbar
    False
    
Source code in src/pyramids/netcdf/plot_options.py
@dataclass(frozen=True)
class ColourOpts:
    """Xarray-aligned colour controls for :meth:`NetCDF.plot`.

    Mirrors the kwargs xarray's plotting accessor accepts. All fields
    are optional. Non-``None`` values are forwarded verbatim to
    cleopatra's :class:`~cleopatra.array_glyph.ArrayGlyph`; the
    ``add_colorbar`` switch is applied post-render on the pyramids
    side because cleopatra does not accept the kwarg today.

    Attributes:
        cmap: Matplotlib colormap name. Defaults to None.
        vmin: Lower colour limit. Defaults to None.
        vmax: Upper colour limit. Defaults to None.
        robust: When True, clip colour limits to the 2nd / 98th
            percentile. Defaults to False.
        levels: int (number of discrete levels) or explicit edge list.
            Defaults to None.
        norm: Custom matplotlib :class:`~matplotlib.colors.Normalize`
            instance. Defaults to None.
        center: Diverging-cmap centre value (for example ``0.0`` for
            anomaly maps). Defaults to None.
        extend: Colorbar arrow extension — one of ``"neither"`` /
            ``"both"`` / ``"min"`` / ``"max"``. Defaults to None.
        add_colorbar: When False, drop the colorbar from the rendered
            result. Defaults to True.
        cbar_kwargs: Extra dict forwarded to :meth:`Figure.colorbar`.
            Defaults to None.

    Examples:
        - The default constructor is a no-op forward — every colour
          control is left at its cleopatra default:

            ```python
            >>> from pyramids.netcdf.plot_options import ColourOpts
            >>> opts = ColourOpts()
            >>> opts.cmap is None
            True
            >>> opts.add_colorbar
            True

            ```

        - Build a robust (percentile-based) colormap with a diverging
          centre at zero:

            ```python
            >>> from pyramids.netcdf.plot_options import ColourOpts
            >>> opts = ColourOpts(cmap="RdBu_r", robust=True, center=0.0)
            >>> opts.cmap
            'RdBu_r'
            >>> opts.robust
            True
            >>> opts.center
            0.0

            ```

        - Disable the colorbar — the facade removes it post-render:

            ```python
            >>> from pyramids.netcdf.plot_options import ColourOpts
            >>> opts = ColourOpts(add_colorbar=False)
            >>> opts.add_colorbar
            False

            ```
    """

    cmap: str | None = None
    vmin: float | None = None
    vmax: float | None = None
    robust: bool = False
    levels: int | list[float] | None = None
    norm: Any | None = None
    center: float | None = None
    extend: str | None = None
    add_colorbar: bool = True
    cbar_kwargs: dict | None = None

pyramids.netcdf.FacetSpec dataclass #

Faceting specification for :meth:NetCDF.plot.

When set, NetCDF.plot builds a stack of slices along the named dims and hands them to :meth:cleopatra.array_glyph.ArrayGlyph.facet. At least one of col or row must be set; row alone (without col) is invalid and rejected by the validator.

Attributes:

Name Type Description
col str | None

Band-dim name to facet across columns. Defaults to None.

row str | None

Band-dim name to facet across rows. Requires col. Defaults to None.

col_wrap int | None

When only col is set, wrap into this many columns (so N panels lay out as ceil(N/col_wrap) x col_wrap). Ignored when row is set. Defaults to None.

Examples:

  • A column-only facet over the time dim:

    >>> from pyramids.netcdf.plot_options import FacetSpec
    >>> spec = FacetSpec(col="time")
    >>> spec.col
    'time'
    >>> spec.row is None
    True
    
  • Two-axis facet across time (columns) and pressure level (rows):

    >>> from pyramids.netcdf.plot_options import FacetSpec
    >>> spec = FacetSpec(col="time", row="pressure_level")
    >>> spec.col
    'time'
    >>> spec.row
    'pressure_level'
    
  • Column-wrap layout — 4 panels in a 2x3 grid:

    >>> from pyramids.netcdf.plot_options import FacetSpec
    >>> spec = FacetSpec(col="time", col_wrap=3)
    >>> spec.col_wrap
    3
    
Source code in src/pyramids/netcdf/plot_options.py
@dataclass(frozen=True)
class FacetSpec:
    """Faceting specification for :meth:`NetCDF.plot`.

    When set, ``NetCDF.plot`` builds a stack of slices along the named
    dims and hands them to
    :meth:`cleopatra.array_glyph.ArrayGlyph.facet`. At least one of
    ``col`` or ``row`` must be set; ``row`` alone (without ``col``) is
    invalid and rejected by the validator.

    Attributes:
        col: Band-dim name to facet across columns. Defaults to None.
        row: Band-dim name to facet across rows. Requires ``col``.
            Defaults to None.
        col_wrap: When only ``col`` is set, wrap into this many
            columns (so ``N`` panels lay out as
            ``ceil(N/col_wrap) x col_wrap``). Ignored when ``row`` is
            set. Defaults to None.

    Examples:
        - A column-only facet over the time dim:

            ```python
            >>> from pyramids.netcdf.plot_options import FacetSpec
            >>> spec = FacetSpec(col="time")
            >>> spec.col
            'time'
            >>> spec.row is None
            True

            ```

        - Two-axis facet across time (columns) and pressure level
          (rows):

            ```python
            >>> from pyramids.netcdf.plot_options import FacetSpec
            >>> spec = FacetSpec(col="time", row="pressure_level")
            >>> spec.col
            'time'
            >>> spec.row
            'pressure_level'

            ```

        - Column-wrap layout — 4 panels in a 2x3 grid:

            ```python
            >>> from pyramids.netcdf.plot_options import FacetSpec
            >>> spec = FacetSpec(col="time", col_wrap=3)
            >>> spec.col_wrap
            3

            ```
    """

    col: str | None = None
    row: str | None = None
    col_wrap: int | None = None