Skip to content

Commit

Permalink
reorder fix docs
Browse files Browse the repository at this point in the history
  • Loading branch information
lukruh committed Sep 5, 2023
1 parent 7d083ca commit bdb9b62
Showing 1 changed file with 123 additions and 131 deletions.
254 changes: 123 additions & 131 deletions esmvaltool/diag_scripts/monitor/multi_datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@
single dimension `height` / `air_pressure`
- Hovmoeller time vs lat or lon (plot type
``hovmoeller_time_vs_lat_or_lon``): # TODO
``hovmoeller_time_vs_lat_or_lon``): A hovmoeller diagram with time on the
Y axis is plotted for each dataset. The input data is expected to be
preprocessed as zonal or meridional mean. The X axis is set accordingly.
Author
------
Expand Down Expand Up @@ -315,8 +317,54 @@
coordinates. Can be adjusted to avoid overlap with the figure. Only
relevant if ``show_stats: true``.
Configuration options for plot type ``1d_profile``
--------------------------------------------------
aspect_ratio: float, optional (default: 1.5)
Aspect ratio of the plot. The default value results in a slender upright
plot.
gridline_kwargs: dict, optional
Optional keyword arguments for grid lines. By default, ``color: lightgrey,
alpha: 0.5`` are used. Use ``gridline_kwargs: false`` to not show grid
lines.
legend_kwargs: dict, optional
Optional keyword arguments for :func:`matplotlib.pyplot.legend`. Use
``legend_kwargs: false`` to not show legends.
log_x: bool, optional (default: False)
Use logarithmic X-axis. Note that for the logarithmic x axis tickmarks are
set so that minor tickmarks show up. Setting of individual tickmarks by
pyplot_kwargs is not recommended in this case.
log_y: bool, optional (default: True)
Use logarithmic Y-axis.
plot_kwargs: dict, optional
Optional keyword arguments for :func:`iris.plot.plot`. Dictionary keys are
elements identified by ``facet_used_for_labels`` or ``default``, e.g.,
``CMIP6`` if ``facet_used_for_labels: project`` or ``historical`` if
``facet_used_for_labels: exp``. Dictionary values are dictionaries used as
keyword arguments for :func:`iris.plot.plot`. String arguments can include
facets in curly brackets which will be derived from the corresponding
dataset, e.g., ``{project}``, ``{short_name}``, ``{exp}``. Examples:
``default: {linestyle: '-', label: '{project}'}, CMIP6: {color: red,
linestyle: '--'}, OBS: {color: black}``.
pyplot_kwargs: dict, optional
Optional calls to functions of :mod:`matplotlib.pyplot`. Dictionary keys
are functions of :mod:`matplotlib.pyplot`. Dictionary values are used as
single argument for these functions. String arguments can include facets in
curly brackets which will be derived from the datasets plotted in the
corresponding plot, e.g., ``{short_name}``, ``{exp}``. Facets like
``{project}`` that vary between the different datasets will be transformed
to something like ``ambiguous_project``. Examples: ``title: 'Awesome Plot
of {long_name}'``, ``xlabel: '{short_name}'``, ``xlim: [0, 5]``.
show_y_minor_ticklabels: bool, optional (default: False)
Show tick labels for the minor ticks on the Y axis.
.. hint::
Extra arguments given to the recipe are ignored, so it is safe to use yaml
anchors to share the configuration of common arguments with other monitor
diagnostic script.
Configuration options for plot type ``hovmoeller time vs lat or lon``
Configuration options for plot type ``hovmoeller_time_vs_lat_or_lon``
----------------------------------------------------------
cbar_label: str, optional (default: '{short_name} [{units}]')
Colorbar label. Can include facets in curly brackets which will be derived
Expand All @@ -335,7 +383,7 @@
plotting biases. These keyword arguments update (and potentially overwrite)
the ``cbar_kwargs`` for the bias plot. This option has no effect if no
reference dataset is given.
common_cbar: bool, optional (default: False)
common_cbar: bool, optional (default: False) # TODO: not tested
Use a common colorbar for the top panels (i.e., plots of the dataset and
the corresponding reference dataset) when using a reference dataset. If
neither ``vmin`` and ``vmix`` nor ``levels`` is given in ``plot_kwargs``,
Expand Down Expand Up @@ -374,62 +422,15 @@
curly brackets which will be derived from the corresponding dataset, e.g.,
``{project}``, ``{short_name}``, ``{exp}``. Examples: ``title: 'Awesome
Plot of {long_name}'``, ``xlabel: '{short_name}'``, ``xlim: [0, 5]``.
rasterize: bool, optional (default: False)
rasterize: bool, optional (default: False) # TODO: not working
If ``True``, use `rasterization
<https://matplotlib.org/stable/gallery/misc/rasterization_demo.html>`_ for
profile plots to produce smaller files. This is only relevant for vector
graphics (e.g., ``output_file_type=pdf,svg,ps``).
show_y_minor_ticklabels: bool, optional (default: False)
Show tick labels for the minor ticks on the Y axis.
show_x_minor_ticklabels: bool, optional (default: False)
Show tick labels for the minor ticks on the X axis.
Configuration options for plot type ``1d_profile``
--------------------------------------------------
aspect_ratio: float, optional (default: 1.5)
Aspect ratio of the plot. The default value results in a slender upright
plot.
gridline_kwargs: dict, optional
Optional keyword arguments for grid lines. By default, ``color: lightgrey,
alpha: 0.5`` are used. Use ``gridline_kwargs: false`` to not show grid
lines.
legend_kwargs: dict, optional
Optional keyword arguments for :func:`matplotlib.pyplot.legend`. Use
``legend_kwargs: false`` to not show legends.
log_x: bool, optional (default: False)
Use logarithmic X-axis. Note that for the logarithmic x axis tickmarks are
set so that minor tickmarks show up. Setting of individual tickmarks by
pyplot_kwargs is not recommended in this case.
log_y: bool, optional (default: True)
Use logarithmic Y-axis.
plot_kwargs: dict, optional
Optional keyword arguments for :func:`iris.plot.plot`. Dictionary keys are
elements identified by ``facet_used_for_labels`` or ``default``, e.g.,
``CMIP6`` if ``facet_used_for_labels: project`` or ``historical`` if
``facet_used_for_labels: exp``. Dictionary values are dictionaries used as
keyword arguments for :func:`iris.plot.plot`. String arguments can include
facets in curly brackets which will be derived from the corresponding
dataset, e.g., ``{project}``, ``{short_name}``, ``{exp}``. Examples:
``default: {linestyle: '-', label: '{project}'}, CMIP6: {color: red,
linestyle: '--'}, OBS: {color: black}``.
pyplot_kwargs: dict, optional
Optional calls to functions of :mod:`matplotlib.pyplot`. Dictionary keys
are functions of :mod:`matplotlib.pyplot`. Dictionary values are used as
single argument for these functions. String arguments can include facets in
curly brackets which will be derived from the datasets plotted in the
corresponding plot, e.g., ``{short_name}``, ``{exp}``. Facets like
``{project}`` that vary between the different datasets will be transformed
to something like ``ambiguous_project``. Examples: ``title: 'Awesome Plot
of {long_name}'``, ``xlabel: '{short_name}'``, ``xlim: [0, 5]``.
show_y_minor_ticklabels: bool, optional (default: False)
Show tick labels for the minor ticks on the Y axis.
.. hint::
Extra arguments given to the recipe are ignored, so it is safe to use yaml
anchors to share the configuration of common arguments with other monitor
diagnostic script.
show_y_minor_ticks: bool, optional (default: True)
Show monthly ticks on the Y axis.
show_x_minor_ticklabels: bool, optional (default: True)
Show minor ticks for latitude or longitude on the X axis.
"""
import logging
from copy import deepcopy
Expand All @@ -447,7 +448,7 @@
from iris.coord_categorisation import add_year
from iris.coords import AuxCoord
from matplotlib.gridspec import GridSpec
from matplotlib.ticker import FormatStrFormatter, LogLocator, NullFormatter
from matplotlib.ticker import FormatStrFormatter, LogLocator, NullFormatter, AutoMinorLocator
from sklearn.metrics import r2_score

import esmvaltool.diag_scripts.shared.iris_helpers as ih
Expand Down Expand Up @@ -624,15 +625,13 @@ def __init__(self, config):
)
self.plots[plot_type].setdefault('pyplot_kwargs', {})
self.plots[plot_type].setdefault('rasterize', False)
self.plots[plot_type].setdefault('show_stats', False)
self.plots[plot_type].setdefault(
'show_y_minor_ticklabels', False
'show_y_minor_ticks', True
)
self.plots[plot_type].setdefault(
'show_x_minor_ticklabels', False
'show_x_minor_ticks', True
)


# Check that facet_used_for_labels is present for every dataset
for dataset in self.input_data:
if self.cfg['facet_used_for_labels'] not in dataset:
Expand Down Expand Up @@ -1150,6 +1149,63 @@ def _plot_zonal_mean_profile_with_ref(self, plot_func, dataset,

return (plot_path, netcdf_paths)

def _plot_zonal_mean_profile_without_ref(self, plot_func, dataset):
"""Plot zonal mean profile for single dataset without reference."""
plot_type = 'zonal_mean_profile'
logger.info("Plotting zonal mean profile without reference dataset"
" for '%s'",
self._get_label(dataset))

# Make sure that the data has the correct dimensions
cube = dataset['cube']
dim_coords_dat = self._check_cube_dimensions(cube, plot_type)

# Create plot with desired settings
with mpl.rc_context(self._get_custom_mpl_rc_params(plot_type)):
fig = plt.figure(**self.cfg['figure_kwargs'])
axes = fig.add_subplot()
plot_kwargs = self._get_plot_kwargs(plot_type, dataset)
plot_kwargs['axes'] = axes
plot_zonal_mean_profile = plot_func(cube, **plot_kwargs)

# Print statistics if desired
self._add_stats(plot_type, axes, dim_coords_dat, dataset)

# Setup colorbar
fontsize = self.plots[plot_type]['fontsize']
colorbar = fig.colorbar(plot_zonal_mean_profile, ax=axes,
**self._get_cbar_kwargs(plot_type))
colorbar.set_label(self._get_cbar_label(plot_type, dataset),
fontsize=fontsize)
colorbar.ax.tick_params(labelsize=fontsize)

# Customize plot
axes.set_title(self._get_label(dataset))
fig.suptitle(f"{dataset['long_name']} ({dataset['start_year']}-"
f"{dataset['end_year']})")
axes.set_xlabel('latitude [°N]')
z_coord = cube.coord(axis='Z')
axes.set_ylabel(f'{z_coord.long_name} [{z_coord.units}]')
if self.plots[plot_type]['log_y']:
axes.set_yscale('log')
axes.get_yaxis().set_major_formatter(
FormatStrFormatter('%.1f'))
if self.plots[plot_type]['show_y_minor_ticklabels']:
axes.get_yaxis().set_minor_formatter(
FormatStrFormatter('%.1f'))
else:
axes.get_yaxis().set_minor_formatter(NullFormatter())
self._process_pyplot_kwargs(plot_type, dataset)

# Rasterization
if self.plots[plot_type]['rasterize']:
self._set_rasterized([axes])

# File paths
plot_path = self.get_plot_path(plot_type, dataset)
netcdf_path = get_diagnostic_filename(Path(plot_path).stem, self.cfg)

return (plot_path, {netcdf_path: cube})

def _plot_hovmoeller_time_vs_lat_or_lon_with_ref(self, plot_func, dataset,
ref_dataset):
Expand Down Expand Up @@ -1258,7 +1314,6 @@ def _plot_hovmoeller_time_vs_lat_or_lon_with_ref(self, plot_func, dataset,

return (plot_path, netcdf_paths)


def _plot_hovmoeller_time_vs_lat_or_lon_without_ref(self, plot_func,
dataset):
"""Plot time vs zonal or meridional Hovmoeller without reference."""
Expand All @@ -1279,8 +1334,6 @@ def _plot_hovmoeller_time_vs_lat_or_lon_without_ref(self, plot_func,
plot_kwargs['axes'] = axes
# Make sure time is on y-axis
plot_kwargs['coords'] = list(reversed(dim_coords_dat))
plt.gca().yaxis.set_major_locator(mdates.YearLocator())
plt.gca().yaxis.set_major_formatter(mdates.DateFormatter("%Y"))
plot_hovmoeller = plot_func(cube, **plot_kwargs)

# Setup colorbar
Expand All @@ -1300,83 +1353,22 @@ def _plot_hovmoeller_time_vs_lat_or_lon_without_ref(self, plot_func,
elif "longitude" in dim_coords_dat:
axes.set_xlabel('Longitude / °E')
axes.set_ylabel('Time / Year')
if self.plots[plot_type]['show_y_minor_ticklabels']:
axes.get_yaxis().set_minor_formatter(
FormatStrFormatter('%.1f'))
else:
axes.get_yaxis().set_minor_formatter(NullFormatter())
if self.plots[plot_type]['show_x_minor_ticklabels']:
axes.get_xaxis().set_minor_formatter(
FormatStrFormatter('%.1f'))
else:
axes.get_yaxis().set_minor_formatter(NullFormatter())
self._process_pyplot_kwargs(plot_type, dataset)

# Rasterization
if self.plots[plot_type]['rasterize']:
self._set_rasterized([axes])

# File paths
plot_path = self.get_plot_path(plot_type, dataset)
netcdf_path = get_diagnostic_filename(Path(plot_path).stem, self.cfg)
return (plot_path, {netcdf_path: cube})

def _plot_zonal_mean_profile_without_ref(self, plot_func, dataset):
"""Plot zonal mean profile for single dataset without reference."""
plot_type = 'zonal_mean_profile'
logger.info("Plotting zonal mean profile without reference dataset"
" for '%s'",
self._get_label(dataset))

# Make sure that the data has the correct dimensions
cube = dataset['cube']
dim_coords_dat = self._check_cube_dimensions(cube, plot_type)

# Create plot with desired settings
with mpl.rc_context(self._get_custom_mpl_rc_params(plot_type)):
fig = plt.figure(**self.cfg['figure_kwargs'])
axes = fig.add_subplot()
plot_kwargs = self._get_plot_kwargs(plot_type, dataset)
plot_kwargs['axes'] = axes
plot_zonal_mean_profile = plot_func(cube, **plot_kwargs)

# Print statistics if desired
self._add_stats(plot_type, axes, dim_coords_dat, dataset)

# Setup colorbar
fontsize = self.plots[plot_type]['fontsize']
colorbar = fig.colorbar(plot_zonal_mean_profile, ax=axes,
**self._get_cbar_kwargs(plot_type))
colorbar.set_label(self._get_cbar_label(plot_type, dataset),
fontsize=fontsize)
colorbar.ax.tick_params(labelsize=fontsize)

# Customize plot
axes.set_title(self._get_label(dataset))
fig.suptitle(f"{dataset['long_name']} ({dataset['start_year']}-"
f"{dataset['end_year']})")
axes.set_xlabel('latitude [°N]')
z_coord = cube.coord(axis='Z')
axes.set_ylabel(f'{z_coord.long_name} [{z_coord.units}]')
if self.plots[plot_type]['log_y']:
axes.set_yscale('log')
axes.get_yaxis().set_major_formatter(
FormatStrFormatter('%.1f'))
if self.plots[plot_type]['show_y_minor_ticklabels']:
axes.get_yaxis().set_minor_formatter(
FormatStrFormatter('%.1f'))
else:
axes.get_yaxis().set_minor_formatter(NullFormatter())
plt.gca().yaxis.set_major_locator(mdates.YearLocator())
plt.gca().yaxis.set_major_formatter(mdates.DateFormatter("%Y"))
if self.plots[plot_type]['show_y_minor_ticks']:
plt.gca().yaxis.set_minor_locator(mdates.MonthLocator())
if self.plots[plot_type]['show_x_minor_ticks']:
plt.gca().xaxis.set_minor_locator(AutoMinorLocator())
self._process_pyplot_kwargs(plot_type, dataset)

# Rasterization
# TODO: seems not to work
if self.plots[plot_type]['rasterize']:
self._set_rasterized([axes])

# File paths
plot_path = self.get_plot_path(plot_type, dataset)
netcdf_path = get_diagnostic_filename(Path(plot_path).stem, self.cfg)

return (plot_path, {netcdf_path: cube})

def _process_pyplot_kwargs(self, plot_type, dataset):
Expand Down

0 comments on commit bdb9b62

Please sign in to comment.