Source code for utopya.eval.plots.time_series

"""A generic, DAG-supporting time series plot"""

import xarray as xr

from . import PlotHelper, is_plot_func

# -----------------------------------------------------------------------------


[docs]@is_plot_func( use_dag=True, required_dag_tags=("data",), helper_defaults=dict(set_limits=dict(x=["min", "max"])), ) def time_series( *, data: dict, hlpr: PlotHelper, x: str = "time", label_fstr: str = "{:.2g}", **plot_kwargs, ): """This is a generic plotting function that plots one or multiple time series from the ``data`` tag that is selected via the DAG framework. The data needs to be an xarray object. If y is an xr.DataArray, it is assumed to be one- or two-dimensional. If is an :py:class:`xarray.Dataset`, all data variables are plotted and their name is used as the label. For the x axis values, the corresponding ``time`` coordinates are used; these need to be part of the dataset! .. note:: For a more generic plot, see dantro's :py:func:`~dantro.plot.funcs.generic.facet_grid`, which is available under ``.plot.facet_grid`` in utopya. Args: data (dict): The data selected by the DAG framework hlpr (PlotHelper): The plot helper x (str, optional): Name of the coordinate dimension to put on the x-axis, typically (and by default) ``time``. label_fstr (str, optional): Formatting to use for label in case of the data being an :py:class:`xarray.DataArray`. **plot_kwargs: Passed on ot :py:func:`matplotlib.pyplot.plot`. """ d = data["data"] # If this is an xr.DataArray, it may be one or two-dimensional if isinstance(d, xr.Dataset): # Simply plot all data variables as individual lines for dvar, line in d.data_vars.items(): hlpr.ax.plot(line.coords[x], line, label=dvar, **plot_kwargs) hlpr.invoke_helper( "set_labels", x=x.capitalize(), mark_disabled_after_use=False ) elif isinstance(d, xr.DataArray): # Also allow two-dimensional arrays if d.ndim == 1: hlpr.ax.plot(d.coords[x], d, **plot_kwargs) elif d.ndim == 2: loop_dim = [dim for dim in d.dims if dim != x][0] for c in d.coords[loop_dim]: line = d.sel({loop_dim: c}) hlpr.ax.plot( line.coords[x], line, label=label_fstr.format(c.item()), **plot_kwargs, ) # Provide a default title to the legend: name of the loop dimension hlpr.invoke_helper( "set_legend", title=f"${loop_dim}$ coordinate", mark_disabled_after_use=False, ) hlpr.invoke_helper( "set_labels", x=x.capitalize(), mark_disabled_after_use=False ) else: raise ValueError( f"Array data needs to be 1D or 2D, but was {d.ndim}D!\n" f"Given data:\n{d}" ) else: raise TypeError(f"Expected xr.Dataset or xr.DataArray, got {type(d)}")