Moving here from gitter. Seems to be somewhat of a blind-spot in support for different datatypes in the various elements that support gridded datasets.
Namely:
hv.HeatMap
does not support a datetime-like key dimensionhv.QuadMesh
does not (seem to) support a categorical-like key dimension
This combination is unfortunate for instances like the Measles
app, where the current docs treat years as categories in a heatmap, but this prevents e.g. a Layout
from syncing curves that plot against a time-series to the elements of the grid above.
Imagine wanting to resample the measles curve to be weeks/months/10Y frequencies, etc, when the underlying dataset is raw occurrence timestamps of individual cases.
On the other hand, QuadMesh
does accept datetime-like key dimensions (as suggested by @philippjfr on Gitter), but it seems that a categorical/str-like key dimension throws an error. From the docs:
heatmap = hv.HeatMap((
['A', 'B', 'C'],
['a', 'b', 'c', 'd', 'e'],
np.random.rand(5, 3)
))
works fine, but heatmap.to(hv.QuadMesh)
throws the following opaque error:
---------------------------------------------------------------------------
UFuncTypeError Traceback (most recent call last)
~/miniconda3/envs/nestor-mod/lib/python3.7/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:
~/miniconda3/envs/nestor-mod/lib/python3.7/site-packages/holoviews/core/dimension.py in _repr_mimebundle_(self, include, exclude)
1292 combined and returned.
1293 """
-> 1294 return Store.render(self)
1295
1296
~/miniconda3/envs/nestor-mod/lib/python3.7/site-packages/holoviews/core/options.py in render(cls, obj)
1366 data, metadata = {}, {}
1367 for hook in hooks:
-> 1368 ret = hook(obj)
1369 if ret is None:
1370 continue
~/miniconda3/envs/nestor-mod/lib/python3.7/site-packages/holoviews/ipython/display_hooks.py in pprint_display(obj)
279 if not ip.display_formatter.formatters['text/plain'].pprint:
280 return None
--> 281 return display(obj, raw_output=True)
282
283
~/miniconda3/envs/nestor-mod/lib/python3.7/site-packages/holoviews/ipython/display_hooks.py in display(obj, raw_output, **kwargs)
249 elif isinstance(obj, (CompositeOverlay, ViewableElement)):
250 with option_state(obj):
--> 251 output = element_display(obj)
252 elif isinstance(obj, (Layout, NdLayout, AdjointLayout)):
253 with option_state(obj):
~/miniconda3/envs/nestor-mod/lib/python3.7/site-packages/holoviews/ipython/display_hooks.py in wrapped(element)
144 try:
145 max_frames = OutputSettings.options['max_frames']
--> 146 mimebundle = fn(element, max_frames=max_frames)
147 if mimebundle is None:
148 return {}, {}
~/miniconda3/envs/nestor-mod/lib/python3.7/site-packages/holoviews/ipython/display_hooks.py in element_display(element, max_frames)
190 return None
191
--> 192 return render(element)
193
194
~/miniconda3/envs/nestor-mod/lib/python3.7/site-packages/holoviews/ipython/display_hooks.py in render(obj, **kwargs)
66 renderer = renderer.instance(fig='png')
67
---> 68 return renderer.components(obj, **kwargs)
69
70
~/miniconda3/envs/nestor-mod/lib/python3.7/site-packages/holoviews/plotting/bokeh/renderer.py in components(self, obj, fmt, comm, **kwargs)
248 # Bokeh has to handle comms directly in <0.12.15
249 comm = False if bokeh_version < '0.12.15' else comm
--> 250 return super(BokehRenderer, self).components(obj,fmt, comm, **kwargs)
251
252
~/miniconda3/envs/nestor-mod/lib/python3.7/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 data, metadata = {}, {}
~/miniconda3/envs/nestor-mod/lib/python3.7/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]
~/miniconda3/envs/nestor-mod/lib/python3.7/site-packages/holoviews/plotting/bokeh/renderer.py in get_plot(self_or_cls, obj, doc, renderer, **kwargs)
133 curdoc().theme = self_or_cls.theme
134 doc.theme = self_or_cls.theme
--> 135 plot = super(BokehRenderer, self_or_cls).get_plot(obj, renderer, **kwargs)
136 plot.document = doc
137 return plot
~/miniconda3/envs/nestor-mod/lib/python3.7/site-packages/holoviews/plotting/renderer.py in get_plot(self_or_cls, obj, renderer, **kwargs)
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
~/miniconda3/envs/nestor-mod/lib/python3.7/site-packages/holoviews/plotting/plot.py in update(self, key)
612 def update(self, key):
613 if len(self) == 1 and ((key == 0) or (key == self.keys[0])) and not self.drawn:
--> 614 return self.initialize_plot()
615 item = self.__getitem__(key)
616 self.traverse(lambda x: setattr(x, '_updated', True))
~/miniconda3/envs/nestor-mod/lib/python3.7/site-packages/holoviews/plotting/bokeh/element.py in initialize_plot(self, ranges, plot, plots, source)
1278 self.handles['plot'] = plot
1279
-> 1280 self._init_glyphs(plot, element, ranges, source)
1281 if not self.overlaid:
1282 self._update_plot(key, plot, style_element)
~/miniconda3/envs/nestor-mod/lib/python3.7/site-packages/holoviews/plotting/bokeh/element.py in _init_glyphs(self, plot, element, ranges, source)
1225 else:
1226 style = self.style[self.cyclic_index]
-> 1227 data, mapping, style = self.get_data(element, ranges, style)
1228 current_id = element._plot_id
1229
~/miniconda3/envs/nestor-mod/lib/python3.7/site-packages/holoviews/plotting/bokeh/raster.py in get_data(self, element, ranges, style)
251 data[y] = np.array(yc)
252 else:
--> 253 xc, yc = (element.interface.coords(element, x, edges=True, ordered=True),
254 element.interface.coords(element, y, edges=True, ordered=True))
255
~/miniconda3/envs/nestor-mod/lib/python3.7/site-packages/holoviews/core/data/grid.py in coords(cls, dataset, dim, ordered, expanded, edges)
234 isedges = False
235 if edges and not isedges:
--> 236 data = cls._infer_interval_breaks(data)
237 elif not edges and isedges:
238 data = data[:-1] + np.diff(data)/2.
~/miniconda3/envs/nestor-mod/lib/python3.7/site-packages/holoviews/core/data/grid.py in _infer_interval_breaks(cls, coord, axis)
196 if len(coord) == 0:
197 return np.array([], dtype=coord.dtype)
--> 198 deltas = 0.5 * np.diff(coord, axis=axis)
199 first = np.take(coord, [0], axis=axis) - np.take(deltas, [0], axis=axis)
200 last = np.take(coord, [-1], axis=axis) + np.take(deltas, [-1], axis=axis)
<__array_function__ internals> in diff(*args, **kwargs)
~/miniconda3/envs/nestor-mod/lib/python3.7/site-packages/numpy/lib/function_base.py in diff(a, n, axis, prepend, append)
1271 op = not_equal if a.dtype == np.bool_ else subtract
1272 for _ in range(n):
-> 1273 a = op(a[slice1], a[slice2])
1274
1275 return a
UFuncTypeError: ufunc 'subtract' did not contain a loop with signature matching types (dtype('<U1'), dtype('<U1')) -> dtype('<U1')
:QuadMesh [x,y] (z)