.. currentmodule:: psyplot.data
psyplot defines a :class:`~xarray.DataArray` and a :class:`~xarray.Dataset` accessor. You can use these accessors (see :ref:`xarray:internals`) to visualize your data and to update your plots. The following sections will show you how to make and update plots with these accessors. The plotmethods of the accessors are the same as for the :class:`psyplot.project.plot` object.
The :class:`DatasetAccessor` dataset accessor
Importing the psyplot package registers a new dataset accessor (see
:func:`xarray.register_dataset_accessor`), the
:class:`DatasetAccessor`. You can access it via the psy
attribute of the :class:`~xarray.Dataset` class, i.e.
.. autosummary::
xarray.Dataset.psy
It can be used to visualize the variables in the dataset directly from the dataset itself, e.g.
.. ipython::
:okwarning:
In [1]: import psyplot
In [2]: ds = psyplot.open_dataset("demo.nc")
@savefig docs_dataset_accessor.png width=4in
In [3]: sp = ds.psy.plot.mapplot(name="t2m", cmap="Reds")
The variable sp is a psyplot subproject of the current main project.
.. ipython::
In [4]: print(sp)
@suppress
In [4]: import psyplot.project as psy
...:
...: psy.close("all")
Hence, it would be completely equivalent if you type
.. ipython::
:verbatim:
In [5]: import psyplot.project as psyplot
In [6]: sp = psy.plot.mapplot(ds, name="t2m", cmap="Reds")
Note that the :attr:`DatasetAccessor.plot` attribute has the same plotmethods as the :attr:`psyplot.project.plot` instance.
The :class:`InteractiveArray` dataarray accessor
More advanced then the :ref:`dataset accessor <dataset-accessor>` is the registered DataArray accessor, the :class:`InteractiveArray`.
As well as the :class:`DatasetAccessor`, it is registered as the 'psy'
attribute of any :class:`~xarray.DataArray`, i.e.
.. autosummary::
xarray.DataArray.psy
You can use it for two things:
- create plots of the array
- update the plots and the array
Just use the :attr:`~psyplot.data.InteractiveBase.plot` attribute the accessor.
.. ipython::
In [1]: import psyplot
In [2]: ds = psyplot.open_dataset("demo.nc")
In [3]: da = ds.t2m[0, 0]
# this is a two dimensional array
In [4]: print(da)
# and we can plot it using the mapplot plot method
@savefig docs_dataarray_accessor_1.png width=4in
In [5]: plotter = da.psy.plot.mapplot()
@suppress
In [6]: import matplotlib.pyplot as plt
...:
...: plt.close("all")
The resulting plotter, an instance of the :class:`psyplot.plotter.Plotter`
class, is the object that visualizes the data array. It can also
be accessed via the da.psy.plotter attribute. Note that the creation of
such a plotter overwrites any previous plotter in the da.psy.plotter
attribute.
This methodology does not only work for :class:`DataArrays <xarray.DataArray>`, but also for multiple DataArrays in a :class:`InteractiveList`. This data structure is, for example, used by the :attr:`psy_simple:psyplot.project.plot.lineplot` plot method to visualize multiple lines. Consider the following example:
.. ipython::
In [7]: ds0 = ds.isel(lev=0) # select a subset of the dataset
# create a list of arrays at different longitudes
In [8]: l = psyplot.InteractiveList(
...: [
...: ds0.t2m.sel(lon=2.35, lat=48.86, method="nearest"), # Paris
...: ds0.t2m.sel(lon=13.39, lat=52.52, method="nearest"), # Berlin
...: ds0.t2m.sel(lon=-74.01, lat=40.71, method="nearest"), # NYC
...: ]
...: )
In [9]: l.arr_names = ["Paris", "Berlin", "NYC"]
# plot the list
@savefig docs_dataarray_accessor_2.png width=4in
In [10]: plotter = l.psy.plot.lineplot(xticks="data", xticklabels="%B")
@suppress
In [10]: import matplotlib.pyplot as plt
....: plt.close('all')
Note that for the :class:`InteractiveList`, the :attr:`~InteractiveList.psy` attribute is just the list it self. So it would have been equivalent to call
.. ipython::
:verbatim:
In [11]: l.plot.lineplot()
The :class:`InteractiveArray` accessor is designed for interactive usage of, not only the matplotlib figures, but also of the data. If you selected a subset of a dataset, e.g. via
.. ipython::
In [1]: da = ds.t2m[0, 0]
...: print(da.time) # January 1979
You can change to a different slice using the :meth:`InteractiveArray.update` method.
.. ipython::
In [2]: da.psy.base = ds # tell psyplot the source of the dataarray
In [3]: da.psy.update(time=2)
...: print(da.time) # changed to March 1979
The da.psy.base = ds command hereby tells the dataarray, where it is
coming from, since this information is not known in the standard
xarray framework.
Hint
You can avoid this, using the :meth:`DatasetAccessor.create_list` method of the dataset accessor
.. ipython::
In [4]: da = ds.psy.create_list(time=0, lev=0, name="t2m")[0]
...: print(da.psy.base is ds)
If you plotted the data, you can also change the formatoptions using the :meth:`~InteractiveArray.update` method, e.g.
.. ipython::
# create plot
@savefig docs_dataarray_accessor_3.png width=4in
In[5]: da.psy.plot.mapplot()
.. ipython::
@savefig docs_dataarray_accessor_4.png width=4in
In [6]: da.psy.update(cmap="Reds")
@suppress
In [6]: import matplotlib.pyplot as plt
...:
...: plt.close("all")
The same holds for the Interactive list
.. ipython::
@suppress
In [6]: plotter = l.psy.plot.lineplot(xticks="data", xticklabels="%B")
@savefig docs_dataarray_accessor_5.png width=4in
In [7]: l.update(
...: time=slice(
...: 1, 4
...: ), # change the data by selecting a subset of the timeslice
...: title="Subset", # change a formatoption, the title of the plot
...: )