From 764145d799eb89e16e226f0345af7dece2980e75 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Wed, 22 Mar 2017 01:10:41 +0000
Subject: [PATCH] Refactored for glyph color handling
---
holoviews/plotting/bokeh/chart.py | 14 ++++----
holoviews/plotting/bokeh/element.py | 54 ++++++++++++++++++-----------
2 files changed, 41 insertions(+), 27 deletions(-)
diff --git a/holoviews/plotting/bokeh/chart.py b/holoviews/plotting/bokeh/chart.py
index d243cff8f6..3df6e8072d 100644
--- a/holoviews/plotting/bokeh/chart.py
+++ b/holoviews/plotting/bokeh/chart.py
@@ -112,7 +112,7 @@ def get_batched_data(self, element, ranges=None, empty=False):
nvals = len(data[k][-1])
if 'color' not in elmapping:
val = styles[zorder].get('color')
- elmapping['color'] = 'color'
+ elmapping['color'] = {'field': 'color'}
if isinstance(val, tuple):
val = rgb2hex(val)
data['color'].append([val]*nvals)
@@ -148,7 +148,7 @@ class VectorFieldPlot(ColorbarPlot):
Whether the lengths will be rescaled to take into account the
smallest non-zero distance between two vectors.""")
- style_opts = ['color'] + line_properties
+ style_opts = line_properties
_plot_methods = dict(single='segment')
def _get_lengths(self, element, ranges):
@@ -222,7 +222,7 @@ class CurvePlot(ElementPlot):
default is 'linear', other options include 'steps-mid',
'steps-pre' and 'steps-post'.""")
- style_opts = ['color'] + line_properties
+ style_opts = line_properties
_plot_methods = dict(single='line', batched='multi_line')
_mapping = {p: p for p in ['xs', 'ys', 'color', 'line_alpha']}
@@ -312,7 +312,7 @@ def get_data(self, element, ranges=None, empty=False):
class SpreadPlot(PolygonPlot):
- style_opts = ['color'] + line_properties + fill_properties
+ style_opts = line_properties + fill_properties
def get_data(self, element, ranges=None, empty=None):
if empty:
@@ -337,7 +337,7 @@ def get_data(self, element, ranges=None, empty=None):
class HistogramPlot(ElementPlot):
- style_opts = ['color'] + line_properties + fill_properties
+ style_opts = line_properties + fill_properties
_plot_methods = dict(single='quad')
def get_data(self, element, ranges=None, empty=None):
@@ -437,7 +437,7 @@ class ErrorPlot(PathPlot):
horizontal = param.Boolean(default=False)
- style_opts = ['color'] + line_properties
+ style_opts = line_properties
def get_data(self, element, ranges=None, empty=False):
if empty:
@@ -644,7 +644,7 @@ class BoxPlot(ChartPlot):
percentiles.
"""
- style_opts = ['color', 'whisker_color', 'marker'] + line_properties
+ style_opts = ['whisker_color', 'marker'] + line_properties
def _init_chart(self, element, ranges):
properties = self.style[self.cyclic_index]
diff --git a/holoviews/plotting/bokeh/element.py b/holoviews/plotting/bokeh/element.py
index 70b8ef3700..34a3de6a65 100644
--- a/holoviews/plotting/bokeh/element.py
+++ b/holoviews/plotting/bokeh/element.py
@@ -42,12 +42,12 @@
else:
FuncTickFormatter = None
-property_prefixes = ['selection', 'nonselection', 'muted', 'hover']
+property_prefixes = ['selection', 'nonselection', 'muted']
# Define shared style properties for bokeh plots
-line_properties = ['line_color', 'line_alpha', 'line_width',
+line_properties = ['line_color', 'line_alpha', 'color', 'line_width',
'line_join', 'line_cap', 'line_dash']
-line_properties += ['_'.join([prefix, prop]) for prop in line_properties[:2]
+line_properties += ['_'.join([prefix, prop]) for prop in line_properties[:3]
for prefix in property_prefixes]
fill_properties = ['fill_color', 'fill_alpha']
@@ -616,22 +616,35 @@ def _glyph_properties(self, plot, element, source, ranges):
properties['source'] = source
return properties
- def _update_glyphs(self, renderer, properties, mapping):
- allowed_properties = renderer.glyph.properties()
+ def _update_glyphs(self, renderer, properties, mapping, glyph):
+ allowed_properties = glyph.properties()
properties = mpl_to_bokeh(properties)
- merged = {k: v for k, v in dict(properties, **mapping).items()
- if k in allowed_properties}
- renderer.glyph.update(**merged)
- if renderer.selection_glyph:
- sel_props = {k[10:]: v for k, v in properties.items()
- if k.startswith('selection_')
- and k[10:] in allowed_properties}
- renderer.selection_glyph.update(**dict(merged, **sel_props))
- if renderer.nonselection_glyph:
- non_props = {k[13:]: v for k, v in properties.items()
- if k.startswith('nonselection_')
- and k[13:] in allowed_properties}
- renderer.nonselection_glyph.update(**dict(merged, **non_props))
+ merged = dict(properties, **mapping)
+ for glyph_type in ('', 'selection_', 'nonselection_'):
+ if renderer:
+ glyph = getattr(renderer, glyph_type+'glyph', None)
+ if not glyph or (not renderer and glyph_type):
+ continue
+ if glyph_type:
+ glyph_props = properties
+ else:
+ glyph_props = merged
+ glyph_color = merged.get(glyph_type+'color')
+
+ glyph_props = {k[len(glyph_type):]: v for k, v in glyph_props.items()
+ if k.startswith(glyph_type)}
+
+ if glyph_color and 'line_color' not in glyph_props:
+ glyph_props['line_color'] = glyph_color
+ if glyph_color and 'fill_color' not in glyph_props:
+ glyph_props['fill_color'] = glyph_color
+
+ if glyph_type:
+ glyph_props = dict(properties, **glyph_props)
+
+ filtered = {k: v for k, v in glyph_props.items()
+ if k in allowed_properties}
+ glyph.update(**filtered)
def _execute_hooks(self, element):
@@ -692,7 +705,7 @@ def initialize_plot(self, ranges=None, plot=None, plots=None, source=None):
# Update plot, source and glyph
with abbreviated_exception():
- self._update_glyphs(renderer, properties, mapping)
+ self._update_glyphs(renderer, properties, mapping, glyph)
if not self.overlaid:
self._update_plot(key, plot, style_element)
self._update_ranges(style_element, ranges)
@@ -760,7 +773,8 @@ def update_frame(self, key, ranges=None, plot=None, element=None, empty=False):
if glyph:
properties = self._glyph_properties(plot, element, source, ranges)
with abbreviated_exception():
- self._update_glyphs(self.handles['glyph_renderer'], properties, mapping)
+ self._update_glyphs(self.handles['glyph_renderer'], properties, mapping,
+ glyph)
if not self.overlaid:
self._update_ranges(style_element, ranges)
self._update_plot(key, plot, style_element)