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)