What’s new in Iris 1.0

Release:1.0.0
Date:15 Oct, 2012

This document explains the new/changed features of Iris in version 1.0. (View all changes.)

With the release of Iris 1.0, we have broadly completed the transition to the CF data model, and established a stable foundation for future work. Following this release we plan to deliver significant performance improvements and additional features.

The role of 1.x

The 1.x series of releases is intended to provide a relatively stable, backwards-compatible platform based on the CF-netCDF data model, upon which long-lived services can be built.

Iris 1.0 targets the data model implicit in CF-netCDF 1.5. This will be extended to cover the new features of CF-netCDF 1.6 (e.g. discrete sampling geometries) and any subsequent versions which maintain backwards compatibility. Similarly, as the efforts of the CF community to formalise their data model reach maturity, they will be included in Iris where significant backwards-compatibility can be maintained.

Iris 1.0 features

A summary of the main features added with version 1.0:

  • Hybrid-pressure vertical coordinates, and the ability to load from GRIB.
  • Initial support for CF-style coordinate systems.
  • Use of Cartopy for mapping in matplotlib.
  • Load data from NIMROD files.
  • Availability of Cynthia Brewer colour palettes.
  • Add a citation to a plot.
  • Ensures netCDF files are properly closed.
  • The ability to bypass merging when loading data.
  • Save netCDF files with an unlimited dimension.
  • A more explicit set of load functions, which also allow the automatic cube merging to be bypassed as a last resort.
  • The ability to project a cube with a lat-lon or rotated lat-lon coordinate system into a range of map projections e.g. Polar Stereographic.

Incompatible changes

Deprecations

  • The methods iris.coords.Coord.cos() and iris.coords.Coord.sin() have been deprecated.
  • The iris.load_strict() function has been deprecated. Code should now use the iris.load_cube() and iris.load_cubes() functions instead.

CF-netCDF coordinate systems

The coordinate systems in Iris are now defined by the CF-netCDF grid mappings. As of Iris 1.0 a subset of the CF-netCDF coordinate systems are supported, but this will be expanded in subsequent versions. Adding this code is a relatively simple, incremental process - it would make a good task to tackle for users interested in getting involved in contributing to the project.

The coordinate systems available in Iris 1.0 and their corresponding Iris classes are:

CF name Iris class
Latitude-longitude GeogCS
Rotated pole RotatedGeogCS
Transverse Mercator TransverseMercator

For convenience, Iris also includes the OSGB class which provides a simple way to create the transverse Mercator coordinate system used by the British Ordnance Survey.

Using Cartopy for mapping in matplotlib

The underlying map drawing package has now been updated to use Cartopy. Cartopy provides a highly flexible set of mapping tools, with a consistent, intuitive interface. As yet it doesn’t have feature-parity with basemap, but its goal is to make maps “just work”, making it the perfect complement to Iris.

The iris.plot.map_setup function has now been replaced with a cleaner interface:

  • To draw a cube on its native map project, one can simply draw the cube directly:

    import iris.plot as iplt
    import matplotlib.pyplot as plt
    
    iplt.contourf(cube)
    plt.gca().coastlines()
    plt.show()
    
  • To draw a cube on the native map and extents of another, one can use the iris.plot.default_projection() and iris.plot.default_projection_extent() functions:

    import iris.plot as iplt
    import matplotlib.pyplot as plt
    
    cube1_projection = iplt.default_projection(cube1)
    cube1_extent = iplt.default_projection_extent(cube1)
    
    ax = plt.axes(projection=cube1_projection)
    ax.set_extent(cube1_extent, cube1_projection)
    iplt.contourf(cube2)
    ax.coastlines()
    plt.show()
    

Note

The iris.plot.gcm function to get the current map is now redundant; instead the current map is the current matplotlib axes, and matplotlib.pyplot.gca() should be used instead.

For more examples of what can be done with Cartopy, see the Iris gallery and Cartopy’s documentation.

Hybrid-pressure

With the introduction of the HybridPressureFactory class, it is now possible to represent data expressed on a hybrid-pressure vertical coordinate, as defined by the second variant in Appendix D. A hybrid-pressure factory is created with references to the coordinates which provide the components of the hybrid coordinate (“ap” and “b”) and the surface pressure. In return, it provides a virtual “pressure” coordinate whose values are derived from the given components.

This facility is utilised by the GRIB2 loader to automatically provide the derived “pressure” coordinate for certain data [1] from the ECMWF.

[1]Where the level type is either 105 or 119, and where the surface pressure has an ECMWF paramId of 152.

NetCDF

When saving a Cube to a netCDF file, Iris will now define the outermost dimension as an unlimited/record dimension. In combination with the iris.cube.Cube.transpose() method, this allows any dimension to take the role of the unlimited/record dimension.

For example, a Cube with the structure:

<iris 'Cube' of air_potential_temperature (time: 6; model_level_number: 70; grid_latitude: 100; grid_longitude: 100)>

would result in a netCDF file whose CDL definition would include:

dimensions:
        time = UNLIMITED ; // (6 currently)
        model_level_number = 70 ;
        grid_latitude = 100 ;
        grid_longitude = 100 ;

Also, Iris will now ensure that netCDF files are properly closed when they are no longer in use. Previously this could cause problems when dealing with large numbers of netCDF files, or in long running processes.

Brewer colour palettes

Iris includes a selection of carefully designed colour palettes produced by Cynthia Brewer. The iris.palette module registers the Brewer colour palettes with matplotlib, so they are explicitly selectable via the matplotlib.pyplot.set_cmap() function. For example:

import iris.palette
import matplotlib.pyplot as plt
import numpy as np
plt.contourf(np.random.randn(10, 10))
plt.set_cmap('brewer_RdBu_11')
plt.show()

Citations

Citations can easily be added to a plot using the iris.plot.citation() function. The recommended text for the Cynthia Brewer citation is provided by iris.plot.BREWER_CITE.

To include a reference in a journal article or report please refer to section 5 in the citation guidance provided by Cynthia Brewer.

Metadata attributes

Iris now stores “source” and “history” metadata in Cube attributes. For example:

>>> print(iris.tests.stock.global_pp())
air_temperature                     (latitude: 73; longitude: 96)
     ...
     Attributes:
          ...
          source: Data from Met Office Unified Model
     ...

Where previously it would have appeared as:

air_temperature                     (latitude: 73; longitude: 96)
     ...
     Scalar coordinates:
          ...
          source: Data from Met Office Unified Model
     ...

Note

This change breaks backwards compatibility with Iris 0.9. But if it is desirable to have the “source” metadata expressed as a coordinate then it can be done with the following pattern:

src = cube.attributes.pop('source')
src_coord = iris.coords.AuxCoord(src, long_name='source')
cube.add_aux_coord(src_coord)

New loading functions

The main functions for loading cubes are now:

These provide convenient cube loading suitable for both interactive (iris.load()) and scripted (iris.load_cube(), iris.load_cubes()) usage.

In addition, iris.load_raw() has been provided as a last resort for situations where the automatic cube merging is not appropriate. However, if you find you need to use this function we would encourage you to contact the Iris developers so we can see if a fix can be made to the cube merge algorithm.

The iris.load_strict() function has been deprecated. Code should now use the iris.load_cube() and iris.load_cubes() functions instead.

Cube projection

Iris now has the ability to project a cube into a number of map projections. This functionality is provided by iris.analysis.cartography.project(). For example:

import iris
import cartopy.crs as ccrs
import matplotlib.pyplot as plt

# Load data
cube = iris.load_cube(iris.sample_data_path('air_temp.pp'))

# Transform cube to target projection
target_proj = ccrs.RotatedPole(pole_longitude=177.5,
                               pole_latitude=37.5)
new_cube, extent = iris.analysis.cartography.project(cube, target_proj)

# Plot
plt.axes(projection=target_proj)
plt.pcolor(new_cube.coord('projection_x_coordinate').points,
           new_cube.coord('projection_y_coordinate').points,
           new_cube.data)
plt.gca().coastlines()
plt.show()

This function is intended to be used in cases where the cube’s coordinates prevent one from directly visualising the data, e.g. when the longitude and latitude are two dimensional and do not make up a regular grid. The function uses a nearest neighbour approach rather than any form of linear/non-linear interpolation to determine the data value of each cell in the resulting cube. Consequently it may have an adverse effect on the statistics of the data e.g. the mean and standard deviation will not be preserved. This function currently assumes global data and will if necessary extrapolate beyond the geographical extent of the source cube.

Other changes

  • Cube summaries are now more readable when the scalar coordinates contain bounds.