Source code for nowcast.figures.day_avg_tracer

# Copyright 2016-2019 Doug Latornell (43ravens)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Produce a figure that shows surface values of a tracer field for the full GoMSS
model domain. The values are day averages. They are displayed as filled colour contours.
The axes grid and tick labels are an angled lon/lat grid using a Lambert Conformal Conic
map projection.

Testing notebook for this module is
https://nbviewer.jupyter.org/urls/bitbucket.org/gomss-nowcast/gomss_nowcast/raw/default/notebooks/figures/TestDayAvgTracer.ipynb

Development notebook for this module is
https://nbviewer.jupyter.org/urls/bitbucket.org/gomss-nowcast/gomss_nowcast/raw/default/notebooks/figures/DevelopDayAvgTracer.ipynb
"""
from types import SimpleNamespace

import matplotlib.pyplot as plt
import numpy
import xarray

import nowcast.figures.website_theme
from nowcast.figures import shared


[docs]def make_figure( results_archive, run_date, var, cmap, bathy, figsize=(16, 9), theme=nowcast.figures.website_theme, ): """Plot colour contours of day averaged tracer variable surface values for the full GoMSS model domain on an angled lon/lat grid using a Lambert Conformal Conic map projection. :param results_archive: Path of directory tree in which NEMO model results are stored. :type results_archive: :py:class:`pathlib.Path` :param run_date: Run date to produce the figure for. :type run_date: :py:class:`arrow.Arrow` :param str var: Name of NEMO results variable to display in figure. :param cmap: Colour map to use for filled contours in figure. :type cmap: :py:class:`matplotlib.colors.ListedColormap` :param bathy: GoMSS NEMO model bathymetry. :type bathy: :py:class:`xarray.Dataset` :param 2-tuple figsize: Figure size (width, height) in inches. :param theme: Module-like object that defines the style elements for the figure. See :py:mod:`nowcast.figures.website_theme` for an example. :return: :py:class:`matplotlib.figure.Figure` """ plot_data = _prep_plot_data(results_archive, run_date, bathy) fig, ax_surface, x, y = _prep_fig_axes(figsize, plot_data, theme) contour_set, isobath = _plot_tracer_surface( ax_surface, x, y, plot_data, var, cmap, theme ) _surface_axes_labels(ax_surface, plot_data, var, contour_set, isobath, theme) return fig
def _prep_plot_data(results_archive, run_date, bathy): """ :param :py:class:`pathlib.Path` results_archive: :param :py:class:`arrow.Arrow` run_date: :param :py:class:`xarray.Dataset` bathy: :return: :py:class:`types.SimpleNamespace` """ yyyymmdd = run_date.format("YYYYMMDD") dataset_path = ( results_archive / run_date.format("YYYY-MM-DD") / f"GoMSS_NOWCAST_1d_{yyyymmdd}_{yyyymmdd}_grid_T.nc" ) day_avg_tracers = xarray.open_dataset(dataset_path) shared.localize_time(day_avg_tracers) return SimpleNamespace( day_avg_tracers=day_avg_tracers, bathy=bathy, tz_name=day_avg_tracers.attrs["tz_name"], ) def _prep_fig_axes(figsize, plot_data, theme): """ :param 2-tuple figsize: Figure size (width, height) in inches. :param :py:class:`types.SimpleNamespace` plot_data: :param :py:mod:`nowcast.figures.website_theme` theme: :return: :py:class:`matplotlib.figure.Figure`, :py:class:`matplotlib.axes.Axes`, :py:class:`numpy.ndarray`, :py:class:`numpy.ndarray` """ fig, ax_surface = plt.subplots( figsize=figsize, facecolor=theme.COLOURS["figure"]["facecolor"] ) x, y = shared.projected_lon_lat_axes( ax_surface, shared.MAP_PARAMS["full domain"], plot_data.bathy, theme ) return fig, ax_surface, x, y def _plot_tracer_surface(ax, x, y, plot_data, var, cmap, theme): """ :param :py:class:`matplotlib.axes.Axes` ax: :param :py:class:`numpy.ndarray` x: :param :py:class:`numpy.ndarray` y: :param :py:class:`types.SimpleNamespace` plot_data: :param str var: :param :py:class:`matplotlib.colors.ListedColormap` cmap: :param :py:mod:`nowcast.figures.website_theme` theme: :return: :py:class:`matplotlib.contour.QuadContourSet`, :py:class:`matplotlib.contour.QuadContourSet` """ tracer = plot_data.day_avg_tracers.data_vars[var].isel(time_counter=0, deptht=0) # tracer as filled contours contour_set = ax.contourf( x, y, tracer, cmap=cmap, levels=numpy.linspace( numpy.floor(tracer.where(tracer > 0).min()), numpy.floor(tracer.where(tracer > 0).max()), 20, ), extend="max", ) # land ax.contourf( x, y, plot_data.bathy.Bathymetry, levels=(-0.01, 0.01), colors=theme.COLOURS["land"], ) # coastline ax.contour( x, y, plot_data.bathy.Bathymetry, levels=(-0.01, 0.01), colors=theme.COLOURS["coastline"], ) # 1000m isobath isobath = ax.contour( x, y, plot_data.bathy.Bathymetry, levels=(1000,), colors=theme.COLOURS["contour lines"]["1000m isobath"], ) return contour_set, isobath def _surface_axes_labels(ax, plot_data, var, contour_set, isobath, theme): """ :param :py:class:`matplotlib.axes.Axes` ax: :param :py:class:`types.SimpleNamespace` plot_data: :param str var: :param :py:class:`matplotlib.contour.QuadContourSet` contour_set: :param :py:class:`matplotlib.contour.QuadContourSet` isobath: :param :py:mod:`nowcast.figures.website_theme` theme: :return: None """ # Colour bar labels cbar = plt.colorbar(contour_set, ax=ax) cbar.ax.axes.tick_params( labelcolor=theme.COLOURS["cbar"]["tick labels"], labelsize=theme.FONTS["cbar"]["tick labels"].get_size(), ) long_name = plot_data.day_avg_tracers.data_vars[var].long_name units = plot_data.day_avg_tracers.data_vars[var].units cbar.set_label( f"Surface {long_name.title()} [{units}]", color=theme.COLOURS["cbar"]["label"], fontproperties=theme.FONTS["cbar"]["label"], ) plt.clabel(isobath, fmt={isobath.levels[0]: f"{isobath.levels[0]:.0f} m"}) # Axes title time = plot_data.day_avg_tracers.temp.time_counter year = time.dt.year.values[0] month = time.dt.month.values[0] day = time.dt.day.values[0] ax.set_title( f"{year}-{month:02d}-{day:02d}\n\n", color=theme.COLOURS["text"]["figure title"], fontproperties=theme.FONTS["figure title"], fontsize=theme.FONTS["figure title"].get_size(), ) # Axes aspect ratio from latitude ax.set_aspect( 1 / numpy.cos(plot_data.day_avg_tracers.nav_lat.median() * numpy.pi / 180) ) # Axes element colours theme.set_axis_colors(ax)