diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3272c9a..0134f62 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,7 +4,9 @@ Changelog 0.4.0 (unreleased) ------------------ -Contributors to this version: Trevor James Smith (:user:`Zeitsperre`), Marco Braun (:user:`vindelico`), Pascal Bourgault (:user:`aulemahal`), Sarah-Claude Bourdeau-Goulet (:user:`Sarahclaude`), Éric Dupuis (:user:`coxipi`) + +Contributors to this version: Trevor James Smith (:user:`Zeitsperre`), Marco Braun (:user:`vindelico`), Pascal Bourgault (:user:`aulemahal`), Sarah-Claude Bourdeau-Goulet (:user:`Sarahclaude`), Éric Dupuis (:user:`coxipi`), Juliette Lavoie (:user:`juliettelavoie`) + New features and enhancements ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,6 +15,7 @@ New features and enhancements * Added style sheet ``transparent.mplstyle`` (:issue:`183`, :pull:`185`) * Fix ``NaN`` issues, extreme values in sizes legend and added edgecolors in ``fg.matplotlib.scattermap`` (:pull:`184`). * New function ``fg.data`` for fetching package data and defined `matplotlib` style definitions. (:pull:`211`). +* New argument ``enumerate_subplots`` for `gridmap`, `timeseries`, `hatchmap` and `scattermap`(:pull:`220`). * ``fg.taylordiagram`` can now accept datasets with many dimensions (not only `taylor_params`), provided that they all share the same `ref_std` (e.g. normalized taylor diagrams) (:pull:`214`). * A new optional way to organize points in a `fg.taylordiagram` with `colors_key`, `markers_key` : DataArrays with a common dimension value or a common attrtibute are grouped with the same color/marker (:pull:`214`). diff --git a/docs/notebooks/figanos_multiplots.ipynb b/docs/notebooks/figanos_multiplots.ipynb index ad7c910..e57bc14 100644 --- a/docs/notebooks/figanos_multiplots.ipynb +++ b/docs/notebooks/figanos_multiplots.ipynb @@ -63,7 +63,8 @@ " plot_kw={'p50': {\"col\": \"lat\"}, 'p90': {\"col\": \"lat\"}},\n", " fig_kw={'figsize':(10,4)},\n", " legend=\"edge\",\n", - " show_lat_lon=True)\n", + " show_lat_lon=True,\n", + " )\n", "\n" ] }, @@ -83,8 +84,9 @@ " legend='facetgrid',\n", " show_lat_lon=False,\n", " fig_kw = {'figsize':(9,4)},\n", - " plot_kw={'tasmax_ssp434': {\"col\": \"lat\"}, 'tasmax_ssp245': {\"col\": \"lat\"}, \"tasmax_ssp585\": {\"col\": \"lat\"}}\n", - " )" + " plot_kw={'tasmax_ssp434': {\"col\": \"lat\"}, 'tasmax_ssp245': {\"col\": \"lat\"}, \"tasmax_ssp585\": {\"col\": \"lat\"}},\n", + " enumerate_subplots=True \n", + " )" ] }, { @@ -113,7 +115,7 @@ " features = ['coastline','ocean'],\n", " frame = False,\n", " use_attrs={\"suptitle\": \"description\"},\n", - "\n", + " enumerate_subplots=True\n", " )\n" ] }, @@ -194,7 +196,9 @@ " },\n", " features = ['coastline','ocean'],\n", " frame = True,\n", - " legend_kw = {'title': 'Ensemble change'})\n", + " legend_kw = {'title': 'Ensemble change'},\n", + " enumerate_subplots=True, \n", + " )\n", "\n", "im.fig.suptitle(\"Multiple hatchmaps\", y=1.08)\n" ] @@ -258,7 +262,6 @@ " },\n", " features = ['coastline','ocean'],\n", " frame = False,\n", - " use_attrs={\"suptitle\": \"description\"}\n", " )\n", "for i, fax in enumerate(im.axs.flat):\n", " fg.scattermap(obs2.isel(time=i),\n", @@ -270,7 +273,7 @@ " 'vmax': vmax,\n", " 'edgecolor':'grey',\n", " 'add_colorbar': False},\n", - " show_time=False\n", + " show_time=False,\n", " )\n", "im.fig.suptitle('Scattermaps over gridmaps', x=0.45, y=0.95)\n" ] diff --git a/src/figanos/matplotlib/plot.py b/src/figanos/matplotlib/plot.py index feeb83c..c4364c4 100644 --- a/src/figanos/matplotlib/plot.py +++ b/src/figanos/matplotlib/plot.py @@ -3,6 +3,7 @@ import copy import math +import string import warnings from collections.abc import Iterable from pathlib import Path @@ -263,6 +264,7 @@ def timeseries( plot_kw: dict[str, Any] | None = None, legend: str = "lines", show_lat_lon: bool | str | int | tuple[float, float] = True, + enumerate_subplots: bool = False, ) -> matplotlib.axes.Axes: """Plot time series from 1D Xarray Datasets or DataArrays as line plots. @@ -304,6 +306,9 @@ def timeseries( 'upper center' 9 'center' 10 ================== ============= + enumerate_subplots: bool + If True, enumerate subplots with letters. + Only works with facetgrids (pass `col` or `row` in plot_kw). Returns ------- @@ -511,6 +516,10 @@ def timeseries( loc=show_lat_lon, backgroundalpha=1, ) + if enumerate_subplots and isinstance(im, xr.plot.facetgrid.FacetGrid): + for idx, ax in enumerate(im.axs.flat): + ax.set_title(f"{string.ascii_lowercase[idx]}) {ax.get_title()}") + return im @@ -530,6 +539,7 @@ def gridmap( divergent: bool | int | float = False, show_time: bool | str | int | tuple[float, float] = False, frame: bool = False, + enumerate_subplots: bool = False, ) -> matplotlib.axes.Axes: """Create map from 2D data. @@ -590,6 +600,9 @@ def gridmap( ================== ============= frame : bool Show or hide frame. Default False. + enumerate_subplots: bool + If True, enumerate subplots with letters. + Only works with facetgrids (pass `col` or `row` in plot_kw). Returns ------- @@ -815,7 +828,13 @@ def gridmap( ) use_attrs.setdefault("suptitle", "long_name") - return set_plot_attrs(use_attrs, data, facetgrid=im) + im = set_plot_attrs(use_attrs, data, facetgrid=im) + if enumerate_subplots and isinstance(im, xr.plot.facetgrid.FacetGrid): + print("here") + for idx, ax in enumerate(im.axs.flat): + ax.set_title(f"{string.ascii_lowercase[idx]}) {ax.get_title()}") + + return im def gdfmap( @@ -1444,6 +1463,7 @@ def scattermap( legend_kw: dict[str, Any] | None = None, show_time: bool | str | int | tuple[float, float] = False, frame: bool = False, + enumerate_subplots: bool = False, ) -> matplotlib.axes.Axes: """Make a scatter plot of georeferenced data on a map. @@ -1510,6 +1530,9 @@ def scattermap( ================== ============= frame : bool Show or hide frame. Default False. + enumerate_subplots: bool + If True, enumerate subplots with letters. + Only works with facetgrids (pass `col` or `row` in plot_kw). Returns ------- @@ -1814,6 +1837,10 @@ def scattermap( else: im.fig.suptitle(get_attributes("long_name", data)) im.set_titles(template="{value}") + if enumerate_subplots and isinstance(im, xr.plot.facetgrid.FacetGrid): + for idx, ax in enumerate(im.axs.flat): + ax.set_title(f"{string.ascii_lowercase[idx]}) {ax.get_title()}") + return im @@ -2179,6 +2206,7 @@ def hatchmap( legend_kw: dict[str, Any] | None = None, show_time: bool | str | int | tuple[float, float] = False, frame: bool = False, + enumerate_subplots: bool = False, ) -> matplotlib.axes.Axes: """Create map of hatches from 2D data. @@ -2231,6 +2259,9 @@ def hatchmap( ================== ============= frame : bool Show or hide frame. Default False. + enumerate_subplots: bool + If True, enumerate subplots with letters. + Only works with facetgrids (pass `col` or `row` in plot_kw). Returns ------- @@ -2521,6 +2552,11 @@ def hatchmap( if dattrs: use_attrs.setdefault("suptitle", "long_name") set_plot_attrs(use_attrs, dattrs, facetgrid=im) + + if enumerate_subplots and isinstance(im, xr.plot.facetgrid.FacetGrid): + for idx, ax in enumerate(im.axs.flat): + ax.set_title(f"{string.ascii_lowercase[idx]}) {ax.get_title()}") + return im