diff --git a/holoviews/plotting/bokeh/plot.py b/holoviews/plotting/bokeh/plot.py index c8676b32e8..b873f10085 100644 --- a/holoviews/plotting/bokeh/plot.py +++ b/holoviews/plotting/bokeh/plot.py @@ -15,10 +15,12 @@ GenericElementPlot, GenericOverlayPlot) from ..util import attach_streams from .util import (layout_padding, pad_plots, filter_toolboxes, make_axis, - update_shared_sources, empty_plot, decode_bytes) + update_shared_sources, empty_plot, decode_bytes, + bokeh_version) from bokeh.layouts import gridplot from bokeh.plotting.helpers import _known_tools as known_tools +from bokeh.util.serialization import convert_datetime_array TOOLS = {name: tool if isinstance(tool, basestring) else type(tool()) for name, tool in known_tools.items()} @@ -184,7 +186,32 @@ def _update_datasource(self, source, data): stream = self.streaming[0] if stream._triggering: data = {k: v[-stream._chunk_length:] for k, v in data.items()} - source.stream(data, stream.length) + + # NOTE: Workaround for bug in bokeh 0.12.14, data conversion + # should be removed once fixed in bokeh (https://github.com/bokeh/bokeh/issues/7587) + converted_data = {} + for k, vals in data.items(): + cdata = source.data[k] + odata = data[k] + if (bokeh_version in ['0.12.14', '0.12.15dev1'] and + isinstance(cdata, np.ndarray) and cdata.dtype.kind == 'M' + and isinstance(vals, np.ndarray) and vals.dtype.kind == 'M'): + cdata = convert_datetime_array(cdata) + odata = convert_datetime_array(odata) + if len(odata): + cdata = np.concatenate([odata, cdata]) + converted_data[k] = cdata + if converted_data: + for k, vals in data.items(): + cdata = source.data[k] + odata = data[k] + if k not in converted_data: + if len(odata): + cdata = np.concatenate([odata, cdata]) + converted_data[k] = cdata + source.data.update(converted_data) + else: + source.stream(data, stream.length) else: source.data.update(data)