From 84f25c460f698dc37254c168b3e9c733a4a8e866 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Sun, 5 Feb 2017 22:37:22 +0000
Subject: [PATCH 1/2] Merge dynamic dimension values
---
holoviews/core/spaces.py | 3 ++-
holoviews/core/traversal.py | 4 ++--
holoviews/core/util.py | 17 +++++++++++++++++
tests/testutils.py | 18 +++++++++++++++++-
4 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/holoviews/core/spaces.py b/holoviews/core/spaces.py
index 5480a33f7b..58b50a6d5b 100644
--- a/holoviews/core/spaces.py
+++ b/holoviews/core/spaces.py
@@ -171,7 +171,8 @@ def __mul__(self, other):
# dimension labels for the new view
self_in_other = self_set.issubset(other_set)
other_in_self = other_set.issubset(self_set)
- dimensions = self.kdims
+ dims = [other.kdims, self.kdims] if self_in_other else [self.kdims, other.kdims]
+ dimensions = util.merge_dimensions(dims)
if self_in_other and other_in_self: # superset of each other
keys = self._dimension_keys() + other._dimension_keys()
diff --git a/holoviews/core/traversal.py b/holoviews/core/traversal.py
index 896e69f708..c377e178ae 100644
--- a/holoviews/core/traversal.py
+++ b/holoviews/core/traversal.py
@@ -8,6 +8,7 @@
from operator import itemgetter
from .dimension import Dimension, OrderedDict
+from .util import merge_dimensions
try:
import itertools.izip as zip
@@ -56,8 +57,7 @@ def unique_dimkeys(obj, default_dim='Frame'):
subset = all(g1 <= g2 or g1 >= g2 for g1 in dgroups for g2 in dgroups)
# Find unique keys
if subset:
- dims = OrderedDict([(dim.name, dim) for dim_group in dim_groups
- for dim in dim_group]).values()
+ dims = merge_dimensions(dim_groups)
all_dims = sorted(dims, key=lambda x: dim_groups[0].index(x))
else:
all_dims = [default_dim]
diff --git a/holoviews/core/util.py b/holoviews/core/util.py
index 9223f01077..e5a071cc7b 100644
--- a/holoviews/core/util.py
+++ b/holoviews/core/util.py
@@ -608,6 +608,23 @@ def python2sort(x,key=None):
return itertools.chain.from_iterable(sorted(group, key=key) for group in groups)
+def merge_dimensions(dimensions_list):
+ """
+ Merges lists of fully or partially overlapping dimensions by
+ combining their values.
+ """
+ dvalues = defaultdict(list)
+ dimensions = []
+ for dims in dimensions_list:
+ for d in dims:
+ dvalues[d.name].append(d.values)
+ if d not in dimensions:
+ dimensions.append(d)
+ dvalues = {k: list(unique_iterator(itertools.chain(*vals)))
+ for k, vals in dvalues.items()}
+ return [d(values=dvalues.get(d.name, [])) for d in dimensions]
+
+
def dimension_sort(odict, kdims, vdims, categorical, key_index, cached_values):
"""
Sorts data by key using usual Python tuple sorting semantics
diff --git a/tests/testutils.py b/tests/testutils.py
index 7fc7b4b656..5aabb9954c 100644
--- a/tests/testutils.py
+++ b/tests/testutils.py
@@ -14,7 +14,10 @@
except:
pd = None
-from holoviews.core.util import sanitize_identifier_fn, find_range, max_range, wrap_tuple_streams, deephash
+from holoviews.core.util import (
+ sanitize_identifier_fn, find_range, max_range, wrap_tuple_streams,
+ deephash, merge_dimensions
+)
from holoviews import Dimension
from holoviews.streams import PositionXY
from holoviews.element.comparison import ComparisonTestCase
@@ -447,3 +450,16 @@ def test_no_streams_two_stream_substitution(self):
[Dimension('x'), Dimension('y')],
[PositionXY(x=0,y=5)])
self.assertEqual(result, (0,5))
+
+
+class TestMergeDimensions(unittest.TestCase):
+
+ def test_merge_dimensions(self):
+ dimensions = merge_dimensions([[Dimension('A')], [Dimension('A'), Dimension('B')]])
+ self.assertEqual(dimensions, [Dimension('A'), Dimension('B')])
+
+ def test_merge_dimensions_with_values(self):
+ dimensions = merge_dimensions([[Dimension('A', values=[0, 1])],
+ [Dimension('A', values=[1, 2]), Dimension('B')]])
+ self.assertEqual(dimensions, [Dimension('A'), Dimension('B')])
+ self.assertEqual(dimensions[0].values, [0, 1, 2])
From f66ec437186335cca7b62ad69bb22c187e886656 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Mon, 6 Feb 2017 17:30:23 +0000
Subject: [PATCH 2/2] Added doctest to merge_dimensions utility
---
holoviews/core/util.py | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/holoviews/core/util.py b/holoviews/core/util.py
index e5a071cc7b..1800d45811 100644
--- a/holoviews/core/util.py
+++ b/holoviews/core/util.py
@@ -611,7 +611,16 @@ def python2sort(x,key=None):
def merge_dimensions(dimensions_list):
"""
Merges lists of fully or partially overlapping dimensions by
- combining their values.
+ merging their values.
+
+ >>> from holoviews import Dimension
+ >>> dim_list = [[Dimension('A', values=[1, 2, 3]), Dimension('B')],
+ ... [Dimension('A', values=[2, 3, 4])]]
+ >>> dimensions = merge_dimensions(dim_list)
+ >>> dimensions
+ [Dimension('A'), Dimension('B')]
+ >>> dimensions[0].values
+ [1, 2, 3, 4]
"""
dvalues = defaultdict(list)
dimensions = []