Source code for aeolus.plot.cart

"""Plotting functions used with cartopy."""

import cartopy.crs as ccrs
from cartopy.mpl.geoaxes import GeoAxes
from matplotlib.transforms import offset_copy
from mpl_toolkits.axes_grid1 import AxesGrid

from .text import fmt_lonlat

__all__ = ("GeoAxesGrid", "label_global_map_gridlines")


[docs] class GeoAxesGrid(AxesGrid): """ Grid of cartopy axes. A subclass of :class:`mpl_toolkits.axes_grid1.AxesGrid` representing a grid of maps with the same projection :class:`~cartopy.crs.Projection`. - `axes_class` is defined automatically - The :class:`AxesGrid` built-in labelling is always switched off, and instead a standard procedure of creating grid lines and labels should be used. """
[docs] def __init__(self, fig, rect, nrows_ncols, projection, **axesgrid_kw): """ Initialise GeoAxesGrid. Build a :class:`GeoAxesGrid` instance with a grid nrows*ncols :class:`GeoAxes` with a projection :class:`~cartopy.crs.Projection` in :class:`~matplotlib.figure.Figure` *fig* with *rect=[left, bottom, width, height]* (in :class:`~matplotlib.figure.Figure` coordinates) or the subplot position code (e.g., "121"). """ axesgrid_kw["axes_class"] = (GeoAxes, {"map_projection": projection}) axesgrid_kw["label_mode"] = "" # note the empty label_mode super().__init__(fig, rect, nrows_ncols, **axesgrid_kw)
[docs] def label_global_map_gridlines( fig, ax, xticks=None, yticks=None, xoff=-10, yoff=-10, degree=False, **text_kw, ): """ Label gridlines of a global cartopy map. Parameters ---------- fig: matplotlib.figure.Figure Figure object. ax: cartopy.mpl.geoaxes.GeoAxesSubplot Cartopy axes. xticks: array-like, optional Sequence of longitude ticks. yticks: array-like, optional Sequence of latitude ticks. xoff: float, optional Longitude label offset from the axis (units are points). If negative (by default), the labels are drawn at the east boundary, otherwise at the west boundary. yoff: float, optional Latitude label offset from the axis (units are points). If negative (by default), the labels are drawn at the south boundary, otherwise at the north boundary. degree: bool, optional Add a degree symbol to tick labels. **text_kw: dict, optional Label text properties. """ # Define what boundary to use if yticks is None: yticks = [] if xticks is None: xticks = [] extent = ax.get_extent(crs=ccrs.PlateCarree()) if xoff <= 0: xpos = extent[0] # labels at the east boundary else: xpos = extent[1] # labels at the west boundary if yoff <= 0: ypos = extent[2] # labels at the south boundary else: ypos = extent[3] # labels at the north boundary geodetic_trans = ccrs.Geodetic() xlab_kw = ylab_kw = {**{"va": "center", "ha": "center"}, **text_kw} for xtick in xticks: s = fmt_lonlat(xtick, "lon", degree=degree) text_transform = offset_copy( geodetic_trans._as_mpl_transform(ax), fig=fig, units="points", x=0, y=yoff, ) ax.text(xtick, ypos, s, transform=text_transform, **xlab_kw) for ytick in yticks: s = fmt_lonlat(ytick, "lat", degree=degree) text_transform = offset_copy( geodetic_trans._as_mpl_transform(ax), fig=fig, units="points", x=xoff, y=0, ) ax.text(xpos, ytick, s, transform=text_transform, **ylab_kw)