Plotting Functions

Timeseries

elm_diagnostics.plots.plot_timeseries(source, varname, *, by=None, config=None, ax=None)[source]

Plot a variable’s time series.

For a Run: single line with optional climatology envelope. For a Comparison: base (gray) and experiment (accent) overlaid.

Parameters:
  • source (Run | Comparison)

  • varname (str) – Variable name to plot

  • by (Optional[Literal['column', 'pft', 'landunit']]) – Facet plots by sub-gridcell dimension. Creates separate subplot for each subgrid unit. Only works with dov2xy=.false. output. Cannot be combined with the ax parameter.

  • config (Config | None)

  • ax (Axes | None) – Axes to plot into. Cannot be combined with by parameter.

Return type:

Figure

Raises:

ValueError – If by is specified but variable doesn’t have that dimension, or if dataset uses gridcell-averaged output (dov2xy=.true.), or if both by and ax are specified.

Examples

>>> from elm_diagnostics import Run
>>> from elm_diagnostics.plots import plot_timeseries
>>> run = Run("/path/to/output")
>>> fig = plot_timeseries(run, "GPP")
>>> fig = plot_timeseries(run, "GPP", by="column")

Seasonal Cycle

elm_diagnostics.plots.plot_seasonal(source, varname, *, by=None, config=None, ax=None)[source]

Plot the seasonal (monthly) cycle of a variable.

Shows the multi-year monthly mean with a spread envelope. For a Comparison, overlays base and experiment.

Parameters:
  • source (Run | Comparison)

  • varname (str)

  • by (Optional[Literal['column', 'pft', 'landunit']]) – Facet plots by sub-gridcell dimension. Creates separate subplot for each subgrid unit. Only works with dov2xy=.false. output. Cannot be combined with the ax parameter.

  • config (Config | None)

  • ax (Axes | None) – Axes to plot into. Cannot be combined with by parameter.

Return type:

Figure

Raises:

ValueError – If by is specified but variable doesn’t have that dimension, or if dataset uses gridcell-averaged output (dov2xy=.true.), or if both by and ax are specified.

Anomalies

elm_diagnostics.plots.plot_anomaly(source, varname, *, by=None, config=None, ax=None)[source]

Plot annual anomalies of a variable as a bar chart.

Positive anomalies in blue, negative in red. For a Comparison, shows the difference (experiment - base).

Parameters:
  • source (Run | Comparison)

  • varname (str)

  • by (Optional[Literal['column', 'pft', 'landunit']]) – Facet plots by sub-gridcell dimension. Creates separate subplot for each subgrid unit. Only works with dov2xy=.false. output. Cannot be combined with the ax parameter.

  • config (Config | None)

  • ax (Axes | None) – Axes to plot into. Cannot be combined with by parameter.

Return type:

Figure

Raises:

ValueError – If by is specified but variable doesn’t have that dimension, or if dataset uses gridcell-averaged output (dov2xy=.true.), or if both by and ax are specified.

Histogram

elm_diagnostics.plots.plot_histogram(source, varname, *, bins=50, density=True, by=None, config=None, ax=None)[source]

Plot a histogram of a variable’s values over time.

For a Comparison, overlays base and experiment distributions.

Parameters:
  • source (Run | Comparison)

  • varname (str)

  • bins (int)

  • density (bool) – If True, plot probability density.

  • by (Optional[Literal['column', 'pft', 'landunit']]) – Facet plots by sub-gridcell dimension. Creates separate subplot for each subgrid unit. Only works with dov2xy=.false. output. Cannot be combined with the ax parameter.

  • config (Config | None)

  • ax (Axes | None) – Axes to plot into. Cannot be combined with by parameter.

Return type:

Figure

Raises:

ValueError – If by is specified but variable doesn’t have that dimension, or if dataset uses gridcell-averaged output (dov2xy=.true.), or if both by and ax are specified.

Diurnal Cycle

elm_diagnostics.plots.plot_diurnal(source, varname, *, by=None, config=None, ax=None)[source]

Plot the diurnal (hourly) cycle of a variable.

