From 6c1937a38822d8f4532f18b2947c50195e313366 Mon Sep 17 00:00:00 2001 From: Jon Mease Date: Thu, 22 Aug 2019 07:06:20 -0400 Subject: [PATCH] Move selection_expr to the first positional arg of Dataset.select Add error message if first arg is not a dim expression, referring users to the selection_specs keyword argument. --- holoviews/core/data/__init__.py | 17 ++++++++++++----- holoviews/core/dimension.py | 4 ++-- holoviews/core/spaces.py | 2 +- holoviews/plotting/util.py | 2 +- holoviews/tests/element/testelementselect.py | 15 +++++++++++++-- 5 files changed, 29 insertions(+), 11 deletions(-) diff --git a/holoviews/core/data/__init__.py b/holoviews/core/data/__init__.py index 6d787f149b..ab3df168ff 100644 --- a/holoviews/core/data/__init__.py +++ b/holoviews/core/data/__init__.py @@ -335,7 +335,7 @@ def add_dimension(self, dimension, dim_pos, dim_val, vdim=False, **kwargs): return self.clone(data, **dimensions) - def select(self, selection_specs=None, selection_expr=None, **selection): + def select(self, selection_expr=None, selection_specs=None, **selection): """Applies selection by dimension name Applies a selection along the dimensions of the object using @@ -366,12 +366,12 @@ def select(self, selection_specs=None, selection_expr=None, **selection): ds.select(selection_expr=dim('x') % 2 == 0) Args: + selection_expr: holoviews.dim predicate expression + specifying selection. selection_specs: List of specs to match on A list of types, functions, or type[.group][.label] strings specifying which objects to apply the selection on. - selection_expr: holoviews.dim predicate expression - specifying selection. **selection: Dictionary declaring selections by dimension Selections can be scalar values, tuple ranges, lists of discrete values and boolean arrays @@ -380,10 +380,17 @@ def select(self, selection_specs=None, selection_expr=None, **selection): Returns an Dimensioned object containing the selected data or a scalar if a single value was selected """ + from ...util.transform import dim + if selection_expr is not None and not isinstance(selection_expr, dim): + raise ValueError("""\ +The first positional argument to the Dataset.select method is expected to be a +holoviews.util.transform.dim expression. Use the selection_specs keyword +argument to specify a selection specification""") + if selection_specs is not None and not isinstance(selection_specs, (list, tuple)): selection_specs = [selection_specs] - selection = {dim: sel for dim, sel in selection.items() - if dim in self.dimensions()+['selection_mask']} + selection = {dim_name: sel for dim_name, sel in selection.items() + if dim_name in self.dimensions()+['selection_mask']} if (selection_specs and not any(self.matches(sp) for sp in selection_specs) or (not selection and not selection_expr)): return self diff --git a/holoviews/core/dimension.py b/holoviews/core/dimension.py index e02aa49fd8..f001fedfbd 100644 --- a/holoviews/core/dimension.py +++ b/holoviews/core/dimension.py @@ -1109,14 +1109,14 @@ def select(self, selection_specs=None, **kwargs): # Apply the selection on the selected object of a different type dimensions = selection.dimensions() + ['value'] if any(kw in dimensions for kw in kwargs): - selection = selection.select(selection_specs, **kwargs) + selection = selection.select(selection_specs=selection_specs, **kwargs) elif isinstance(selection, Dimensioned) and selection._deep_indexable: # Apply the deep selection on each item in local selection items = [] for k, v in selection.items(): dimensions = v.dimensions() + ['value'] if any(kw in dimensions for kw in kwargs): - items.append((k, v.select(selection_specs, **kwargs))) + items.append((k, v.select(selection_specs=selection_specs, **kwargs))) else: items.append((k, v)) selection = selection.clone(items) diff --git a/holoviews/core/spaces.py b/holoviews/core/spaces.py index cb780aa945..c584381556 100644 --- a/holoviews/core/spaces.py +++ b/holoviews/core/spaces.py @@ -1371,7 +1371,7 @@ def select(self, selection_specs=None, **kwargs): """ if selection_specs is not None and not isinstance(selection_specs, (list, tuple)): selection_specs = [selection_specs] - selection = super(DynamicMap, self).select(selection_specs, **kwargs) + selection = super(DynamicMap, self).select(selection_specs=selection_specs, **kwargs) def dynamic_select(obj, **dynkwargs): if selection_specs is not None: matches = any(obj.matches(spec) for spec in selection_specs) diff --git a/holoviews/plotting/util.py b/holoviews/plotting/util.py index 8a5f6c1764..f72ded0ac7 100644 --- a/holoviews/plotting/util.py +++ b/holoviews/plotting/util.py @@ -477,7 +477,7 @@ def initialize_unbounded(obj, dimensions, key): """ select = dict(zip([d.name for d in dimensions], key)) try: - obj.select([DynamicMap], **select) + obj.select(selection_specs=[DynamicMap], **select) except KeyError: pass diff --git a/holoviews/tests/element/testelementselect.py b/holoviews/tests/element/testelementselect.py index 5331b393e1..5ed3473dba 100644 --- a/holoviews/tests/element/testelementselect.py +++ b/holoviews/tests/element/testelementselect.py @@ -86,7 +86,9 @@ def test_deep_layout_nesting_slice(self): self.assertEqual(selection, hmap1 + hmap2) def test_spec_duplicate_dim_select(self): - selection = self.duplicate_map.select((HoloMap,), x=(0, 1), y=(1, 3)) + selection = self.duplicate_map.select( + selection_specs=(HoloMap,), x=(0, 1), y=(1, 3) + ) self.assertEqual(selection, self.duplicate_map[0:1, 1:3]) def test_duplicate_dim_select(self): @@ -102,7 +104,8 @@ def test_datetime_select(self): curve = self.datetime_fn() overlay = curve * self.datetime_fn() for el in [curve, overlay]: - self.assertEqual(el.select(time=(s, e)), el[s:e]) + v = el.select(time=(s, e)) + self.assertEqual(v, el[s:e]) self.assertEqual(el.select(time= (dt.datetime(1999, 12, 31), dt.datetime(2000, 1, 2))), el[s:e] ) @@ -110,3 +113,11 @@ def test_datetime_select(self): self.assertEqual(el.select( time=(pd.Timestamp(s), pd.Timestamp(e)) ), el[pd.Timestamp(s):pd.Timestamp(e)]) + + def test_selection_spec_positional_error_message(self): + s, e = '1999-12-31', '2000-1-2' + curve = self.datetime_fn() + with self.assertRaisesRegex( + ValueError, "Use the selection_specs keyword" + ): + curve.select((Curve,), time=(s, e))