-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Code Sample, a copy-pastable example if possible
Consider a simple working example of converting an xarray dataset to holoviews for plotting:
ref_date = '1981-01-01'
ds = xr.DataArray([1, 2, 3], dims=['time'],
coords={'time': ('time', [1, 2, 3],
{'units': 'days since %s' % ref_date})}
).to_dataset(name='foo')
with xr.set_options(enable_cftimeindex=True):
ds = xr.decode_cf(ds)
print(ds)
hv_ds = hv.Dataset(ds)
hv_ds.to(hv.Curve)
This gives
<xarray.Dataset>
Dimensions: (time: 3)
Coordinates:
* time (time) datetime64[ns] 1981-01-02 1981-01-03 1981-01-04
Data variables:
foo (time) int64 ...
Problem description
Now change ref_date = '0181-01-01'
(or anything outside of the valid range for regular pandas datetime index). We get a beautiful new cftimeindex
<xarray.Dataset>
Dimensions: (time: 3)
Coordinates:
* time (time) object 0181-01-02 00:00:00 0181-01-03 00:00:00 ...
Data variables:
foo (time) int64 ...
but holoviews / bokeh doesn't like it
/opt/conda/lib/python3.6/site-packages/xarray/coding/times.py:132: SerializationWarning: Unable to decode time axis into full numpy.datetime64 objects, continuing using dummy cftime.datetime objects instead, reason: dates out of range
enable_cftimeindex)
/opt/conda/lib/python3.6/site-packages/xarray/coding/variables.py:66: SerializationWarning: Unable to decode time axis into full numpy.datetime64 objects, continuing using dummy cftime.datetime objects instead, reason: dates out of range
return self.func(self.array[key])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/opt/conda/lib/python3.6/site-packages/IPython/core/formatters.py in __call__(self, obj, include, exclude)
968
969 if method is not None:
--> 970 return method(include=include, exclude=exclude)
971 return None
972 else:
/opt/conda/lib/python3.6/site-packages/holoviews/core/dimension.py in _repr_mimebundle_(self, include, exclude)
1229 combined and returned.
1230 """
-> 1231 return Store.render(self)
1232
1233
/opt/conda/lib/python3.6/site-packages/holoviews/core/options.py in render(cls, obj)
1287 data, metadata = {}, {}
1288 for hook in hooks:
-> 1289 ret = hook(obj)
1290 if ret is None:
1291 continue
/opt/conda/lib/python3.6/site-packages/holoviews/ipython/display_hooks.py in pprint_display(obj)
278 if not ip.display_formatter.formatters['text/plain'].pprint:
279 return None
--> 280 return display(obj, raw_output=True)
281
282
/opt/conda/lib/python3.6/site-packages/holoviews/ipython/display_hooks.py in display(obj, raw_output, **kwargs)
248 elif isinstance(obj, (CompositeOverlay, ViewableElement)):
249 with option_state(obj):
--> 250 output = element_display(obj)
251 elif isinstance(obj, (Layout, NdLayout, AdjointLayout)):
252 with option_state(obj):
/opt/conda/lib/python3.6/site-packages/holoviews/ipython/display_hooks.py in wrapped(element)
140 try:
141 max_frames = OutputSettings.options['max_frames']
--> 142 mimebundle = fn(element, max_frames=max_frames)
143 if mimebundle is None:
144 return {}, {}
/opt/conda/lib/python3.6/site-packages/holoviews/ipython/display_hooks.py in element_display(element, max_frames)
186 return None
187
--> 188 return render(element)
189
190
/opt/conda/lib/python3.6/site-packages/holoviews/ipython/display_hooks.py in render(obj, **kwargs)
63 renderer = renderer.instance(fig='png')
64
---> 65 return renderer.components(obj, **kwargs)
66
67
/opt/conda/lib/python3.6/site-packages/holoviews/plotting/bokeh/renderer.py in components(self, obj, fmt, comm, **kwargs)
257 # Bokeh has to handle comms directly in <0.12.15
258 comm = False if bokeh_version < '0.12.15' else comm
--> 259 return super(BokehRenderer, self).components(obj,fmt, comm, **kwargs)
260
261
/opt/conda/lib/python3.6/site-packages/holoviews/plotting/renderer.py in components(self, obj, fmt, comm, **kwargs)
319 plot = obj
320 else:
--> 321 plot, fmt = self._validate(obj, fmt)
322
323 widget_id = None
/opt/conda/lib/python3.6/site-packages/holoviews/plotting/renderer.py in _validate(self, obj, fmt, **kwargs)
218 if isinstance(obj, tuple(self.widgets.values())):
219 return obj, 'html'
--> 220 plot = self.get_plot(obj, renderer=self, **kwargs)
221
222 fig_formats = self.mode_formats['fig'][self.mode]
/opt/conda/lib/python3.6/site-packages/holoviews/plotting/bokeh/renderer.py in get_plot(self_or_cls, obj, doc, renderer)
150 doc = Document() if self_or_cls.notebook_context else curdoc()
151 doc.theme = self_or_cls.theme
--> 152 plot = super(BokehRenderer, self_or_cls).get_plot(obj, renderer)
153 plot.document = doc
154 return plot
/opt/conda/lib/python3.6/site-packages/holoviews/plotting/renderer.py in get_plot(self_or_cls, obj, renderer)
205 init_key = tuple(v if d is None else d for v, d in
206 zip(plot.keys[0], defaults))
--> 207 plot.update(init_key)
208 else:
209 plot = obj
/opt/conda/lib/python3.6/site-packages/holoviews/plotting/plot.py in update(self, key)
511 def update(self, key):
512 if len(self) == 1 and ((key == 0) or (key == self.keys[0])) and not self.drawn:
--> 513 return self.initialize_plot()
514 item = self.__getitem__(key)
515 self.traverse(lambda x: setattr(x, '_updated', True))
/opt/conda/lib/python3.6/site-packages/holoviews/plotting/bokeh/element.py in initialize_plot(self, ranges, plot, plots, source)
729 if not self.overlaid:
730 self._update_plot(key, plot, style_element)
--> 731 self._update_ranges(style_element, ranges)
732
733 for cb in self.callbacks:
/opt/conda/lib/python3.6/site-packages/holoviews/plotting/bokeh/element.py in _update_ranges(self, element, ranges)
498 if not self.drawn or xupdate:
499 self._update_range(x_range, l, r, xfactors, self.invert_xaxis,
--> 500 self._shared['x'], self.logx, streaming)
501 if not self.drawn or yupdate:
502 self._update_range(y_range, b, t, yfactors, self.invert_yaxis,
/opt/conda/lib/python3.6/site-packages/holoviews/plotting/bokeh/element.py in _update_range(self, axis_range, low, high, factors, invert, shared, log, streaming)
525 updates = {}
526 if low is not None and (isinstance(low, util.datetime_types)
--> 527 or np.isfinite(low)):
528 updates['start'] = (axis_range.start, low)
529 if high is not None and (isinstance(high, util.datetime_types)
TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
Similar but slightly different errors arise for different holoviews types (e.g. hv.Image
) and contexts (using time as a holoviews kdim).
Expected Output
This should work.
I'm not sure if this is really an xarray problem. Maybe it needs a fix in holoviews (or bokeh). But I'm raising it here first since clearly we have introduced this new wrinkle in the stack. Cc'ing @philippjfr since he is the expert on all things holoviews.
Output of xr.show_versions()
xarray: 0.10.4
pandas: 0.23.0
numpy: 1.14.3
scipy: 1.1.0
netCDF4: 1.4.0
h5netcdf: None
h5py: None
Nio: None
zarr: 2.2.0
bottleneck: None
cyordereddict: None
dask: 0.17.5
distributed: 1.21.8
matplotlib: 2.2.2
cartopy: None
seaborn: None
setuptools: 39.0.1
pip: 10.0.1
conda: 4.3.34
pytest: 3.5.1
IPython: 6.3.1
sphinx: None