Converting time in netCDF files

2,038 views
Skip to first unread message

Jamie Mitchell

unread,
Mar 14, 2014, 6:24:32 AM3/14/14
to scitoo...@googlegroups.com
Hello,

I want to convert the time in my netCDF files from the current days since 1990-01-01 to months of the year or just years.

Here is what I have:

'ALl times :/n', swh_1981.coord('time')
('ALl times :/n', AuxCoord(array([-3287.   , -3286.875, -3286.75 , ..., -2923.375, -2923.25 ,
       -2923.125]), standard_name=u'time', units=Unit('days since 1990-01-01T00:00:00Z', calendar='gregorian'), long_name=u'julian day (UT)', attributes={'conventions': 'relative julian days with decimal part (as parts of the day )'}))

Apologies if I am being ignorant here I am new to Python/IRIS etc!

Any help would be great.

Cheers,

Jamie

DeeKay

unread,
Mar 14, 2014, 11:48:50 AM3/14/14
to scitoo...@googlegroups.com
Hi Jamie, welcome to Python and Iris!

You can indeed do what you are asking about, but it is done through adding a new coordinate to your cube rather than by updating the existing one. This process is adding a categorised coordinate.

Take a look at this iPython notebook that demonstrates how to add a categorised coord (and the associated Iris coord categorisation documentation). Note that after [4] in the documentation the cube has gained an auxiliary coord called 'year'. This contains the year value for each point in the cube's time coord. You're not limited by only being able to categorise on year either - see the documentation I also linked to for a list of all built-in categorisations - and you can also define your own categorisation function as demonstrated by [5] and [6] of the notebook.

Note also that if you meant 'can I convert the units of my time coordinate', then yes you can, so long as you're only converting the step to one of `seconds`, `minutes`, `hours` or `days`:

new_unit = iris.unit.Unit('days since 1990-01-01 00:00:00', calendar='gregorian')  # define a new Iris unit instance whose timestep is days
swh_1981
.coord('time').convert_units(new_unit)

Converting the units suchlike requires that you keep the same calendar, as you cannot convert between calendars; what do you do with the five days' difference between 360-day and 365-day calendars, for example?!

Hope this helps!

DeeKay

unread,
Mar 14, 2014, 11:52:19 AM3/14/14
to scitoo...@googlegroups.com
So I didn't pay *quite* enough attention to the time coord units conversion example I gave above... clearly your time coordinate is already in days, so converting it to days won't actually achieve anything! But were you to choose one of the three other options you would convert the units of your cube's time coordinate.

Jamie Mitchell

unread,
Mar 17, 2014, 6:44:14 AM3/17/14
to scitoo...@googlegroups.com
Hi DeeKay,

Thanks for your prompt and useful reply!

Using coord_cat.add_year I have managed to add an auxiliary coordinate of 'year' to my cube.

How do I ensure that when I plot the cube that the 'year' coordinate is plotted rather than the 'time' coordinate which is automatically plotted.

Thanks again for your help.

Cheers,

Jamie

rsignell

unread,
Mar 17, 2014, 7:04:56 AM3/17/14
to scitoo...@googlegroups.com
Iris folks,

I didn't think that ISO style units on time:

days since 1990-01-01T00:00:00Z

were CF-compliant and that they would need to be written as

 days since 1990-01-01 00:00:00
instead.

Is that not true?

Thanks,
Rich

DeeKay

unread,
Mar 17, 2014, 8:24:46 AM3/17/14
to scitoo...@googlegroups.com
Hi Jamie,

To plot the 'year' coordinate instead of the 'time' coordinate you can use the coords keyword arg to Iris plot routines, as demonstrated by this Iris gallery example. Note that if you have extra dimensions on your cube beyond the two you're plotting you will have to take slices of the cube, as is also demonstrated in the example and select the appropriate slice from the iterator that is returned.

However if you are only plotting your data it may be that you won't actually need to use a categorised coord as I introduced above. The real benefit of categorised coordinates is being able to aggregate on the categorisation, as is demonstrated in the iPython notebook I linked in my earlier post. If you don't need to aggregate like this but just need to plot your time axis with year values on the ticks you can use matplotlib formatters to perform this function for you (note this only works well with line and contour plots due to a bug in matplotlib that should be fixed in v1.4). So, assuming that you're making a line or contour plot, you can use:

plt.gca().xaxis.axis_date()

assuming your x-axis is your time axis, though the equivalent should work for the y-axis if required. You can then add further formatting as required with a matplotlib dates formatter:

plt.gca().xaxis.set_major_formatter()

and pass a matplotlib.dates.DateFormatter object (see also the documentation) to set_major_formatter to specify the date format.

Andrew Dawson

unread,
Mar 17, 2014, 10:48:19 AM3/17/14
to scitoo...@googlegroups.com
FYI for 1D plotting you can do this:
 
import iris.plot as iplt
iplt
.plot(cube.coord('year'), cube)
 
i.e. the x-axis will be the coordinate named year and the y coordinate will be data values. For 2D plotting you should do as suggested previously.

marqh

unread,
Mar 17, 2014, 12:42:06 PM3/17/14
to scitoo...@googlegroups.com
Hello Rich

I think that Iris respects this on export to NetCDF but uses the iso style when printing output in Python.

This seems reasonable to me, CF only provides explicit details on these strings as part of the CF-NetCDF encoding, i don't think this needs to drive use in Python unless there is functional need or difference.

all the best
mark

Jamie Mitchell

unread,
Mar 21, 2014, 6:55:55 AM3/21/14
to scitoo...@googlegroups.com
Thank you DeeKay and Andrew that is exactly what I was looking for!

Much appreciated.

Jamie
Reply all
Reply to author
Forward
0 new messages