-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
enable internal plotting with cftime datetime #2665
Conversation
I have been along the lines of a short example. This works for timeseries data.
For pcolormesh plots this still fails.
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
in
3 data2 = np.random.rand(len(time), 4)
4 da2 = xr.DataArray(data2, coords=[('time', time), ('other', range(4))])
----> 5 da2.plot()
~/Work/CODE/PYTHON/xarray/xarray/plot/plot.py in call(self, **kwargs) ~/Work/CODE/PYTHON/xarray/xarray/plot/plot.py in plot(darray, row, col, col_wrap, ax, hue, rtol, subplot_kws, **kwargs) ~/Work/CODE/PYTHON/xarray/xarray/plot/plot.py in newplotfunc(darray, x, y, figsize, size, aspect, ax, row, col, col_wrap, xincrease, yincrease, add_colorbar, add_labels, vmin, vmax, cmap, center, robust, extend, levels, infer_intervals, colors, subplot_kws, cbar_ax, cbar_kwargs, xscale, yscale, xticks, yticks, xlim, ylim, norm, **kwargs) ~/Work/CODE/PYTHON/xarray/xarray/plot/plot.py in pcolormesh(x, y, z, ax, infer_intervals, **kwargs) ~/Work/CODE/PYTHON/xarray/xarray/plot/plot.py in _infer_interval_breaks(coord, axis, check_monotonic) ~/Work/CODE/PYTHON/xarray/xarray/plot/plot.py in _is_monotonic(coord, axis) TypeError: '>=' not supported between instances of 'CalendarDateTime' and 'CalendarDateTime' Perhaps @spencerkclark has an idea how to deal with differencing cftime.datetime objects? |
xarray/plot/plot.py
Outdated
'arrays indexed by cftime.datetime objects requires the ' | ||
'optional `nc-time-axis` package ' | ||
'(https://github.com/SciTools/nc-time-axis).' | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The old version of contains_cftime_datetimes
was never triggered for my example. Not sure if this was a bug or if I am missing something here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thanks, checking the dimensions would definitely be an improvement 👍. We probably still want to check that the data does not contain cftime.datetime
objects too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about this a little more, technically, I think you could still pass a time dimension filled with cftime dates to the row
or col
argument of plot
, and things would still work without nc-time-axis (because you would not be plotting cftime dates in that case; they would just be in the plot titles).
For that reason, it might be slightly cleaner to move this check to _ensure_plottable
, because that only gets called on things that xarray tries to plot. Something like:
def _ensure_plottable(*args):
"""
Raise exception if there is anything in args that can't be plotted on an
axis by matplotlib.
"""
numpy_types = [np.floating, np.integer, np.timedelta64, np.datetime64]
other_types = [datetime]
try:
import cftime
cftime_datetime = [cftime.datetime]
except ImportError:
cftime_datetime = []
other_types = other_types + cftime_datetime
for x in args:
if not (_valid_numpy_subdtype(np.array(x), numpy_types)
or _valid_other_type(np.array(x), other_types)):
raise TypeError('Plotting requires coordinates to be numeric '
'or dates of type np.datetime64, '
'datetime.datetime, or cftime.datetime or '
'pd.Interval.')
if (_valid_other_type(np.array(x), cftime_datetime)
and not nc_axis_available):
raise ImportError('Plotting of arrays of cftime.datetime '
'objects or arrays indexed by cftime.datetime '
'objects requires the optional `nc-time-axis` '
'package.')
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am super sorry @spencerkclark. I misread your example and then had to submit a paper. I am working on it now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All good @jbusecke -- I appreciate your help with this.
One of the more general questions I had was if we should expose the conversion using
Just an idea... |
Note I have a PR open in nc-time-axis, which enables plotting of That said, I'm not sure if/when it will be merged, so it probably makes sense to go forward with this approach for now. |
@spencerkclark - I pinged the met-office folks about your PR. Hopefully that get's merged. |
Oh shoot, I now remember seeing this. |
I appreciate it @jhamman; we'll see what happens there.
Or this PR could be amended :). We'd still need to make some changes to xarray along the lines of what you've started on here for the optional import of nc-time-axis, addition of
If you're in pinch I think things would work here if you passed da2.plot(infer_intervals=False) though in general |
xarray/plot/plot.py
Outdated
@@ -102,6 +111,26 @@ def _line_facetgrid(darray, row=None, col=None, hue=None, | |||
return g.map_dataarray_line(hue=hue, **kwargs) | |||
|
|||
|
|||
def _convert_cftime_data(values): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would move these to utils.py
because they might come in handy for a Dataset plotting API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you still think that this could be of use? Otherwise Ill go ahead and remove it.
Is there still interest in this PR? Or did the upstream changes move ahead? But obviously if things are going to be fixed upstream soon, I would devote time to other projects. |
Looks like upstream hasn't moved. Maybe @jhamman and @spencerkclark can re-ping for a review there? I am +0.5 on moving forward with an xarray workaround. It seems easy to remove once upstream makes all the required changes. |
I agree @dcherian; I just pinged the PR again, but if there is no activity there by this time next week, I think we should probably move forward here. |
Sounds good to me.
Best
Julius
…On Jan 23, 2019, 12:56 PM -0500, Spencer Clark ***@***.***>, wrote:
I agree @dcherian; I just pinged the PR again, but if there is no activity there by this time next week, I think we should probably move forward here.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.
|
@jbusecke SciTools/nc-time-axis#42 has been merged, and a new release has been made (it's already available on conda-forge)! It would be great if you could update this PR to use this latest version of nc-time-axis -- you should no longer need to convert dates to Thanks again @lbdreyer for your help. |
Cool. Ill give it a shot right now. |
4c93272
to
bbe4da2
Compare
Hello @jbusecke! Thanks for updating the PR. Cheers ! There are no PEP8 issues in this Pull Request. 🍻 Comment last updated on February 07, 2019 at 13:16 Hours UTC |
Ok so the plotting works now with both timeseries and 2d data as follows
|
I have quickly looked into the testing and found an oddity that might be important if nc-time-axis is not installed. So in the definition of
to
Because if I understand correctly, the previous statement only checks the dtype of the actual data, not the dimensions. Is this appropriate or am I misunderstanding the syntax? In my example above it doesnt matter, because this only spits out an error message when nc-time-axis is not available. |
Great idea to simplify @spencerkclark. Thanks.
And the test suite passes locally. But I assume Ill have to add another test dataset with a cftime.datetime time-axis, which then gets dragged through all the plotting tests? Where would I have to put that in? Many thanks for all the help |
I think it would make sense to follow this example, but use xarray/xarray/tests/test_plot.py Lines 1797 to 1813 in 2e99c7d
Note you'll also need to add nc-time-axis to some CI environments so that things run in some Travis/AppVeyor builds, probably best in:
and add some decorators to skip the tests if the needed packages (cftime and nc-time-axis) are not installed. xarray/xarray/tests/__init__.py Line 65 in 2e99c7d
Maybe by leaving nc-time-axis out of the py36 test environment (which has cftime) you can use it to test the error message if nc-time-axis is not installed? |
2812ba1
to
0479829
Compare
Ok I think I have most of the things covered. All test pass for me locally. What should I add to the |
I think I have addressed all the above remarks (Many thanks for the thorough review and tips). Waiting for the CI again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more thing before I forget -- at the bottom of doc/time-series.rst
there is a note that says that built-in plotting with cftime datetime coordinate axes is not supported:
While much of the time series functionality that is possible for standard dates has been implemented for dates from non-standard calendars, there are still some remaining important features that have yet to be implemented, for example:
- Built-in plotting of data with cftime.datetime coordinate axes (GH2164).
Go ahead and delete the quoted portion above. I believe the rest of the note is worth leaving to describe to_datetimeindex()
in case folks are interested in it (xref: this StackOverflow question).
Co-Authored-By: jbusecke <[email protected]>
Co-Authored-By: jbusecke <[email protected]>
Co-Authored-By: jbusecke <[email protected]>
Seems like the travis builds all pass, wohoo. Please let me know if anything else is needed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @jbusecke -- I have a few more minor cleanup suggestions, but once those are addressed I think this should be ready to go.
xarray/tests/test_plot.py
Outdated
self.darray_2d.plot.contour() | ||
|
||
|
||
# @requires_nc_time_axis |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reminder to delete this commented-out code.
xarray/tests/test_plot.py
Outdated
|
||
def test_cfdatetime_line_plot(self): | ||
# test if line plot raises no Exception | ||
self.darray.plot.line() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I think you could use the 2D DataArray for the line plot test instead of creating a separate DataArray for the 1D case (i.e. just use isel
to select a single point along the 'x'
dimension before calling plot
).
Co-Authored-By: jbusecke <[email protected]>
Co-Authored-By: jbusecke <[email protected]>
Thanks. I updated the PR accordingly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another documentation note, sorry -- it occurred to me it would be helpful to add a reference to nc-time-axis under the "For plotting" heading in the "Optional dependencies" section of the installation page (doc/installing.rst
). Could you add that as well?
Create a DataArray with a time-axis that contains cftime.datetime | ||
objects. | ||
''' | ||
# case for 1d array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# case for 1d array |
Awesome. Just added the line. Let me know if you think it is appropriate. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @jbusecke, this looks good to me too!
Is there anything else that I need to do at this point? Sorry for the xarray noob question... |
thanks @jbusecke |
Thanks for this @jbusecke! Really excited to have this feature in Xarray now. |
* master: typo in whats_new (pydata#2763) Update computation.py to use Python 3 function signatures (pydata#2756) add h5netcdf+dask tests (pydata#2737) Fix name loss when masking (pydata#2749) fix datetime_to_numeric and Variable._to_numeric (pydata#2668) Fix mypy errors (pydata#2753) enable internal plotting with cftime datetime (pydata#2665) remove references to cyordereddict (pydata#2750) BUG: Pass kwargs to the FileManager for pynio engine (pydata#2380) (pydata#2732) reintroduce pynio/rasterio/iris to py36 test env (pydata#2738) Fix CRS being WKT instead of PROJ.4 (pydata#2715) Refactor (part of) dataset.py to use explicit indexes (pydata#2696)
This PR is meant to restore the internal plotting capabilities for objects with cftime.datetime dimensions.
Based mostly on the discussions in #2164
whats-new.rst
for all changes andapi.rst
for new API