From cb78e087a3259d473edff850205badc5d4268acb Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Fri, 4 May 2018 18:38:45 +0100
Subject: [PATCH 1/3] Sort dynamic dimension values in widget constructor
---
holoviews/plotting/widgets/__init__.py | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/holoviews/plotting/widgets/__init__.py b/holoviews/plotting/widgets/__init__.py
index b313269261..de2e3cdb15 100644
--- a/holoviews/plotting/widgets/__init__.py
+++ b/holoviews/plotting/widgets/__init__.py
@@ -129,9 +129,14 @@ def __init__(self, plot, renderer=None, **params):
self.renderer = renderer
# Create mock NdMapping to hold the common dimensions and keys
+ sorted_dims = []
+ for dim in self.dimensions:
+ if dim.values and all(isnumeric(v) for v in dim.values):
+ dim = dim.clone(values=sorted(dim.values))
+ sorted_dims.append(dim)
with item_check(False):
- self.mock_obj = NdMapping([(k, None) for k in self.keys], kdims=list(self.dimensions),
- sort=False)
+ self.mock_obj = NdMapping([(k, None) for k in self.keys],
+ kdims=sorted_dims, sort=False)
NdWidget.widgets[self.id] = self
@@ -386,7 +391,7 @@ def _get_dynamic_widget(cls, idx, dim):
# Widgets currently detect dynamic mode by type
# this value representation is now redundant
# and should be removed in a refactor
- values = sorted(dim.values)
+ values = dim.values
dim_vals = {i: i for i, v in enumerate(values)}
widget_type = 'slider'
value_labels = escape_list(escape_vals([dim.pprint_value(v)
From 5017c82697de6dabf24897f0d3a9a9f57aa5eacc Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Mon, 7 May 2018 12:37:10 +0100
Subject: [PATCH 2/3] Ensure initial DynamicMap key respects default and
numeric values sorting
---
holoviews/core/spaces.py | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/holoviews/core/spaces.py b/holoviews/core/spaces.py
index 76851297f8..c335c1108d 100644
--- a/holoviews/core/spaces.py
+++ b/holoviews/core/spaces.py
@@ -807,8 +807,13 @@ def _initial_key(self):
for kdim in self.kdims:
if str(kdim) in stream_params:
key.append(None)
+ elif kdim.default:
+ key.append(kdim.default)
elif kdim.values:
- key.append(kdim.values[0])
+ if all(util.isnumeric(v) for v in kdim.values):
+ key.append(sorted(kdim.values)[0])
+ else:
+ key.append(kdim.values[0])
elif kdim.range[0] is not None:
key.append(kdim.range[0])
else:
From 28f6c33944bb1e598b334009d81b0ac437a3b12a Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Mon, 7 May 2018 12:55:23 +0100
Subject: [PATCH 3/3] Added unit tests for dynamic plot and widget
initialization
---
tests/plotting/bokeh/testwidgets.py | 22 ++++++++++++++++++++++
tests/plotting/testplotutils.py | 18 +++++++++++++++++-
2 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/tests/plotting/bokeh/testwidgets.py b/tests/plotting/bokeh/testwidgets.py
index 50e1998164..978b50ee2a 100644
--- a/tests/plotting/bokeh/testwidgets.py
+++ b/tests/plotting/bokeh/testwidgets.py
@@ -373,3 +373,25 @@ def test_holomap_dropdown_bad_default(self):
hmap = HoloMap({chr(65+i): Curve([1, 2, 3]) for i in range(10)}, dim)
with self.assertRaises(ValueError):
bokeh_renderer.get_widget(hmap, 'widgets').get_widgets()
+
+ def test_dynamicmap_default_value_slider_plot_initialization(self):
+ dims = [Dimension('N', default=5, range=(0, 10))]
+ dmap = DynamicMap(lambda N: Curve([1, N, 5]), kdims=dims)
+ widgets = bokeh_renderer.get_widget(dmap, 'widgets')
+ widgets.get_widgets()
+ self.assertEqual(widgets.plot.current_key, (5,))
+
+ def test_dynamicmap_unsorted_numeric_values_slider_plot_initialization(self):
+ dims = [Dimension('N', values=[10, 5, 0])]
+ dmap = DynamicMap(lambda N: Curve([1, N, 5]), kdims=dims)
+ widgets = bokeh_renderer.get_widget(dmap, 'widgets')
+ widgets.get_widgets()
+ self.assertEqual(widgets.plot.current_key, (0,))
+
+ def test_dynamicmap_unsorted_numeric_values_slider_plot_update(self):
+ dims = [Dimension('N', values=[10, 5, 0])]
+ dmap = DynamicMap(lambda N: Curve([1, N, 5]), kdims=dims)
+ widgets = bokeh_renderer.get_widget(dmap, 'widgets')
+ widgets.get_widgets()
+ widgets.update((2,))
+ self.assertEqual(widgets.plot.current_key, (10,))
diff --git a/tests/plotting/testplotutils.py b/tests/plotting/testplotutils.py
index 02038be4f6..d84e4ad361 100644
--- a/tests/plotting/testplotutils.py
+++ b/tests/plotting/testplotutils.py
@@ -5,7 +5,7 @@
import numpy as np
-from holoviews import NdOverlay, Overlay
+from holoviews import NdOverlay, Overlay, Dimension
from holoviews.core.spaces import DynamicMap, HoloMap
from holoviews.core.options import Store, Cycle
from holoviews.element.comparison import ComparisonTestCase
@@ -323,6 +323,22 @@ def test_dynamic_compute_overlayable_zorders_three_deep_dynamic_layers_reduced_l
self.assertNotIn(curve, sources[2])
+class TestInitializeDynamic(ComparisonTestCase):
+
+ def test_dynamicmap_default_initializes(self):
+ dims = [Dimension('N', default=5, range=(0, 10))]
+ dmap = DynamicMap(lambda N: Curve([1, N, 5]), kdims=dims)
+ initialize_dynamic(dmap)
+ self.assertEqual(dmap.keys(), [5])
+
+ def test_dynamicmap_numeric_values_initializes(self):
+ dims = [Dimension('N', values=[10, 5, 0])]
+ dmap = DynamicMap(lambda N: Curve([1, N, 5]), kdims=dims)
+ initialize_dynamic(dmap)
+ self.assertEqual(dmap.keys(), [0])
+
+
+
class TestSplitDynamicMapOverlay(ComparisonTestCase):
"""
Tests the split_dmap_overlay utility