Skip to content

Commit

Permalink
Merge branch 'main' into new_axis_concat_docs
Browse files Browse the repository at this point in the history
* main:
  [pre-commit.ci] pre-commit autoupdate (SciTools#6175)
  Updated environment lockfiles (SciTools#6183)
  Update to `cell_method` parsing (SciTools#6083)
  Bump scitools/workflows from 2024.10.0 to 2024.10.1 (SciTools#6179)
  `colorbar` keyword for iris.quickplot routines (SciTools#6169)
  Make Iris backwards compatible with Cartopy (SciTools#6172)
  Updated environment lockfiles (SciTools#6173)
  Bump scitools/workflows from 2024.09.9 to 2024.10.0 (SciTools#6170)
  Update lock files, pin Cartopy!=0.23 (SciTools#6171)
  • Loading branch information
stephenworsley committed Oct 22, 2024
2 parents e8a5add + b15e3e2 commit 30d2e32
Show file tree
Hide file tree
Showing 16 changed files with 241 additions and 164 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/benchmarks_run.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ jobs:
env:
IRIS_TEST_DATA_LOC_PATH: benchmarks
IRIS_TEST_DATA_PATH: benchmarks/iris-test-data
IRIS_TEST_DATA_VERSION: "2.22"
IRIS_TEST_DATA_VERSION: "2.28"
# Lets us manually bump the cache to rebuild
ENV_CACHE_BUILD: "0"
TEST_DATA_CACHE_BUILD: "2"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-manifest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ concurrency:
jobs:
manifest:
name: "check-manifest"
uses: scitools/workflows/.github/workflows/ci-manifest.yml@2024.09.9
uses: scitools/workflows/.github/workflows/ci-manifest.yml@2024.10.1
3 changes: 2 additions & 1 deletion .github/workflows/ci-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ jobs:
session: "tests"

env:
IRIS_TEST_DATA_VERSION: "2.25"
# NOTE: IRIS_TEST_DATA_VERSION is also set in benchmarks_run.yml
IRIS_TEST_DATA_VERSION: "2.28"
ENV_NAME: "ci-tests"

steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/refresh-lockfiles.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ on:

jobs:
refresh_lockfiles:
uses: scitools/workflows/.github/workflows/refresh-lockfiles.yml@2024.09.9
uses: scitools/workflows/.github/workflows/refresh-lockfiles.yml@2024.10.1
secrets: inherit
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ repos:
- id: no-commit-to-branch

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.6.9"
rev: "v0.7.0"
hooks:
- id: ruff
types: [file, python]
Expand All @@ -51,7 +51,7 @@ repos:
types: [file, python]

- repo: https://github.com/asottile/blacken-docs
rev: 1.18.0
rev: 1.19.0
hooks:
- id: blacken-docs
types: [file, rst]
Expand All @@ -63,7 +63,7 @@ repos:
types: [file, python]

- repo: https://github.com/pre-commit/mirrors-mypy
rev: 'v1.11.2'
rev: 'v1.12.1'
hooks:
- id: mypy
additional_dependencies:
Expand Down
1 change: 1 addition & 0 deletions docs/src/common_links.inc
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,6 @@
.. _@stephenworsley: https://github.com/stephenworsley
.. _@tkknight: https://github.com/tkknight
.. _@trexfeathers: https://github.com/trexfeathers
.. _@ukmo-ccbunney: https://github.com/ukmo-ccbunney
.. _@wjbenfold: https://github.com/wjbenfold
.. _@zklaus: https://github.com/zklaus
21 changes: 19 additions & 2 deletions docs/src/whatsnew/latest.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,27 @@ This document explains the changes made to Iris for this release
equality methods to :class:`iris.io.format_picker.FormatAgent`, as requested
in :issue:`6108`, actioned in :pull:`6119`.

#. `@ukmo-ccbunney`_ added ``colorbar`` keyword to allow optional creation of
the colorbar in the following quickplot methods:

* :meth:`iris.quickplot.contourf`

* :meth:`iris.quickplot.pcolor`

* :meth:`iris.quickplot.pcolormesh`

Requested in :issue:`5970`, actioned in :pull:`6169`.


🐛 Bugs Fixed
=============

#. N/A

#. `@rcomer`_ enabled partial collapse of multi-dimensional string coordinates,
fixing :issue:`3653`. (:pull:`5955`)

#. `@ukmo-ccbunney`_ improved error handling for malformed `cell_method`
attribute. Also made cell_method string parsing more lenient w.r.t.
whitespace. (:pull:`6083`)

💣 Incompatible Changes
=======================
Expand Down Expand Up @@ -95,6 +107,9 @@ This document explains the changes made to Iris for this release
in Iris v3.10.0, :pull:`5948`) to use the same statistical repeat strategy
as timing benchmarks. (:pull:`5981`)

#. `@trexfeathers`_ adapted Iris to work with Cartopy v0.24. (:pull:`6171`,
:pull:`6172`)


.. comment
Whatsnew author names (@github name) in alphabetical order. Note that,
Expand All @@ -105,3 +120,5 @@ This document explains the changes made to Iris for this release

.. comment
Whatsnew resources in alphabetical order:
.. _cartopy#2390: https://github.com/SciTools/cartopy/issues/2390
12 changes: 9 additions & 3 deletions lib/iris/fileformats/_nc_load_rules/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,11 +202,11 @@
_CM_INTERVAL = "interval"
_CM_METHOD = "method"
_CM_NAME = "name"
_CM_PARSE_NAME = re.compile(r"([\w_]+\s*?:\s+)+")
_CM_PARSE_NAME = re.compile(r"([\w_]+\s*?:\s*)+")
_CM_PARSE = re.compile(
r"""
(?P<name>([\w_]+\s*?:\s+)+)
(?P<method>[\w_\s]+(?![\w_]*\s*?:))\s*
(?P<name>([\w_]+\s*?:\s*)+)
(?P<method>[^\s][\w_\s]+(?![\w_]*\s*?:))\s*
(?:
\(\s*
(?P<extra>.+)
Expand Down Expand Up @@ -296,6 +296,12 @@ def _split_cell_methods(nc_cell_methods: str) -> List[re.Match]:
for m in _CM_PARSE_NAME.finditer(nc_cell_methods):
name_start_inds.append(m.start())

# No matches? Must be malformed cell_method string; warn and return
if not name_start_inds:
msg = f"Failed to parse cell method string: {nc_cell_methods}"
warnings.warn(msg, category=iris.warnings.IrisCfLoadWarning, stacklevel=2)
return []

# Remove those that fall inside brackets
bracket_depth = 0
for ind, cha in enumerate(nc_cell_methods):
Expand Down
11 changes: 8 additions & 3 deletions lib/iris/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import datetime
import warnings

import cartopy
import cartopy.crs as ccrs
from cartopy.geodesic import Geodesic
import cartopy.mpl.geoaxes
Expand All @@ -25,6 +26,7 @@
import matplotlib.transforms as mpl_transforms
import numpy as np
import numpy.ma as ma
from packaging.version import Version

import iris.analysis.cartography as cartography
import iris.coord_systems
Expand All @@ -44,8 +46,9 @@


class _GeoAxesPatched(cartopy.mpl.geoaxes.GeoAxes):
# TODO: see cartopy#2390
# Remove this once the bug is addressed in a Cartopy release.
# Workaround for a bug where titles collide with axis labels (cartopy#2390)
# Bug is only present in Cartopy v0.23, so this will only be invoked for
# that version.
def _draw_preprocess(self, renderer):
super()._draw_preprocess(renderer)

Expand All @@ -57,7 +60,9 @@ def _draw_preprocess(self, renderer):
artist._draw_gridliner(renderer=renderer)


cartopy.mpl.geoaxes.GeoAxes = _GeoAxesPatched
cartopy_version = Version(cartopy.__version__)
if cartopy_version.major == 0 and cartopy_version.minor == 23:
cartopy.mpl.geoaxes.GeoAxes = _GeoAxesPatched


def _get_plot_defn_custom_coords_picked(cube, coords, mode, ndims=2):
Expand Down
41 changes: 32 additions & 9 deletions lib/iris/quickplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,15 @@ def _title(cube_or_coord, with_units):
return title


def _label(cube, mode, result=None, ndims=2, coords=None, axes=None):
def _label(cube, mode, result=None, ndims=2, coords=None, axes=None, colorbar=True):
"""Put labels on the current plot using the given cube."""
if axes is None:
axes = plt.gca()

axes.set_title(_title(cube, with_units=False))

if result is not None:
# optional colorbar
if colorbar and result is not None:
draw_edges = mode == iris.coords.POINT_MODE
bar = plt.colorbar(
result, ax=axes, orientation="horizontal", drawedges=draw_edges
Expand Down Expand Up @@ -89,12 +90,16 @@ def _label(cube, mode, result=None, ndims=2, coords=None, axes=None):
raise ValueError(msg)


def _label_with_bounds(cube, result=None, ndims=2, coords=None, axes=None):
_label(cube, iris.coords.BOUND_MODE, result, ndims, coords, axes)
def _label_with_bounds(
cube, result=None, ndims=2, coords=None, axes=None, colorbar=True
):
_label(cube, iris.coords.BOUND_MODE, result, ndims, coords, axes, colorbar)


def _label_with_points(cube, result=None, ndims=2, coords=None, axes=None):
_label(cube, iris.coords.POINT_MODE, result, ndims, coords, axes)
def _label_with_points(
cube, result=None, ndims=2, coords=None, axes=None, colorbar=True
):
_label(cube, iris.coords.POINT_MODE, result, ndims, coords, axes, colorbar)


def _get_titles(u_object, v_object):
Expand Down Expand Up @@ -181,6 +186,11 @@ def contourf(cube, *args, **kwargs):
contour(cube, V)
Keywords
--------
colorbar : bool, default=True
If True, an appropriate colorbar will be added to the plot.
See :func:`iris.plot.contourf` for details of valid keyword arguments.
Notes
Expand All @@ -190,8 +200,9 @@ def contourf(cube, *args, **kwargs):
"""
coords = kwargs.get("coords")
axes = kwargs.get("axes")
colorbar = kwargs.pop("colorbar", True)
result = iplt.contourf(cube, *args, **kwargs)
_label_with_points(cube, result, coords=coords, axes=axes)
_label_with_points(cube, result, coords=coords, axes=axes, colorbar=colorbar)
return result


Expand Down Expand Up @@ -229,6 +240,11 @@ def outline(cube, coords=None, color="k", linewidth=None, axes=None):
def pcolor(cube, *args, **kwargs):
"""Draw a labelled pseudocolor plot based on the given Cube.
Keywords
--------
colorbar : bool, default=True
If True, an appropriate colorbar will be added to the plot.
See :func:`iris.plot.pcolor` for details of valid keyword arguments.
Notes
Expand All @@ -238,14 +254,20 @@ def pcolor(cube, *args, **kwargs):
"""
coords = kwargs.get("coords")
axes = kwargs.get("axes")
colorbar = kwargs.pop("colorbar", True)
result = iplt.pcolor(cube, *args, **kwargs)
_label_with_bounds(cube, result, coords=coords, axes=axes)
_label_with_bounds(cube, result, coords=coords, axes=axes, colorbar=colorbar)
return result


def pcolormesh(cube, *args, **kwargs):
"""Draw a labelled pseudocolour plot based on the given Cube.
Keywords
--------
colorbar : bool, default=True
If True, an appropriate colorbar will be added to the plot.
See :func:`iris.plot.pcolormesh` for details of valid keyword arguments.
Notes
Expand All @@ -256,8 +278,9 @@ def pcolormesh(cube, *args, **kwargs):
"""
coords = kwargs.get("coords")
axes = kwargs.get("axes")
colorbar = kwargs.pop("colorbar", True)
result = iplt.pcolormesh(cube, *args, **kwargs)
_label_with_bounds(cube, result, coords=coords, axes=axes)
_label_with_bounds(cube, result, coords=coords, axes=axes, colorbar=colorbar)
return result


Expand Down
9 changes: 6 additions & 3 deletions lib/iris/tests/results/imagerepo.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"gallery_tests.test_plot_COP_1d.0": "aefec91c3601249cc9b3336dc4c8cdb31a64c6d997b3c0eccb5932d285e42f33",
"gallery_tests.test_plot_COP_maps.0": "ea91789995668566913e43474adb6a917e8d947c4b46957ec6716a91958e6f81",
"gallery_tests.test_plot_SOI_filtering.0": "fa56f295c5e0694a3c17a58d95e8da536233da99984c5af4c6739b4a9a444eb4",
"gallery_tests.test_plot_TEC.0": "e5a761b69a589a4bc46f9e48c65c6631ce61d1ce3982c13739b33193c0ee3f8c",
"gallery_tests.test_plot_TEC.0": "e59661969a589a49c06f1e69c27c66314e71c06e3986c1b739b33993c1df3fc4",
"gallery_tests.test_plot_anomaly_log_colouring.0": "ec4464e384a39b13931a9b1c85696da968d5e6e63e26847bdbd399938d3c5a4c",
"gallery_tests.test_plot_atlantic_profiles.0": "97c160f462a88f07203ebc77a1e36707e61f4e38d8f3d08a910597fc877cec58",
"gallery_tests.test_plot_atlantic_profiles.1": "eeea64dd6ea8cd99991d1322b3741e2684571cd89995b3131f32a4765ee2a1cc",
Expand All @@ -12,7 +12,7 @@
"gallery_tests.test_plot_custom_aggregation.0": "ee816f81917e907eb03ec73f856f7ac198d070186e90811f1be33ee1a57a6e18",
"gallery_tests.test_plot_custom_file_loading.0": "fa81cb47845e34bc932797436cccc8343f11359b73523746c48c72d9d9b34da5",
"gallery_tests.test_plot_deriving_phenomena.0": "ec97681793689768943c97e8926669d186e8c33f6c99c32e6b936c83d33e2c98",
"gallery_tests.test_plot_global_map.0": "fb997b958466846ed13e87467a997a898d66d17e2cc9906684696f99d3162e81",
"gallery_tests.test_plot_global_map.0": "fb997b958466846ed13e87467b997a898d66d1762cc9806684696f99d3162f81",
"gallery_tests.test_plot_hovmoller.0": "eeb46cb4934b934bc07e974bc14b38949943c0fe3e94c17f6ea46cb4c07b3f00",
"gallery_tests.test_plot_inset.0": "ebff6992b50096ad9267dac4d640949294924cdbc95d4b699d29952dcda46ed4",
"gallery_tests.test_plot_lagged_ensemble.0": "bbbb31b1c44e64e4b1579b5b917133cecc61f146c414668eb1119b1bb197ce34",
Expand Down Expand Up @@ -67,7 +67,7 @@
"iris.tests.test_mapping.TestLowLevel.test_params.1": "be21a71bc1de58e43a63a71b3e016061c1fe9b8c3e01a473847e5b94d1fb9ac3",
"iris.tests.test_mapping.TestLowLevel.test_params.2": "fa81909f857e6520957e7acc7a8194716e31851e857e6ac281fe3ba17a81963f",
"iris.tests.test_mapping.TestLowLevel.test_simple.0": "faa0e558855f9de7857a1ab16a85a51d36a1e55a854e58a5c13837096e8fe17a",
"iris.tests.test_mapping.TestMappingSubRegion.test_simple.0": "b9913d90c66eca6ec66ec2f3689195aecf5b2f00392cb3496495e21da4db6c92",
"iris.tests.test_mapping.TestMappingSubRegion.test_simple.0": "b9913d90c66eca6ec66ee2fb689195a6cf522f00392cb149648de69fa4db6c90",
"iris.tests.test_mapping.TestUnmappable.test_simple.0": "fa81b54a817eca37817ec701857e3e64943e7bb41b806f996e817e006ee1b19b",
"iris.tests.test_plot.Test1dFillBetween.test_coord_coord.0": "f31432798cebcd87723835b4a5c5c2dbcf139c6c8cf4730bf3c36d801e380378",
"iris.tests.test_plot.Test1dFillBetween.test_coord_cube.0": "ea17352b92f0cbd42d6c8d25e59d36dc3a538d2bb2e42d26c6d2c2c8e4a1ce99",
Expand Down Expand Up @@ -212,10 +212,13 @@
"iris.tests.test_quickplot.TestLabels.test_contourf.1": "bf802f85c17fc17fc07eb42ac17f3f929130c06e3f80c07f7aa02e85c07f3e81",
"iris.tests.test_quickplot.TestLabels.test_contourf.2": "be816a95907ae508c17e955ac07f3fa0945bc07f3f80c07f3aa36f01c0ff3f80",
"iris.tests.test_quickplot.TestLabels.test_contourf_nameless.0": "be816af5907ee508c17e955ac03f3f809419c07f3f80c07f3a8b6f81c0ff3f80",
"iris.tests.test_quickplot.TestLabels.test_contourf_no_colorbar.0": "bf80c391c17fe07ec07e1d1a917e3f42917879224834487c6e24ca3e2f87c2ff",
"iris.tests.test_quickplot.TestLabels.test_map.0": "e85a634c86a597a793c9349b94b79969c396c95bcce69a64d938c9b039a58ca6",
"iris.tests.test_quickplot.TestLabels.test_map.1": "e85a636c86a597a793c9349b94b69969c396c95bcce69a64d938c9b039a58ca6",
"iris.tests.test_quickplot.TestLabels.test_pcolor.0": "eea16affc05ab500956e974ac53f3d80925ac03f2f81c07e3fa12da1c2fe3f80",
"iris.tests.test_quickplot.TestLabels.test_pcolor_no_colorbar.0": "eea1c2dac51ab54a905e2d20905a6da5d05e6da19d60dade6da1dade6da1d2d8",
"iris.tests.test_quickplot.TestLabels.test_pcolormesh.0": "eea16affc05ab500956e974ac53f3d80925ac03f2f81c07e3fa12da1c2fe3f80",
"iris.tests.test_quickplot.TestLabels.test_pcolormesh_no_colorbar.0": "eea1c2dac51ab54a905e2d20905a6da1d05e6da19d60dade6da1dade6da1d2dc",
"iris.tests.test_quickplot.TestLabels.test_pcolormesh_str_symbol.0": "eea16affc05ab500956e974ac53f3d80925ac03f3f80c07e3fa12d21c2ff3f80",
"iris.tests.test_quickplot.TestPlotHist.test_horizontal.0": "b59cc3dadb433c24c4f166039438793591a7dbdcbcdc9ccc68c697a91b139131",
"iris.tests.test_quickplot.TestPlotHist.test_vertical.0": "bf80c7c6c07d7959647e343a33364b699589c6c64ec0312b9e227ad681ffcc68",
Expand Down
16 changes: 16 additions & 0 deletions lib/iris/tests/test_quickplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,22 @@ def test_contourf_nameless(self):
qplt.contourf(cube, coords=["grid_longitude", "model_level_number"])
self.check_graphic()

def test_contourf_no_colorbar(self):
qplt.contourf(
self._small(),
colorbar=False,
coords=["model_level_number", "grid_longitude"],
)
self.check_graphic()

def test_pcolor(self):
qplt.pcolor(self._small())
self.check_graphic()

def test_pcolor_no_colorbar(self):
qplt.pcolor(self._small(), colorbar=False)
self.check_graphic()

def test_pcolormesh(self):
qplt.pcolormesh(self._small())

Expand All @@ -193,6 +205,10 @@ def test_pcolormesh_str_symbol(self):

self.check_graphic()

def test_pcolormesh_no_colorbar(self):
qplt.pcolormesh(self._small(), colorbar=False)
self.check_graphic()

def test_map(self):
cube = self._slice(["grid_latitude", "grid_longitude"])
qplt.contour(cube)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class Test(tests.IrisTest):
def test_simple(self):
cell_method_strings = [
"time: mean",
"time:mean",
"time : mean",
]
expected = (CellMethod(method="mean", coords="time"),)
Expand Down Expand Up @@ -125,6 +126,7 @@ def test_badly_formatted_warning(self):
cell_method_strings = [
# "time: maximum (interval: 1 hr comment: first bit "
# "time: mean (interval: 1 day comment: second bit)",
"time",
"time: (interval: 1 hr comment: first bit) "
"time: mean (interval: 1 day comment: second bit)",
"time: maximum (interval: 1 hr comment: first bit) "
Expand Down
Loading

0 comments on commit 30d2e32

Please sign in to comment.