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 / CoordinateSpec / FacetSpec docs).

NetCDF.plot mirrors Dataset.plot's signature. You pick a variable, slice along the non-spatial dimensions, pass faceting / coordinate options through small grouped, frozen dataclasses (Selectors, CoordinateSpec, FacetSpec) re-exported from pyramids.netcdf, and express colour exactly as Dataset.plot does — through loose keyword arguments plus the shared cleopatra render bags.

The option bags and loose kwargs feed NetCDF.plot, which is a thin facade over NetCDFPlot (_plot.py). That resolves the variable/slice and hands the array to the shared render_array core (_plot_helpers.py) — the same renderer behind Dataset.plot and DatasetCollection.plot — which draws into a cleopatra ArrayGlyph and returns the glyph (.fig / .ax / .im):

Hold "Ctrl" to enable pan & zoom
flowchart LR
    SEL["Selectors<br/>time · level · member<br/>sel · isel"]
    AXES["CoordinateSpec<br/>coords · x_dim · y_dim"]
    FAC["FacetSpec<br/>col · row · col_wrap"]
    KW["loose colour kwargs<br/>cmap · vmin · vmax · robust<br/>levels · norm · center · extend"]
    SEL --> P["NetCDF.plot(variable, ...)"]
    AXES --> P
    FAC --> P
    KW --> P
    P --> NP["NetCDFPlot<br/>(_plot.py)"]
    NP --> RA["render_array<br/>(_plot_helpers.py)"]
    RA --> CG(["cleopatra ArrayGlyph"])
    CG --> FIG[("glyph<br/>.fig · .ax · .im")]

Colour is expressed exactly as on Dataset.plot — via loose keyword arguments (cmap, vmin, vmax, robust, center, extend, levels, norm) plus the cleopatra render bags (colorbar=, color=, contour=, cells=, data_style=). There is no dedicated colour-options parameter — the colour knobs are loose kwargs, and colorbar=False hides the colour bar.

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

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

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

# curvilinear (WRF) grid -> pcolormesh, faceted over time
nc.plot("T2", axes=CoordinateSpec(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, facet=None, axes=None, kind="auto", animate=None, chunks=None, basemap=None, exclude_value=None, title=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=.
facet FacetSpec, optional Small-multiples grid — col=, row=, col_wrap=.
axes CoordinateSpec, optional Curvilinear coords / dimension names — coords=(x_2d, y_2d) (-> pcolormesh), x_dim=, y_dim=. Auto-detected from CF / WRF / ROMS / NEMO 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 Colour, exactly as Dataset.plot: loose kwargs (cmap, vmin, vmax, robust, center, extend, levels, norm) + cleopatra bags colorbar= (ColorBar(...) / False), color=, contour=, cells=, data_style=; plus ax, figsize.

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, loose colour kwargs such as cmap= / robust= 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.CoordinateSpec dataclass #

How a NetCDF variable's spatial axes are interpreted, for :meth:NetCDF.plot.

Groups the three axis-related plot options into one bag: an explicit curvilinear (x, y) 2-D coordinate pair, or the names of the x / y dimensions when they cannot be auto-resolved from CF attributes. All fields default to None (auto-detect).

Attributes:

Name Type Description
coords tuple | list | None

Explicit (x, y) coordinate arrays for a curvilinear grid, passed straight to the renderer. None auto-detects from CF attributes / conventions.

x_dim str | None

Name of the x (longitude / easting) dimension, when it cannot be inferred. Applying it requires re-resolving the variable from its parent container.

y_dim str | None

Name of the y (latitude / northing) dimension, when it cannot be inferred.

Examples:

  • A curvilinear coordinate pair:

    >>> import numpy as np
    >>> from pyramids.netcdf.plot_options import CoordinateSpec
    >>> x2d, y2d = np.meshgrid(np.arange(4), np.arange(3))
    >>> axes = CoordinateSpec(coords=(x2d, y2d))
    >>> axes.coords[0].shape
    (3, 4)
    
  • Explicit dimension names:

    >>> from pyramids.netcdf.plot_options import CoordinateSpec
    >>> axes = CoordinateSpec(x_dim="rlon", y_dim="rlat")
    >>> (axes.x_dim, axes.y_dim)
    ('rlon', 'rlat')
    
Source code in src/pyramids/netcdf/plot_options.py
@dataclass(frozen=True)
class CoordinateSpec:
    """How a NetCDF variable's spatial axes are interpreted, for :meth:`NetCDF.plot`.

    Groups the three axis-related plot options into one bag: an explicit curvilinear ``(x, y)``
    2-D coordinate pair, or the names of the ``x`` / ``y`` dimensions when they cannot be
    auto-resolved from CF attributes. All fields default to ``None`` (auto-detect).

    Attributes:
        coords: Explicit ``(x, y)`` coordinate arrays for a curvilinear grid, passed straight to
            the renderer. ``None`` auto-detects from CF attributes / conventions.
        x_dim: Name of the ``x`` (longitude / easting) dimension, when it cannot be inferred.
            Applying it requires re-resolving the variable from its parent container.
        y_dim: Name of the ``y`` (latitude / northing) dimension, when it cannot be inferred.

    Examples:
        - A curvilinear coordinate pair:

            ```python
            >>> import numpy as np
            >>> from pyramids.netcdf.plot_options import CoordinateSpec
            >>> x2d, y2d = np.meshgrid(np.arange(4), np.arange(3))
            >>> axes = CoordinateSpec(coords=(x2d, y2d))
            >>> axes.coords[0].shape
            (3, 4)

            ```

        - Explicit dimension names:

            ```python
            >>> from pyramids.netcdf.plot_options import CoordinateSpec
            >>> axes = CoordinateSpec(x_dim="rlon", y_dim="rlat")
            >>> (axes.x_dim, axes.y_dim)
            ('rlon', 'rlat')

            ```
    """

    coords: tuple | list | None = None
    x_dim: str | None = None
    y_dim: str | 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.glyphs.gridded.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.glyphs.gridded.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