v3.14 (14 Nov 2025)#

This document explains the changes made to Iris for this release (View all changes.)

v3.14 Release Highlights

The highlights for this minor release of Iris include:

  • Added a convenience function make_gridcube() for creating a 2D cube with a grid of a specified shape. This is useful for functions such as regridding where creating a target cube of a given size is common.

  • Improved functionality of Dataless Cubes. Dataless cubes were introduced in Iris 3.12 with limited functionality, it is now possible to load, save and do the following operations: extract(), collapsed(), aggregated_by(), convert_units(), subset() and slices().

  • Added the utility mask_cube_from_shape(), superceding mask_cube_from_shapefile() and adding the ability to handle shapefiles that use different coordinate systems to the cube they are being applied to, adding the ability to handle additional Point and Line shape types and improving the performance. This was a major piece of work from an external colaborator so big thanks to @hsteptoe!

  • Various performance improvements including:

    • Extending zlib compression to include CF-UGRID data.

    • Improved NetCDF loading when constraining by multiple names.

    • Prevented transient failures in parallelised NetCDF saving (caused by an HDF locking delay).

    • Improved the memory-per-chunk resulting from regridding.

And finally, get in touch with us on GitHub if you have any issues or feature requests for improving Iris. Enjoy!

v3.14.1 (05 Dec 2025)#

v3.14.1 Patches

The patches in this release of Iris include:

  1. Fixed compatibility with NumPy v2 for guess_bounds() See the full entry for more.

  2. Tentative compatibility with Python 3.14, pending full CI support later. See Dependencies for more.

  3. Removed netCDF4<1.7.3 temporary pin.

  4. Enabled Dask versions beyond 2025.10 (2025.10.0 contained a known bug and is therefore disabled).

