v3.1 (17 Sep 2021)

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

📢 Announcements

  1. Congratulations to @jamesp who recently became an Iris core developer after joining the Iris development team at the Met Office. 🎉

  2. A special thanks goes to @akuhnregnier, @gcaria, @jamesp, @schlunma, @MHBalsmeier and @Badboy-16 all of whom made their first contributions to Iris, which were gratefully received and included in this release. Keep up the awesome work! 🍻

✨ Features

  1. @pelson and @trexfeathers enhanced iris.plot.plot() and iris.quickplot.plot() to automatically place the cube on the x axis if the primary coordinate being plotted against is a vertical coordinate. E.g. iris.plot.plot(z_cube) will produce a z-vs-phenomenon plot, where before it would have produced a phenomenon-vs-z plot. (PR #3906)

  2. @jonseddon added iris.plot.barbs() to provide a convenient way to use matplotlib.pyplot.barbs() with Iris cubes. A gallery example was included to illustrate the new method’s use. (PR #3710)

  3. @bjlittle introduced iris.common.metadata.hexdigest() to the public API. Previously it was a private function introduced in v3.0.0. Given any object, hexdigest() returns a string representation of the 64-bit non-cryptographic hash of the object using the extremely fast xxhash hashing algorithm. (PR #4020)

  4. @rcomer implemented a __str__ method for metadata classes, so printing these objects skips metadata elements that are set to None or an empty string or dictionary. (PR #4040)

  5. @Badboy-16 implemented a CubeList.copy() method to return a CubeList object instead of a list. (PR #4094)

  6. @pp-mo and @trexfeathers reformatted iris.cube.Cube.summary(), (which is used for print(Cube)); putting cell_methods before attributes, and improving spacing throughout. (PR #4206)

  7. @schlunma added support for loading atmosphere sigma coordinates from netcdf-CF files. These now load as iris.aux_factory.AtmosphereSigmaFactory derived coordinates. (PR #4052)

🐛 Bugs Fixed

  1. @gcaria fixed Cell comparison with 0-dimensional arrays and 1-dimensional arrays with len=1. (PR #4083)

  2. @gcaria fixed cell_measure_dims() to also accept the string name of a CellMeasure. (PR #3931)

  3. @gcaria fixed ancillary_variable_dims() to also accept the string name of a AncillaryVariable. (PR #3931)

  4. @rcomer modified contourf() to skip the special handling for antialiasing when data values are too low for it to have an effect. This caused unexpected artifacts in some edge cases, as shown at Issue #4086. (PR #4150)

  5. @MHBalsmeier modified contourf() to generalize PR #4150 for the cases where NaN values occur in the plot array (PR #4263)

  6. @trexfeathers fixed the “anomaly_log_colouring” gallery example to be compatible with the latest Matplotlib usage (PR #4115)

🚀 Performance Enhancements

  1. @bjlittle added support for automated import linting with isort, which also includes significant speed-ups for Iris imports. (PR #4174)

  2. @bjlittle Optimised the creation of dynamic metadata manager classes within the metadata_manager_factory(), resulting in a significant speed-up in the creation of Iris AncillaryVariable, AuxCoord, CellMeasure, and Cube instances. (PR #4227)

  3. @pp-mo and @lbdreyer optimised loading netcdf files, resulting in a speed up when loading with a single NameConstraint().

    For example, cube = iris.load('x.nc', NameConstraint('air_temperature')).

    Note that this optimisation only applies when matching on standard name, long name or NetCDF variable name, not when matching on STASH. (PR #4176)

💣 Incompatible Changes

  1. The adoption of ‘isort’ has significantly reduced the import time of Iris packages.

    However, this may break existing code which, for convenience, relies on some subpackages being imported implicitly (as some, but not all, previously were).

    For example: import iris; print(iris.cube.Cube).

    This style is essentially unsafe, and in this case no longer works. It must be modified to explicitly import all subpackages,

    i.e. import iris.cube; print(iris.cube.Cube).

🔗 Dependencies

  1. @bjlittle dropped both black and flake8 package dependencies from our conda YAML and setup.cfg PyPI requirements. (PR #4181)

  2. @pp-mo removed dependency on PyKE. (PR #4198)

📚 Documentation

  1. @rcomer updated the “Seasonal ensemble model plots” and “Global average annual temperature maps” Gallery examples. (PR #3933 and PR #3934)

  2. @MHBalsmeier described non-conda installation on Debian-based distros. (PR #3958)

  3. @bjlittle clarified in the doc-string that Coord is now an abstract base class since Iris 3.0.0, and it is not possible to create an instance of it. (PR #3971)

  4. @bjlittle added automated Iris version discovery for the latest.rst in the whatsnew documentation. (PR #3981)

  5. @tkknight stated the Python version used to build the documentation on Installing Iris and to the footer of all pages. Also added the copyright years to the footer. (PR #3989)

  6. @bjlittle updated the intersphinx_mapping and fixed documentation to use stable URLs for matplotlib. (PR #4003)

  7. @bjlittle added the PyPI badge to the README.md. (PR #4004)

  8. @tkknight added a banner at the top of every page of the unreleased development documentation if being viewed on Read the Docs. (PR #3999)

  9. @bjlittle added post-release instructions on how to Update PyPI with scitools-iris. (PR #4038)

  10. @bjlittle added the pre-commit.ci badge to the README.md. See pre-commit CI for further details. (PR #4061)

  11. @rcomer tweaked docstring layouts in the iris.plot module, so they render better in the published documentation. See Issue #4085. (PR #4100)

  12. @tkknight documented the --force command line option when creating a conda development environment. See Installing from Source with Conda (Developers). (PR #4240)

  13. @MHBalsmeier updated and simplified non-conda installation on Debian-based distros. (PR #4260)

  14. @bjlittle updated the intersphinx_mapping and fixed documentation to use stable URLs for matplotlib. (PR #4003)

💼 Internal

  1. @rcomer removed an old unused test file. (PR #3913)

  2. @tkknight moved the docs/iris directory to be in the parent directory docs. (PR #3975)

  3. @jamesp updated a test for numpy 1.20.0. (PR #3977)

  4. @bjlittle and @jamesp extended the cirrus-ci testing and nox testing automation to support Python 3.8. (PR #3976)

  5. @bjlittle rationalised the noxfile.py, and added the ability for each nox session to list its conda environment packages and environment info. (PR #3990)

  6. @bjlittle enabled cirrus-ci compute credits for non-draft pull-requests from collaborators targeting the Iris main branch. (PR #4007)

  7. @akuhnregnier replaced deprecated numpy 1.20 aliases for builtin types. (PR #3997)

  8. @bjlittle added conditional task execution to .cirrus.yml to allow developers to easily disable cirrus-ci tasks. See Skipping Cirrus-CI Tasks. (PR #4019)

  9. @bjlittle and @jamesp addressed a regression in behaviour when using conda 4.10.0 within cirrus-ci. (PR #4084)

  10. @bjlittle updated the perceptual imagehash graphical test support for matplotlib 3.4.1. (PR #4087)

  11. @jamesp switched cirrus-ci testing and nox testing to use conda-lock files for static test environments. (PR #4108)

  12. @bjlittle updated the bug-report and feature-request GitHub issue templates to remove an external URL reference that caused un-posted user issue content to be lost in the browser when followed. (PR #4147)

  13. @bjlittle dropped Python 3.6 support, and automated the discovery of supported Python versions tested by cirrus-ci for documentation. (PR #4163)

  14. @bjlittle refactored setup.py into setup.cfg. (PR #4168)

  15. @bjlittle consolidated the .flake8 configuration into setup.cfg. (PR #4200)

  16. @bjlittle renamed iris/master branch to iris/main and migrated references of master to main within codebase. (PR #4202)

  17. @bjlittle added the blacken-docs pre-commit hook to automate black linting of documentation code blocks. (PR #4205)

  18. @bjlittle consolidated nox black, flake8 and isort sessions into one lint session using pre-commit. (PR #4181)

  19. @bjlittle streamlined the cirrus-ci testing by removing the minimal tests, which are a subset of the full tests. (PR #4218)

  20. @bjlittle consolidated the cirrus-ci documentation doctest and gallery tasks into a single task and associated nox session. (PR #4219)

  21. @jamesp and @trexfeathers implemented a benchmarking CI check using asv. (PR #4253)

  22. @pp-mo and @stephenworsley refactored almost all of iris.cube.Cube.summary() into the new private module: iris._representation; rewritten with a more modular approach, resulting in more readable and extensible code. (PR #3987) (PR #4206)

  23. @pp-mo reworked the netcdf loading code, replacing Pyke rules with a pure Python implementation. (PR #4198)

  24. @lbdreyer updated the CF standard name table to the latest version: v77. (PR #4282)

  25. @jamesp updated a test to the latest numpy version (PR #3977)

  26. @bjlittle enabled cirrus-ci compute credits for non-draft pull-requests from collaborators targeting the Iris master branch. (PR #4007)

  27. @bjlittle added conditional task execution to .cirrus.yml to allow developers to easily disable cirrus-ci tasks. See Skipping Cirrus-CI Tasks. (PR #4019)