Open cgsandford opened 2 years ago
Hi @cgsandford, can you get what you want using
tcoord = cube.coord("time")
time_points = tcoord.units.num2pydate(tcoord.points)
?
Or this might work
import iris.plot as iplt
iplt.scatter(cube.coord("time"), cube[4])
Hi @rcomer , yes the first one works. It's just that mostly I'm doing analysis rather than plotting, so I forget about this, and every time cell.point
doesn't work I spend an hour or so digging for this forgotten error on Google / Yammer / Teams.
It's a feature request because lots of things work smoothly in iris, and this doesn't, and I couldn't see a good reason why it shouldn't. If it's problematic to change, an alternative might be to document this behaviour more clearly in the iris docs (which I also looked at and couldn't see any timeseries examples or clear reason why this wouldn't work).
@cgsandford sorry to hear you're experiencing problems. You're right that Iris' use of cftime datetimes isn't documented, but then again this isn't something that's expected to cause problems in user scripts.
As noted, using Iris' own plotting functions sorts out Matplotlib (because Iris uses nc-time-axis). What other datetime incompatibilities are you experiencing, beyond Matplotlib?
Or perhaps I've misunderstood:
I'm doing analysis rather than plotting
And you mean that your problems are specifically with plotting, but this is particularly difficult due to unfamiliarity with plotting?
As noted, using Iris' own plotting functions sorts out Matplotlib (because Iris uses nc-time-axis).
Note that Iris will convert to datetime.datetime
s for plotting if it finds the "gregorian" calendar, otherwise it uses nc-time-axis
as you say:
https://github.com/SciTools/iris/blob/4c43fc6e8a692aa637e1becf6415cd4f4f7d6475/lib/iris/plot.py#L590-L594
Or perhaps I've misunderstood:
I'm doing analysis rather than plotting
And you mean that your problems are specifically with plotting, but this is particularly difficult due to unfamiliarity with plotting?
Yes, my analysis is fine, it's just plotting I encounter issues with.
Thanks for clarifying, @cgsandford.
As noted, Iris' default use of cftime datetimes isn't expected to cause issues at the user level, hence this not being documented. If you use Iris' plotting modules (recommended here) these specialised datetimes are handled automatically. On this gallery page you can see that no specific lines are required for the time coordinates to be automatically formatted correctly on the x-axis.
With this information in mind, is there still a need for you to use the cells()
method and/or to work exclusively with Python datetimes in your workflow?
Looking at the docstrings for the coordinate cell and cells methods, they don’t actually mention anything about the conversion to datetimes. It’s not obvious that a cell point should be of different type to its respective coordinate point - in fact this was a change at Iris v2. So it seems sensible to me to at least update those docstrings to state we get cftime.datetime
s for the points and bounds.
However I wonder if the root of @cgsandford’s problem is that the Sphinx search is not very clever and only finds exact word matches. So you get very different results if you search timeseries vs time series. One workaround is to use an external search engine. For plotting examples I tend to go straight to the gallery and browse for something that look vaguely similar to what I want to do. That section of the User Guide that @trexfeathers linked might benefit from a link to the gallery.
@bsherratt has provided a use case when a cftime datetime is definitely NOT appropriate: when working with time-zones (which cftime can't represent). In such cases the preferred method is to manually construct the datetime objects starting with the raw numbers from Coord.points
.
Noting down yet another instance where this has caused me issues - this time in designing unit tests. Thankfully this issue now comes up as an early hit in a Google search to obtain the workaround.
And again ... you'd think I'd have memorised this by now but nope!
Hey @cgsandford.
Would you fancy bringing this to the UK Met Office AVD Surgery so we can talk in more detail?
@cgsandford sorry to hear you're experiencing problems. You're right that Iris' use of cftime datetimes isn't documented, but then again this isn't something that's expected to cause problems in user scripts.
As noted, using Iris' own plotting functions sorts out Matplotlib (because Iris uses nc-time-axis). What other datetime incompatibilities are you experiencing, beyond Matplotlib?
Hey @trexfeathers / all - just ran into this myself in a user script (mine!) - not 1st time, but 1st time I've dug enough to find this. Mentioning to add a space weather use-case. Happy to discuss further if useful!
My specific use-case/context: using iris to load in a netCDF file with auroral data, then plotting with cartopy.
Issues arose as I updated code:
fill_dark_side(ax, time, ...)
in <v0.17 cartopy gallery example (underlying sun_pos(dt)
seems to cope with a cftime)More details/actual code in commit message and linked code in a178520 (MO-only repo, commit should be visible just above this comment to MO people with access to MO GH org, sorry anyone else). Pseudo-code below.
As per comment in my commit, I guess this could be classed as a cartopy issue - e.g. "Extend Nightshade to handle cftimes".
But IMO @rcomer is bang on the money re root cause here being docs and discoverability of all this.
BTW, just in case I've excluded this prematurely as an option here, just to say that when I was 1st debugging this, I was hunting for a .to_datetime()
method on the cftime object (dt below), so that I could simply change my Nightshade call in pseudocode ^^^, leaving iris manipulations out of it, something like
--- ax.add_feature(Nightshade(date=dt, color="black", alpha=0.75))
+++ ax.add_feature(Nightshade(date=dt.to_datetime(), color="black", alpha=0.75))
This doesn't seem to be an option: there's no public to_datetime
method on the cftime object. However it does have a really tempting private _to_real_datetime
method, which quacks right - see below.
The only reason I've not used this is that leading "I'm private - don't use me!" underscore.
So far I've assumed not worth raising an issue in cftime seeking to get a public method counterpart/interface to _to_real_datetime
(or checked previously-raised cftime issues) - I've assumed that there will be good cftime design reasons for this being private.
I mention here however only in case you think my assumptions wrong, as this was my 1st thought on how to address this - and doesn't put so much onus on iris (though IMO extension of iris docs here still useful)!
@edmundhenley-mo @SciTools/peloton thinks this would be best discussed in person, perhaps at the next aforementioned surgery, or alternatively a dedicated meeting?
Eep, sorry for radio silence @ESadek-MO - just noticed I completely missed your reply at time. Yes, happy to discuss in person - will follow up separately!
✨ Feature Request
Recently iris time.cell.point calls return cftime instances rather than python datetime instances. This is due to the underpinning change in behaviour of the
cftime.num2date
function on which the cell functionality relies (the relevant code is in iris._coords.py). It would be easier for plotting purposes if this were changed to return a python datetime by default (eg usingcftime.num2pydate
), or given the option of returning one of these two datatypes.Motivation
I'm always frustrated when I try to make a timeseries plot, since:
raises a matplotlib TypeError, even though matplotlib is capable of handling python datetimes.
Additional context
None really. It's in the iris coords file and looks straightforward to fix, just a question of whether it has undesirable impacts.