_images/wavespectra_logo.png

Plotting#

Wavespectra wraps the plotting functionality from xarray to allow easily defining frequency-direction spectral plots in polar coordinates.

In [1]: import matplotlib.pyplot as plt

In [2]: import cmocean

In [3]: from wavespectra import read_swan, read_era5

In [4]: dset = read_era5("_static/era5file.nc").isel(time=0)

In [5]: ds = dset.isel(lat=0, lon=0)

Simplest usage#

The plot method is available in SpecArray. The simplest usage takes no arguments and defines sensible settings for plotting normalised spectra on logarithmic radii and countour levels:

In [6]: ds.spec.plot();
savefig/single_polar_plot.png

Plotting types#

Wavespectra supports xarray’s contour, `contourf`_ and pcolormesh plotting types.

Contour#

In [7]: ds.spec.plot(kind="contour", colors="#af1607", linewidths=0.5);
savefig/contour_type_plot.png

Contourf#

In [8]: ds.spec.plot(kind="contourf", cmap=cmocean.cm.thermal);
savefig/contourf_type_plot.png

Pcolormesh#

In [9]: ds.spec.plot(kind="pcolormesh", cmap=cmocean.cm.thermal);
savefig/pcolormesh_type_plot.png

Wave period spectrum#

Frequency-direction spectra can be easily plotted in the period space.

In [10]: ds.spec.plot(as_period=True, cmap="pink_r");
savefig/single_polar_plot_period.png

Normalised#

The normalised spectrum \(\frac{E_{d}(f,d)}{\max{E_{d}}}\) is plotted by default but the actual values can be shown instead:

In [11]: ds.spec.plot(as_period=True, normalised=False, cmap="Spectral_r");
savefig/single_polar_plot_period_realvalues.png

Logarithmic contour levels are only default for normalised spectra but they can be still manually specified:

In [12]: ds.spec.plot(
   ....:     as_period=True,
   ....:     normalised=False,
   ....:     cmap="Spectral_r",
   ....:     levels=np.logspace(np.log10(0.005), np.log10(0.4), 15),
   ....:     cbar_ticks=[0.01, 0.1, 1],
   ....: );
   ....: 
savefig/single_polar_plot_period_realvalues_loglevels.png

Logarithmic radii#

Radii are shown in a logarithmic scale by default. Linear radii can be defined by setting logradius=False (radii ticks can be prescribed from the radii_ticks paramater):

In [13]: ds.spec.plot(
   ....:     as_period=True,
   ....:     normalised=False,
   ....:     levels=15,
   ....:     cmap="bone_r",
   ....:     logradius=False,
   ....:     radii_ticks=[5, 10, 15, 20, 25],
   ....: );
   ....: 
savefig/single_polar_plot_period_linear_radii.png

Hint

The as_log10 option to plot the \(\log{E_{d}(f,d)}\) has been deprecated but similar result can be achieved by calculating the \(\log{E_{d}(f,d)}\) beforehand:

In [14]: ds1 = ds.where(ds>0, 1e-5) # Avoid infinity values

In [15]: ds1 = np.log10(ds1)

In [16]: ds1.spec.plot(
   ....:     as_period=True,
   ....:     logradius=False,
   ....:     cbar_kwargs={"label": "Normalised $\log{E_{d}(f,d)}$"},
   ....:     vmin=0.39,
   ....:     levels=15,
   ....:     extend="both",
   ....:     cmap=cmocean.cm.thermal,
   ....: );
   ....: 
savefig/replicate_as_log10.png

Radii extents#

The radii extents are controlled from rmin and rmax parameters:

In [17]: ds.spec.plot(
   ....:     rmin=0,
   ....:     rmax=0.15,
   ....:     logradius=False,
   ....:     normalised=False,
   ....:     levels=25,
   ....:     cmap="gray_r",
   ....:     radii_ticks=[0.03, 0.06, 0.09, 0.12, 0.15],
   ....:     radii_labels=["0.05", "0.1", "0.15Hz"],
   ....:     radii_labels_angle=120,
   ....:     radii_labels_size=7,
   ....: );
   ....: 

In [18]: plt.draw()
savefig/single_polar_plot_ax_extent3.png

Exclusive plotting parameters from wavespectra

  • kind (“contourf”) : Plot kind, one of (“contourf”, “contour”, “pcolormesh”).

  • normalised (True): Plot the normalised \(E(f,d)\) between 0 and 1.

  • logradius (True): Set log radii.

  • as_period (False): Set wave period radii instead of frequency.

  • show_radii_labels (True): Display the radii tick labels.

  • show_theta_labels (False): Display the directions tick labels.

  • radii_ticks (array): Tick values for radii.

  • radii_labels_angle (22.5): Polar angle at which radii labels are positioned.

  • radii_labels_size (8): Fontsize for radii labels.

  • cbar_ticks: Tick values for colorbar (default depends if normalised, logradius and as_period).

  • clean_axis (False): Remove radii and theta ticks for a clean view.

Plotting parameters from xarray#

Wavespectra allows passing some parameters from the functions wrapped from xarray such as contourf (excluding some that are manipulated in wavespectra such as ax, x and others):

In [19]: ds.spec.plot(
   ....:     kind="contourf",
   ....:     cmap="turbo",
   ....:     add_colorbar=False,
   ....:     extend="both",
   ....:     levels=25,
   ....: );
   ....: 
savefig/single_polar_plot_xarray_parameters.png

Some of the xarray parameters that are not exposed in wavespectra

  • projection: Always set to “polar”.

  • x, y: Set to wavespectra coordinates naming.

  • xlabel, ylabel: Disabled.

  • ax, aspect, size: Conflict with axes defined in wavespectra.

  • xlim, ylim: produce no effect.

Faceting#

Xarray’s faceting capability is fully supported.

In [20]: dset.spec.plot(
   ....:     col="lon",
   ....:     row="lat",
   ....:     figsize=(16,8),
   ....:     add_colorbar=False,
   ....:     show_theta_labels=False,
   ....:     show_radii_labels=True,
   ....:     radii_ticks=[0.05, 0.1, 0.2, 0.4],
   ....:     rmax=0.4,
   ....:     radii_labels_size=5,
   ....:     cmap="Spectral_r",
   ....: );
   ....: 

In [21]: plt.tight_layout()

In [22]: plt.draw()
savefig/faceted.png

Clean axes#

Use the clean_axis argument to remove radii and theta grids for a clean overview. This is equivalent to disabling ticks from the axis by calling ax.set_rticks=[], ax.set_xticks=[].

In [23]: dset1 = dset.where(dset>0, 1e-5)

In [24]: dset1 = np.log10(dset1)

In [25]: dset1.spec.plot(
   ....:     clean_axis=True,
   ....:     col="lon",
   ....:     row="lat",
   ....:     figsize=(16,8),
   ....:     logradius=False,
   ....:     vmin=0.39,
   ....:     levels=15,
   ....:     extend="both",
   ....:     cmap=cmocean.cm.thermal,
   ....:     add_colorbar=False,
   ....: );
   ....: 

In [26]: plt.tight_layout()

In [27]: plt.draw()
savefig/faceted_cleanaxis.png