From f3bb186ffc5b3aa5b6256c803ff6e239e0e8542b Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Mon, 13 Mar 2017 21:16:48 +0000
Subject: [PATCH] Fixed batched plot style cycles/palettes
---
holoviews/plotting/bokeh/chart.py | 23 +++++++++++++----------
holoviews/plotting/bokeh/path.py | 24 ++++++++++++++----------
holoviews/plotting/plot.py | 13 ++++++++-----
3 files changed, 35 insertions(+), 25 deletions(-)
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):