From aed81db850c3d39aca1bf7996cb847fb26b1e025 Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Mon, 25 Mar 2019 18:55:41 +0000 Subject: [PATCH 1/5] Improved support for style mapping constant values --- holoviews/plotting/bokeh/element.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/holoviews/plotting/bokeh/element.py b/holoviews/plotting/bokeh/element.py index a343132d21..d9b0655076 100644 --- a/holoviews/plotting/bokeh/element.py +++ b/holoviews/plotting/bokeh/element.py @@ -23,7 +23,7 @@ from bokeh.models.widgets import Panel, Tabs from bokeh.plotting.helpers import _known_tools as known_tools -from ...core import DynamicMap, CompositeOverlay, Element, Dimension +from ...core import DynamicMap, CompositeOverlay, Element, Dimension, Dataset from ...core.options import abbreviated_exception, SkipRendering from ...core import util from ...element import Graph, VectorField, Path, Contours, Tiles @@ -953,8 +953,9 @@ def _apply_transforms(self, element, data, ranges, style, group=None): 'as not all dimensions could be resolved.' % (k, v)) continue - if len(v.ops) == 0 and v.dimension in self.overlay_dims: - val = self.overlay_dims[v.dimension] + if v.dimension in self.overlay_dims: + ds = Dataset([self.overlay_dims[v.dimension]], v.dimension) + val = v.apply(ds, ranges=ranges, flat=True)[0] elif isinstance(element, Path) and not isinstance(element, Contours): val = np.concatenate([v.apply(el, ranges=ranges, flat=True)[:-1] for el in element.split()]) @@ -962,7 +963,7 @@ def _apply_transforms(self, element, data, ranges, style, group=None): val = v.apply(element, ranges=ranges, flat=True) if (not util.isscalar(val) and len(util.unique_array(val)) == 1 and - (not 'color' in k or validate('color', val))): + ((not 'color' in k or validate('color', val)) or k in self._nonvectorized_styles)): val = val[0] if not util.isscalar(val): From 87a4884c0374e897f69887a4bf7bb9d9a04adee5 Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Mon, 25 Mar 2019 19:37:06 +0000 Subject: [PATCH 2/5] Allow NdOverlay dimension mapping in matplotlib --- holoviews/plotting/mpl/element.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/holoviews/plotting/mpl/element.py b/holoviews/plotting/mpl/element.py index 77f5a4f8da..d93187d8ea 100644 --- a/holoviews/plotting/mpl/element.py +++ b/holoviews/plotting/mpl/element.py @@ -558,8 +558,9 @@ def _apply_transforms(self, element, ranges, style): % (k, v)) continue - if len(v.ops) == 0 and v.dimension in self.overlay_dims: - val = self.overlay_dims[v.dimension] + if v.dimension in self.overlay_dims: + ds = Dataset([self.overlay_dims[v.dimension]], v.dimension) + val = v.apply(ds, ranges=ranges, flat=True)[0] elif type(element) is Path: val = np.concatenate([v.apply(el, ranges=ranges, flat=True)[:-1] for el in element.split()]) From abfcde70fd95b0c7fb7c9e19a22c972f6c9fb2e0 Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Tue, 26 Mar 2019 00:27:47 +0000 Subject: [PATCH 3/5] Added tests for Curve style mapping --- holoviews/plotting/bokeh/element.py | 3 +- holoviews/plotting/mpl/element.py | 3 +- .../tests/plotting/bokeh/testcurveplot.py | 55 +++++++++++++++++++ .../plotting/matplotlib/testcurveplot.py | 53 ++++++++++++++++++ 4 files changed, 112 insertions(+), 2 deletions(-) diff --git a/holoviews/plotting/bokeh/element.py b/holoviews/plotting/bokeh/element.py index d9b0655076..57652202a3 100644 --- a/holoviews/plotting/bokeh/element.py +++ b/holoviews/plotting/bokeh/element.py @@ -954,7 +954,8 @@ def _apply_transforms(self, element, data, ranges, style, group=None): continue if v.dimension in self.overlay_dims: - ds = Dataset([self.overlay_dims[v.dimension]], v.dimension) + ds = Dataset({d.name: v for d, v in self.overlay_dims.items()}, + list(self.overlay_dims)) val = v.apply(ds, ranges=ranges, flat=True)[0] elif isinstance(element, Path) and not isinstance(element, Contours): val = np.concatenate([v.apply(el, ranges=ranges, flat=True)[:-1] diff --git a/holoviews/plotting/mpl/element.py b/holoviews/plotting/mpl/element.py index d93187d8ea..94d952e862 100644 --- a/holoviews/plotting/mpl/element.py +++ b/holoviews/plotting/mpl/element.py @@ -559,7 +559,8 @@ def _apply_transforms(self, element, ranges, style): continue if v.dimension in self.overlay_dims: - ds = Dataset([self.overlay_dims[v.dimension]], v.dimension) + ds = Dataset({d.name: v for d, v in self.overlay_dims.items()}, + list(self.overlay_dims)) val = v.apply(ds, ranges=ranges, flat=True)[0] elif type(element) is Path: val = np.concatenate([v.apply(el, ranges=ranges, flat=True)[:-1] diff --git a/holoviews/tests/plotting/bokeh/testcurveplot.py b/holoviews/tests/plotting/bokeh/testcurveplot.py index b9ed795c67..1a68c7802e 100644 --- a/holoviews/tests/plotting/bokeh/testcurveplot.py +++ b/holoviews/tests/plotting/bokeh/testcurveplot.py @@ -9,6 +9,7 @@ from holoviews.element import Curve from holoviews.plotting.util import rgb2hex from holoviews.streams import PointerX +from holoviews.util.transform import dim from .testplot import TestBokehPlot, bokeh_renderer @@ -377,3 +378,57 @@ def test_curve_line_width_op(self): vdims=['y', 'linewidth']).options(line_width='linewidth') with self.assertRaises(Exception): bokeh_renderer.get_plot(curve) + + def test_curve_style_mapping_ndoverlay_dimensions(self): + ndoverlay = NdOverlay({ + (0, 'A'): Curve([1, 2, 0]), (0, 'B'): Curve([1, 2, 1]), + (1, 'A'): Curve([1, 2, 2]), (1, 'B'): Curve([1, 2, 3])}, + ['num', 'cat'] + ).opts({ + 'Curve': dict( + color=dim('num').categorize({0: 'red', 1: 'blue'}), + line_dash=dim('cat').categorize({'A': 'solid', 'B': 'dashed'}) + ) + }) + plot = bokeh_renderer.get_plot(ndoverlay) + for (num, cat), sp in plot.subplots.items(): + glyph = sp.handles['glyph'] + color = glyph.line_color + if num == 0: + self.assertEqual(color, 'red') + else: + self.assertEqual(color, 'blue') + print(glyph.properties_with_values()) + linestyle = glyph.line_dash + if cat == 'A': + self.assertEqual(linestyle, []) + else: + self.assertEqual(linestyle, [6]) + + def test_curve_style_mapping_constant_value_dimensions(self): + vdims = ['y', 'num', 'cat'] + ndoverlay = NdOverlay({ + 0: Curve([(0, 1, 0, 'A'), (1, 0, 0, 'A')], vdims=vdims), + 1: Curve([(0, 1, 0, 'B'), (1, 1, 0, 'B')], vdims=vdims), + 2: Curve([(0, 1, 1, 'A'), (1, 2, 1, 'A')], vdims=vdims), + 3: Curve([(0, 1, 1, 'B'), (1, 3, 1, 'B')], vdims=vdims)} + ).opts({ + 'Curve': dict( + color=dim('num').categorize({0: 'red', 1: 'blue'}), + line_dash=dim('cat').categorize({'A': 'solid', 'B': 'dashed'}) + ) + }) + plot = bokeh_renderer.get_plot(ndoverlay) + for k, sp in plot.subplots.items(): + glyph = sp.handles['glyph'] + color = glyph.line_color + if ndoverlay[k].iloc[0, 2] == 0: + self.assertEqual(color, 'red') + else: + self.assertEqual(color, 'blue') + linestyle = glyph.line_dash + print(linestyle) + if ndoverlay[k].iloc[0, 3] == 'A': + self.assertEqual(linestyle, []) + else: + self.assertEqual(linestyle, [6]) diff --git a/holoviews/tests/plotting/matplotlib/testcurveplot.py b/holoviews/tests/plotting/matplotlib/testcurveplot.py index 4a57a8c6fd..21ae9ab750 100644 --- a/holoviews/tests/plotting/matplotlib/testcurveplot.py +++ b/holoviews/tests/plotting/matplotlib/testcurveplot.py @@ -6,6 +6,7 @@ from holoviews.core.overlay import NdOverlay from holoviews.core.util import pd from holoviews.element import Curve +from holoviews.util.transform import dim from .testplot import TestMPLPlot, mpl_renderer @@ -185,3 +186,55 @@ def test_curve_linewidth_op(self): vdims=['y', 'linewidth']).options(linewidth='linewidth') with self.assertRaises(Exception): mpl_renderer.get_plot(curve) + + def test_curve_style_mapping_ndoverlay_dimensions(self): + ndoverlay = NdOverlay({ + (0, 'A'): Curve([1, 2, 0]), (0, 'B'): Curve([1, 2, 1]), + (1, 'A'): Curve([1, 2, 2]), (1, 'B'): Curve([1, 2, 3])}, + ['num', 'cat'] + ).opts({ + 'Curve': dict( + color=dim('num').categorize({0: 'red', 1: 'blue'}), + linestyle=dim('cat').categorize({'A': '-.', 'B': '-'}) + ) + }) + plot = mpl_renderer.get_plot(ndoverlay) + for (num, cat), sp in plot.subplots.items(): + artist = sp.handles['artist'] + color = artist.get_color() + if num == 0: + self.assertEqual(color, 'red') + else: + self.assertEqual(color, 'blue') + linestyle = artist.get_linestyle() + if cat == 'A': + self.assertEqual(linestyle, '-.') + else: + self.assertEqual(linestyle, '-') + + def test_curve_style_mapping_constant_value_dimensions(self): + vdims = ['y', 'num', 'cat'] + ndoverlay = NdOverlay({ + 0: Curve([(0, 1, 0, 'A'), (1, 0, 0, 'A')], vdims=vdims), + 1: Curve([(0, 1, 0, 'B'), (1, 1, 0, 'B')], vdims=vdims), + 2: Curve([(0, 1, 1, 'A'), (1, 2, 1, 'A')], vdims=vdims), + 3: Curve([(0, 1, 1, 'B'), (1, 3, 1, 'B')], vdims=vdims)} + ).opts({ + 'Curve': dict( + color=dim('num').categorize({0: 'red', 1: 'blue'}), + linestyle=dim('cat').categorize({'A': '-.', 'B': '-'}) + ) + }) + plot = mpl_renderer.get_plot(ndoverlay) + for k, sp in plot.subplots.items(): + artist = sp.handles['artist'] + color = artist.get_color() + if ndoverlay[k].iloc[0, 2] == 0: + self.assertEqual(color, 'red') + else: + self.assertEqual(color, 'blue') + linestyle = artist.get_linestyle() + if ndoverlay[k].iloc[0, 3] == 'A': + self.assertEqual(linestyle, '-.') + else: + self.assertEqual(linestyle, '-') From 3a70552921d042cf4a61ede452705529b9afbfe0 Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Tue, 26 Mar 2019 00:28:58 +0000 Subject: [PATCH 4/5] Update holoviews/tests/plotting/bokeh/testcurveplot.py --- holoviews/tests/plotting/bokeh/testcurveplot.py | 1 - 1 file changed, 1 deletion(-) diff --git a/holoviews/tests/plotting/bokeh/testcurveplot.py b/holoviews/tests/plotting/bokeh/testcurveplot.py index 1a68c7802e..2196a694c7 100644 --- a/holoviews/tests/plotting/bokeh/testcurveplot.py +++ b/holoviews/tests/plotting/bokeh/testcurveplot.py @@ -398,7 +398,6 @@ def test_curve_style_mapping_ndoverlay_dimensions(self): self.assertEqual(color, 'red') else: self.assertEqual(color, 'blue') - print(glyph.properties_with_values()) linestyle = glyph.line_dash if cat == 'A': self.assertEqual(linestyle, []) From 17422ee530cbda0af096478475777255747f16c2 Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Tue, 26 Mar 2019 00:29:15 +0000 Subject: [PATCH 5/5] Update holoviews/tests/plotting/bokeh/testcurveplot.py --- holoviews/tests/plotting/bokeh/testcurveplot.py | 1 - 1 file changed, 1 deletion(-) diff --git a/holoviews/tests/plotting/bokeh/testcurveplot.py b/holoviews/tests/plotting/bokeh/testcurveplot.py index 2196a694c7..b9516070c6 100644 --- a/holoviews/tests/plotting/bokeh/testcurveplot.py +++ b/holoviews/tests/plotting/bokeh/testcurveplot.py @@ -426,7 +426,6 @@ def test_curve_style_mapping_constant_value_dimensions(self): else: self.assertEqual(color, 'blue') linestyle = glyph.line_dash - print(linestyle) if ndoverlay[k].iloc[0, 3] == 'A': self.assertEqual(linestyle, []) else: