pythonnetcdfcubepython-iris

How to convert auxiliary coordinates to dimension coordinates in a cube in iris?


I am pretty new to using NetCDF Jules output files. I am trying to write a routine to create multiple plots visualising the output from my simulations.

After reading in the cubes I have the following format:

filename = '/home/users/---------.nc'
cubelist = iris.load(filename)

cons = iris.Constraint(cube_func=lambda x: x.var_name == 'gpp_gb')
cube = cubelist.extract_cube(cons)

print (cube)
type(cube)
print (cube.shape)
print (cube.ndim)

first_timestep = cube[0,...]
print (first_timestep)

output:

Gridbox gross primary productivity / (kg m-2 s-1) (time: 12; -- : 1; -- : 7247)
    Dimension coordinates:
        time                                           x        -       -
    Auxiliary coordinates:
        latitude                                       -        x       x
        longitude                                      -        x       x
    Cell methods:
        mean                                      time
(12, 1, 7247)
3
Gridbox gross primary productivity / (kg m-2 s-1) (-- : 1; -- : 7247)
    Auxiliary coordinates:
        latitude                                      x       x
        longitude                                     x       x
    Scalar coordinates:
        time                                      2009-02-01 00:00:00, bound=(2009-01-01 00:00:00, 2009-02-01 00:00:00)
    Cell methods:
        mean                                      time

However when i try to map the data with:

qplt.contourf(first_timestep, 50)

I get the following error message:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_2386/1836137079.py in <module>
     16 
     17 
---> 18 qplt.contourf(first_timestep, 50)

/opt/jaspy/lib/python3.8/site-packages/iris/quickplot.py in contourf(cube, *args, **kwargs)
    206     coords = kwargs.get("coords")
    207     axes = kwargs.get("axes")
--> 208     result = iplt.contourf(cube, *args, **kwargs)
    209     _label_with_points(cube, result, coords=coords, axes=axes)
    210     return result

/opt/jaspy/lib/python3.8/site-packages/iris/plot.py in contourf(cube, *args, **kwargs)
   1057     coords = kwargs.get("coords")
   1058     kwargs.setdefault("antialiased", True)
-> 1059     result = _draw_2d_from_points("contourf", None, cube, *args, **kwargs)
   1060 
   1061     # Matplotlib produces visible seams between anti-aliased polygons.

/opt/jaspy/lib/python3.8/site-packages/iris/plot.py in _draw_2d_from_points(draw_method_name, arg_func, cube, *args, **kwargs)
    495 
    496     if _can_draw_map(plot_defn.coords):
--> 497         result = _map_common(
    498             draw_method_name,
    499             arg_func,

/opt/jaspy/lib/python3.8/site-packages/iris/plot.py in _map_common(draw_method_name, arg_func, mode, cube, plot_defn, *args, **kwargs)
   1007     axes = kwargs.pop("axes", None)
   1008     plotfn = getattr(axes if axes else plt, draw_method_name)
-> 1009     return plotfn(*new_args, **kwargs)
   1010 
   1011 

/opt/jaspy/lib/python3.8/site-packages/matplotlib/pyplot.py in contourf(data, *args, **kwargs)
   2743 @_copy_docstring_and_deprecators(Axes.contourf)
   2744 def contourf(*args, data=None, **kwargs):
-> 2745     __ret = gca().contourf(
   2746         *args, **({"data": data} if data is not None else {}),
   2747         **kwargs)

/opt/jaspy/lib/python3.8/site-packages/cartopy/mpl/geoaxes.py in wrapper(self, *args, **kwargs)
    308 
    309         kwargs['transform'] = transform
--> 310         return func(self, *args, **kwargs)
    311     return wrapper
    312 

/opt/jaspy/lib/python3.8/site-packages/cartopy/mpl/geoaxes.py in contourf(self, *args, **kwargs)
   1506                         sub_trans.force_path_ccw = True
   1507 
-> 1508         result = matplotlib.axes.Axes.contourf(self, *args, **kwargs)
   1509 
   1510         # We need to compute the dataLim correctly for contours.

/opt/jaspy/lib/python3.8/site-packages/matplotlib/__init__.py in inner(ax, data, *args, **kwargs)
   1359     def inner(ax, *args, data=None, **kwargs):
   1360         if data is None:
-> 1361             return func(ax, *map(sanitize_sequence, args), **kwargs)
   1362 
   1363         bound = new_sig.bind(ax, *args, **kwargs)

/opt/jaspy/lib/python3.8/site-packages/matplotlib/axes/_axes.py in contourf(self, *args, **kwargs)
   6432     def contourf(self, *args, **kwargs):
   6433         kwargs['filled'] = True
-> 6434         contours = mcontour.QuadContourSet(self, *args, **kwargs)
   6435         self._request_autoscale_view()
   6436         return contours

/opt/jaspy/lib/python3.8/site-packages/matplotlib/contour.py in __init__(self, ax, levels, filled, linewidths, linestyles, hatches, alpha, origin, extent, cmap, colors, norm, vmin, vmax, extend, antialiased, nchunk, locator, transform, *args, **kwargs)
    775         self._transform = transform
    776 
--> 777         kwargs = self._process_args(*args, **kwargs)
    778         self._process_levels()
    779 

/opt/jaspy/lib/python3.8/site-packages/matplotlib/contour.py in _process_args(self, corner_mask, *args, **kwargs)
   1364             self._corner_mask = corner_mask
   1365 
-> 1366             x, y, z = self._contour_args(args, kwargs)
   1367 
   1368             _mask = ma.getmask(z)

/opt/jaspy/lib/python3.8/site-packages/matplotlib/contour.py in _contour_args(self, args, kwargs)
   1422             args = args[1:]
   1423         elif Nargs <= 4:
-> 1424             x, y, z = self._check_xyz(args[:3], kwargs)
   1425             args = args[3:]
   1426         else:

/opt/jaspy/lib/python3.8/site-packages/matplotlib/contour.py in _check_xyz(self, args, kwargs)
   1452             raise TypeError(f"Input z must be 2D, not {z.ndim}D")
   1453         if z.shape[0] < 2 or z.shape[1] < 2:
-> 1454             raise TypeError(f"Input z must be at least a (2, 2) shaped array, "
   1455                             f"but has shape {z.shape}")
   1456         Ny, Nx = z.shape

TypeError: Input z must be at least a (2, 2) shaped array, but has shape (1, 7247)

I think it could be because my coordinate data is not in a format the iris package can understand as it is in the auxiliary fields when i print the cube. I think the code should work if I could put the latitude and longitude data into the dimension coordinates. Any help or ideas would be much appreciated.

Thank you for considering the problem.


Solution

  • some functions to which helped my specific problem.

    https://code.metoffice.gov.uk/trac/utils/browser/smstress_jpeg/trunk/jules.py#L629