Skip to content

Commit

Permalink
Plotly: Add Panel-based support for linked streams and dynamic updates (
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr authored Aug 16, 2019
1 parent f62f629 commit 26fea8b
Show file tree
Hide file tree
Showing 16 changed files with 915 additions and 126 deletions.
4 changes: 0 additions & 4 deletions holoviews/plotting/bokeh/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -1871,10 +1871,6 @@ class OverlayPlot(GenericOverlayPlot, LegendPlot):
'margin', 'aspect', 'data_aspect', 'frame_width',
'frame_height', 'responsive']

def __init__(self, overlay, **params):
super(OverlayPlot, self).__init__(overlay, **params)
self.set_root(params.pop('root', None))

def _process_legend(self):
plot = self.handles['plot']
subplots = self.traverse(lambda x: x, [lambda x: x is not self])
Expand Down
71 changes: 4 additions & 67 deletions holoviews/plotting/bokeh/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@

from ...core import (
OrderedDict, Store, AdjointLayout, NdLayout, Layout, Empty,
GridSpace, HoloMap, Element, DynamicMap
GridSpace, HoloMap, Element
)
from ...core.options import SkipRendering
from ...core.util import (
basestring, cftime_to_timestamp, cftime_types, get_method_owner,
unique_iterator, wrap_tuple, wrap_tuple_streams, _STANDARD_CALENDARS)
from ...streams import Stream
from ..links import Link
from ..plot import (
DimensionedPlot, GenericCompositePlot, GenericLayoutPlot,
GenericElementPlot, GenericOverlayPlot, GenericAdjointLayoutPlot
GenericElementPlot, GenericOverlayPlot, GenericAdjointLayoutPlot,
CallbackPlot
)
from ..util import attach_streams, displayable, collate
from .callbacks import LinkCallback
Expand All @@ -31,7 +31,7 @@
empty_plot, decode_bytes, theme_attr_json, cds_column_replace)


class BokehPlot(DimensionedPlot):
class BokehPlot(DimensionedPlot, CallbackPlot):
"""
Plotting baseclass for the Bokeh backends, implementing the basic
plotting interface for Bokeh based plots.
Expand Down Expand Up @@ -91,60 +91,6 @@ def get_data(self, element, ranges, style):
raise NotImplementedError


@property
def link_sources(self):
"Returns potential Link or Stream sources."
if isinstance(self, GenericOverlayPlot):
zorders = []
elif self.batched:
zorders = list(range(self.zorder, self.zorder+len(self.hmap.last)))
else:
zorders = [self.zorder]

if isinstance(self, GenericOverlayPlot) and not self.batched:
sources = []
elif not self.static or isinstance(self.hmap, DynamicMap):
sources = [o for i, inputs in self.stream_sources.items()
for o in inputs if i in zorders]
else:
sources = [self.hmap.last]
return sources


def _construct_callbacks(self):
"""
Initializes any callbacks for streams which have defined
the plotted object as a source.
"""
cb_classes = set()
registry = list(Stream.registry.items())
callbacks = Stream._callbacks['bokeh']
for source in self.link_sources:
streams = [
s for src, streams in registry for s in streams
if src is source or (src._plot_id is not None and
src._plot_id == source._plot_id)]
cb_classes |= {(callbacks[type(stream)], stream) for stream in streams
if type(stream) in callbacks and stream.linked
and stream.source is not None}
cbs = []
sorted_cbs = sorted(cb_classes, key=lambda x: id(x[0]))
for cb, group in groupby(sorted_cbs, lambda x: x[0]):
cb_streams = [s for _, s in group]
cbs.append(cb(self, cb_streams, source))
return cbs


def set_root(self, root):
"""
Sets the root model on all subplots.
"""
if root is None:
return
for plot in self.traverse(lambda x: x):
plot._root = root


def _init_datasource(self, data):
"""
Initializes a data source to be passed into the bokeh glyph.
Expand Down Expand Up @@ -263,9 +209,6 @@ def cleanup(self):
if get_method_owner(subscriber) not in plots
]

if self.comm and self.root is self.handles.get('plot'):
self.comm.close()


def _fontsize(self, key, label='fontsize', common=True):
"""
Expand Down Expand Up @@ -510,10 +453,7 @@ def __init__(self, layout, ranges=None, layout_num=1, keys=None, **params):
ranges=ranges, keys=keys, **params)
self.cols, self.rows = layout.shape
self.subplots, self.layout = self._create_subplots(layout, ranges)
self.set_root(params.pop('root', None))
if self.top_level:
self.comm = self.init_comm()
self.traverse(lambda x: setattr(x, 'comm', self.comm))
self.traverse(lambda x: attach_streams(self, x.hmap, 2),
[GenericElementPlot])
if 'axis_offset' in params:
Expand Down Expand Up @@ -721,10 +661,7 @@ class LayoutPlot(CompositePlot, GenericLayoutPlot):
def __init__(self, layout, keys=None, **params):
super(LayoutPlot, self).__init__(layout, keys=keys, **params)
self.layout, self.subplots, self.paths = self._init_layout(layout)
self.set_root(params.pop('root', None))
if self.top_level:
self.comm = self.init_comm()
self.traverse(lambda x: setattr(x, 'comm', self.comm))
self.traverse(lambda x: attach_streams(self, x.hmap, 2),
[GenericElementPlot])

Expand Down
4 changes: 0 additions & 4 deletions holoviews/plotting/mpl/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,6 @@ def __init__(self, layout, axis=None, create_axes=True, ranges=None,
self.subplots, self.subaxes, self.layout = self._create_subplots(layout, axis,
ranges, create_axes)
if self.top_level:
self.comm = self.init_comm()
self.traverse(lambda x: setattr(x, 'comm', self.comm))
self.traverse(lambda x: attach_streams(self, x.hmap, 2),
[GenericElementPlot])

Expand Down Expand Up @@ -767,8 +765,6 @@ def __init__(self, layout, keys=None, **params):
with mpl.rc_context(rc=self.fig_rcparams):
self.subplots, self.subaxes, self.layout = self._compute_gridspec(layout)
if self.top_level:
self.comm = self.init_comm()
self.traverse(lambda x: setattr(x, 'comm', self.comm))
self.traverse(lambda x: attach_streams(self, x.hmap, 2),
[GenericElementPlot])

Expand Down
2 changes: 0 additions & 2 deletions holoviews/plotting/mpl/raster.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,6 @@ def __init__(self, layout, keys=None, dimensions=None, create_axes=False, ranges
if top_level:
dimensions, keys = traversal.unique_dimkeys(layout)
MPLPlot.__init__(self, dimensions=dimensions, keys=keys, **params)
if top_level:
self.comm = self.init_comm()

self.layout = layout
self.cyclic_index = 0
Expand Down
Loading

0 comments on commit 26fea8b

Please sign in to comment.