โœจ Features#

  1. @pp-mo added the make_gridcube() utility function, for making a dataless test-cube with a specified 2D horizontal grid. (Issue #5770, PR #6581, PR #6741)

  2. @hsteptoe and @trexfeathers (reviewer) added iris.util.mask_cube_from_shape() to handle additional Point and Line shape types. This change also facilitates the use of shapefiles that use a different projection system to the cube that they are being applied to, and makes performance improvements to the mask weighting calculations. (Issue #6126, PR #6129).

  3. @bjlittle extended zlib compression of Cube data payload when saving to NetCDF to also include any attached CF-UGRID MeshXY. Additionally, save_mesh() also supports zlib compression. (Issue #6565, PR #6728)

  4. @pp-mo made it possible to save โ€˜datalessโ€™ cubes to a netcdf file, and load them back again. (Issue #6727, PR #6739)

  5. @ukmo-ccbunney added a new CMLSettings class to control the formatting of Cube CML output via a context manager. (Issue #6244, PR #6743)

  6. @ESadek-MO added functionality to allow extract(), collapsed(), aggregated_by(), convert_units(), subset() and slices() to work with dataless cubes. (Issue #6725, PR #6724)

  7. @pp-mo added the ability to merge dataless cubes. This also means they can be re-loaded normally with iris.load(). See: Merging. Also added a new documentation section on dataless cubes. (Issue #6740, PR #6741)

  8. @trexfeathers, @jrackham-mo and @pp-mo added support for lazy calculation in iris.analysis.calculus.cube_delta(). This therefore means that differentiate() also supports lazy calculation. (Issue #6734, PR #6772)

๐Ÿ› Bugs Fixed#

  1. @trexfeathers corrected the ESMF/ESMPy import in iris.experimental.regrid_conservative (the module was renamed to ESMPy in v8.4). Note that regrid_conservative is already deprecated and will be removed in a future release. (PR #6643)

  2. @rcomer fixed a bug in merging cubes with cell measures or ancillary variables. The merged cube now has the cell measures and ancillary variables on the correct dimensions, and merge no longer fails when trying to add them to a dimension of the wrong length. (Issue #2076, PR #6688)

  3. @bjlittle added support for preserving masked auxiliary coordinates when using aggregated_by() or collapsed(). (Issue #6473, PR #6706, PR #6719)

  4. @trexfeathers protected the NetCDF saving code from a transient I/O error, caused by bad synchronisation between Python-layer and HDF-layer file locking on certain filesystems. (PR #6760).

  1. @rcomer ensured that guess_bounds() calculates at double precision for circular coordinates so the bounds span the full circle (Issue #6738, PR #6793)

๐Ÿ’ฃ Incompatible Changes#

  1. Existing users of iris.util.mask_cube_from_shapefile() will need to install the additional dependencies rasterio and affine to continue using this function. These dependencies are necessary to support bug fixes implemented in (Issue #6126, PR #6129). Note that this function will be deprecated in a future version of Iris in favour of the new iris.util.mask_cube_from_shape(), which offers richer shape handling.

๐Ÿš€ Performance#

  1. @trexfeathers investigated a significant performance regression in NetCDF loading and saving, caused by libnetcdf version 4.9.3. The regression is equal to several milliseconds per chunk of parallel operation; so a dataset containing ~100 chunks could be around 0.5 seconds slower to load or save. This regression will NOT be fixed within Iris - doing so would introduce unacceptable complexity and potential concurrency problems. The regession has been reported to the NetCDF team; it is hoped that a future libnetcdf release will recover the original performance. See netcdf-c#3183 for more details. (PR #6747)

  2. @stephenworsley made NetCDF loading more efficient by filtering variables before they become instantiated as cubes in the case where multiple name constraints are given. This was previously only implemented where one such constraint was given. (Issue #6228, PR #6754)

  3. @stephenworsley reduced the memory load for regridding and other operations using map_complete_blocks() when the output chunks would exceed the optimum chunksize set in dask. (PR #6730)

๐Ÿ”— Dependencies#

  1. @hsteptoe added rasterio and affine as optional dependencies that facilitate iris.util.mask_cube_from_shape(). These packages support new functionality that handles additional shapefile types and projections. (Issue #6126, PR #6129)

  2. @pp-mo added a temporary dependency pins for Python<3.14, dask<2025.10.0 and netCDF4<1.7.3. Edit 2025-12-03: the Python pin has now been removed in PR #6817, PR #6826 has removed the netCDF4 pin and replaced the Dask pin with a negation (!=2025.10.0). (Issue #6775, Issue #6776, Issue #6777, PR #6773)

  3. @trexfeathers provided tentative compatibility with Python 3.14 by fixing DimCoord deepcopy behaviour. Note that CI coverage for Python 3.14 is not yet possible due to problems in some fringe dependencies, but the relevant tests have been shown to pass in PR #6816. (Issue #6775, PR #6817)

  4. @trexfeathers fixed an incompatibility with the netCDF4 package (relating to dataset iterability). (Issue #6777, PR #6826)

  5. @trexfeathers replaced the Dask version pin with a negation (!=2025.10.0), as the relevant bug has been fixed in subsequent Dask releases. (Issue #6776, PR #6826)

๐Ÿ“š Documentation#

  1. @rcomer updated all Cartopy references to point to the new location at https://cartopy.readthedocs.io (PR #6636)

  2. @hsteptoe added additional worked examples to Cube Masking in the user guide, and iris.util.mask_cube_from_shape() documentation, to demonstrate how to use the function with different types of shapefiles. (PR #6129)

๐Ÿ’ผ Internal#

  1. @trexfeathers fixed benchmark result comparison to inspect the results for the current machine only. This is useful for setups where a single home-space is shared between multiple machines, as with some virtual desktop arrangements. (PR #6550)

  2. @melissaKG upgraded Irisโ€™ tests to no longer use the deprecated git whatchanged command. (PR #6672)

  3. @ukmo-ccbunney merged functionality of assert_CML_approx_data into assert_CML via the use of a new approx_data keyword. (PR #6713)

  4. @ukmo-ccbunney assert_CML now uses stricter array formatting to avoid changes in tests due to Numpy version changes. (PR #6743)

  5. @stephenworsley added a private switch _CONCRETE_DERIVED_LOADING for controlling laziness of coordinates from pp loading, avoiding a slowdown due to merging. Note: this object is temporary and is likely to be replaced by a permanent solution or else be renamed. (Issue #6755, PR #6767)