diff --git a/holoviews/plotting/bokeh/chart.py b/holoviews/plotting/bokeh/chart.py index 8e73c638ac..4d4469b48a 100644 --- a/holoviews/plotting/bokeh/chart.py +++ b/holoviews/plotting/bokeh/chart.py @@ -98,9 +98,11 @@ def get_data(self, element, ranges=None, empty=False): def get_batched_data(self, element, ranges=None, empty=False): data = defaultdict(list) - for key, el in element.data.items(): - style = self.lookup_options(el, 'style') - style = style.max_cycles(len(self.ordering)) + zorders = self._updated_zorders(element) + styles = self.lookup_options(element.last, 'style') + styles = styles.max_cycles(len(self.ordering)) + + for (key, el), zorder in zip(element.data.items(), zorders): self.set_param(**self.lookup_options(el, 'plot').options) eldata, elmapping = self.get_data(el, ranges, empty) for k, eld in eldata.items(): @@ -108,8 +110,7 @@ def get_batched_data(self, element, ranges=None, empty=False): nvals = len(data[k][-1]) if 'color' not in elmapping: - zorder = self.get_zorder(element, key, el) - val = style[zorder].get('color') + val = styles[zorder].get('color') elmapping['color'] = 'color' if isinstance(val, tuple): val = rgb2hex(val) @@ -271,16 +272,18 @@ def _hover_opts(self, element): def get_batched_data(self, overlay, ranges=None, empty=False): data = defaultdict(list) opts = ['color', 'line_alpha', 'line_color'] - for key, el in overlay.data.items(): + + zorders = self._updated_zorders(overlay) + styles = self.lookup_options(overlay.last, 'style') + styles = styles.max_cycles(len(self.ordering)) + + for (key, el), zorder in zip(overlay.data.items(), zorders): eldata, elmapping = self.get_data(el, ranges, empty) for k, eld in eldata.items(): data[k].append(eld) # Add options - style = self.lookup_options(el, 'style') - style = style.max_cycles(len(self.ordering)) - zorder = self.get_zorder(overlay, key, el) - style = style[zorder] + style = styles[zorder] for opt in opts: if opt not in style: continue diff --git a/holoviews/plotting/bokeh/path.py b/holoviews/plotting/bokeh/path.py index 8448737779..5f70048dc5 100644 --- a/holoviews/plotting/bokeh/path.py +++ b/holoviews/plotting/bokeh/path.py @@ -35,15 +35,17 @@ def get_data(self, element, ranges=None, empty=False): def get_batched_data(self, element, ranges=None, empty=False): data = defaultdict(list) - for key, el in element.data.items(): - style = self.lookup_options(el, 'style') - style = style.max_cycles(len(self.ordering)) + + zorders = self._updated_zorders(element) + styles = self.lookup_options(element.last, 'style') + styles = styles.max_cycles(len(self.ordering)) + + for (key, el), zorder in zip(element.data.items(), zorders): self.overlay_dims = dict(zip(element.kdims, key)) eldata, elmapping = self.get_data(el, ranges, empty) for k, eld in eldata.items(): data[k].extend(eld) - zorder = self.get_zorder(element, key, el) - val = style[zorder].get('color') + val = styles[zorder].get('color') if val: elmapping['line_color'] = 'color' if isinstance(val, tuple): @@ -92,16 +94,18 @@ def get_data(self, element, ranges=None, empty=False): def get_batched_data(self, element, ranges=None, empty=False): data = defaultdict(list) - for key, el in element.data.items(): - style = self.lookup_options(el, 'style') - style = style.max_cycles(len(self.ordering)) + + zorders = self._updated_zorders(element) + styles = self.lookup_options(element.last, 'style') + styles = styles.max_cycles(len(self.ordering)) + + for (key, el), zorder in zip(element.data.items(), zorders): self.overlay_dims = dict(zip(element.kdims, key)) eldata, elmapping = self.get_data(el, ranges, empty) for k, eld in eldata.items(): data[k].extend(eld) if 'color' not in elmapping: - zorder = self.get_zorder(element, key, el) - val = style[zorder].get('color') + val = styles[zorder].get('color') elmapping['color'] = 'color' if isinstance(val, tuple): val = rgb2hex(val) diff --git a/holoviews/plotting/plot.py b/holoviews/plotting/plot.py index 8ca19f9f48..f6014b7da2 100644 --- a/holoviews/plotting/plot.py +++ b/holoviews/plotting/plot.py @@ -615,11 +615,14 @@ def get_zorder(self, overlay, key, el): taking into account possible batching of elements. """ spec = util.get_overlay_spec(overlay, key, el) - try: - return self.ordering.index(spec) - except ValueError: - self.ordering = sorted(self.ordering+[spec]) - return self.ordering.index(spec) + return self.ordering.index(spec) + + + def _updated_zorders(self, overlay): + specs = [util.get_overlay_spec(overlay, key, el) + for key, el in overlay.data.items()] + self.ordering = sorted(set(self.ordering+specs)) + return [self.ordering.index(spec) for spec in specs] def _get_frame(self, key):