Only works with sub-daily data (e.g., h1 tapes with hourly output). Shows the multi-day mean diurnal cycle with spread envelope.

For a Comparison, overlays base and experiment cycles.

Parameters:
  • source (Run | Comparison) – Data source containing sub-daily output.

  • varname (str) – Variable name to plot.

  • by (Optional[Literal['column', 'pft', 'landunit']]) – Facet plots by sub-gridcell dimension. Creates separate subplot for each subgrid unit. Only works with dov2xy=.false. output. Cannot be combined with the ax parameter.

  • config (Config | None) – Configuration object. If None, loads default config.

  • ax (Axes | None) – Axes to plot on. If None, creates new figure. Cannot be combined with by parameter.

Return type:

Figure

Raises:

ValueError – If data is not sub-daily (less than 24 time steps per day), or if by is specified but variable doesn’t have that dimension, or if dataset uses gridcell-averaged output (dov2xy=.true.), or if both by and ax are specified.

Sub-gridcell Helpers

Helper functions for faceting plots by sub-gridcell dimensions.

elm_diagnostics.plots.subgrid_helpers.calculate_facet_layout(n_units)[source]

Calculate optimal (nrows, ncols) layout for n subgrid units.

The layout aims for a roughly square grid, with preference for wider-than-tall layouts for better use of screen space.

Parameters:

n_units (int) – Number of sub-gridcell units to plot

Returns:

(nrows, ncols) for subplot layout

Return type:

tuple[int, int]

Examples

>>> calculate_facet_layout(1)
(1, 1)
>>> calculate_facet_layout(3)
(1, 3)
>>> calculate_facet_layout(4)
(2, 2)
>>> calculate_facet_layout(6)
(2, 3)
>>> calculate_facet_layout(9)
(3, 3)
elm_diagnostics.plots.subgrid_helpers.create_facet_figure(n_units, style, sharex=True, sharey=True)[source]

Create figure with subplots for faceting by sub-gridcell units.

Parameters:
  • n_units (int) – Number of sub-gridcell units to plot

  • style (PlotStyleConfig) – Style configuration (figsize, dpi)

  • sharex (bool) – Share x-axis across subplots

  • sharey (bool) – Share y-axis across subplots

Return type:

tuple[Figure, ndarray]

Returns:

  • fig (matplotlib.figure.Figure)

  • axes (numpy.ndarray) – Flattened array of axes (1D), with length ≥ n_units. Unused axes (if grid is larger than n_units) should be hidden by the caller.

Warning

Issues a warning if n_units > 16 (large figures may be slow to render or difficult to read).

elm_diagnostics.plots.subgrid_helpers.validate_variable_for_subgrid(da, by, varname)[source]

Validate that a variable has the requested sub-gridcell dimension.

Parameters:
  • da (DataArray) – Variable data array

  • by (Literal['column', 'pft', 'landunit']) – Requested sub-gridcell dimension

  • varname (str) – Variable name (for error message)

Raises:

ValueError – If the variable does not have the requested dimension, or if the dimension has size ≤ 1 (making faceting meaningless).

Return type:

None

elm_diagnostics.plots.subgrid_helpers.get_subgrid_units(da, by)[source]

Extract list of sub-gridcell unit indices from a DataArray.

Parameters:
  • da (DataArray) – Data array with sub-gridcell dimension

  • by (Literal['column', 'pft', 'landunit']) – Sub-gridcell dimension name

Returns:

Sorted list of unit indices along the specified dimension

Return type:

list[int]

elm_diagnostics.plots.subgrid_helpers.format_subgrid_title(by, unit_id)[source]

Format a subplot title for a sub-gridcell unit.

Parameters:
  • by (Literal['column', 'pft', 'landunit']) – Sub-gridcell level

  • unit_id (int) – Unit index/ID

Returns:

Formatted title (e.g., “Column 1”, “PFT 12”, “Landunit 3”)

Return type:

str

Examples

>>> format_subgrid_title("column", 1)
'Column 1'
>>> format_subgrid_title("pft", 12)
'PFT 12'
>>> format_subgrid_title("landunit", 3)
'Landunit 3'