From 2e801dabdc730f969734026f7dbccf664cad6c5f Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Wed, 26 Oct 2016 00:07:42 +0100
Subject: [PATCH 1/3] Reimplemented Layout.from_values
---
holoviews/core/layout.py | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/holoviews/core/layout.py b/holoviews/core/layout.py
index 828ab0f3c5..f994b72471 100644
--- a/holoviews/core/layout.py
+++ b/holoviews/core/layout.py
@@ -366,10 +366,6 @@ def relabel_item_paths(cls, items):
return list(zip(paths, path_items))
- @classmethod
- def _from_values(cls, val):
- return reduce(lambda x,y: x+y, val).display('auto')
-
@classmethod
def from_values(cls, val):
"""
@@ -379,15 +375,20 @@ def from_values(cls, val):
collection = isinstance(val, (list, tuple))
if type(val) is cls:
return val
- elif collection and len(val)>1:
- return cls._from_values(val)
- elif collection:
- val = val[0]
- group = group_sanitizer(val.group)
- group = ''.join([group[0].upper(), group[1:]])
- label = label_sanitizer(val.label if val.label else 'I')
- label = ''.join([label[0].upper(), label[1:]])
- return cls(items=[((group, label), val)])
+ elif not collection:
+ val = [val]
+ paths, items = [], []
+ count = 2
+ for v in val:
+ group = group_sanitizer(v.group)
+ group = ''.join([group[0].upper(), group[1:]])
+ label = label_sanitizer(v.label if v.label else 'I')
+ label = ''.join([label[0].upper(), label[1:]])
+ new_path, count = cls.new_path((group, label), v, paths, count)
+ new_path = tuple(''.join((p[0].upper(), p[1:])) for p in new_path)
+ paths.append(new_path)
+ items.append((new_path, v))
+ return cls(items=items)
def __init__(self, items=None, identifier=None, parent=None, **kwargs):
From 84b0a9a0dd621a9990064290327d2a12b8cfaa4a Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Wed, 26 Oct 2016 00:08:26 +0100
Subject: [PATCH 2/3] Added collate method on Overlay
---
holoviews/core/overlay.py | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/holoviews/core/overlay.py b/holoviews/core/overlay.py
index 0a611da9ca..cf162b1597 100644
--- a/holoviews/core/overlay.py
+++ b/holoviews/core/overlay.py
@@ -149,6 +149,14 @@ def __mul__(self, other):
return Overlay(items=self.relabel_item_paths(items)).display('all')
+ def collate(self):
+ """
+ Collates any objects in the Overlay resolving any issues
+ the recommended nesting structure.
+ """
+ return reduce(lambda x,y: x*y, self.values())
+
+
def collapse(self, function):
"""
Collapses all the Elements in the Overlay using the
From f5c9e2f6756f2772d6c3e90bff56dc09389e605b Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Wed, 26 Oct 2016 00:10:32 +0100
Subject: [PATCH 3/3] Overlays containing GridSpaces/HoloMaps auto-collate
---
holoviews/plotting/util.py | 15 ++++++++++++++-
tests/testcollation.py | 17 +++++++++++++++--
2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/holoviews/plotting/util.py b/holoviews/plotting/util.py
index f272018594..26aaaa5d14 100644
--- a/holoviews/plotting/util.py
+++ b/holoviews/plotting/util.py
@@ -4,7 +4,7 @@
import param
from ..core import (HoloMap, DynamicMap, CompositeOverlay, Layout,
- GridSpace, NdLayout, Store)
+ GridSpace, NdLayout, Store, Overlay)
from ..core.util import (match_spec, is_number, wrap_tuple, basestring,
get_overlay_spec, unique_iterator, safe_unicode)
@@ -14,6 +14,9 @@ def displayable(obj):
Predicate that returns whether the object is displayable or not
(i.e whether the object obeys the nesting hierarchy
"""
+ if isinstance(obj, Overlay) and any(isinstance(o, (HoloMap, GridSpace))
+ for o in obj):
+ return False
if isinstance(obj, HoloMap):
return not (obj.type in [Layout, GridSpace, NdLayout])
if isinstance(obj, (GridSpace, Layout, NdLayout)):
@@ -28,6 +31,16 @@ class Warning(param.Parameterized): pass
display_warning = Warning(name='Warning')
def collate(obj):
+ if isinstance(obj, Overlay):
+ nested_type = [type(o).__name__ for o in obj
+ if isinstance(o, (HoloMap, GridSpace))][0]
+ display_warning.warning("Nesting %ss within an Overlay makes it difficult "
+ "to access your data or control how it appears; "
+ "we recommend calling .collate() on the Overlay "
+ "in order to follow the recommended nesting "
+ "structure shown in the Composing Data tutorial"
+ "(http://git.io/vtIQh)" % nested_type)
+ return obj.collate()
if isinstance(obj, HoloMap):
display_warning.warning("Nesting %ss within a HoloMap makes it difficult "
"to access your data or control how it appears; "
diff --git a/tests/testcollation.py b/tests/testcollation.py
index 51d035e50c..479843c464 100644
--- a/tests/testcollation.py
+++ b/tests/testcollation.py
@@ -7,10 +7,12 @@
import numpy as np
-from holoviews.core import Collator, HoloMap, NdOverlay
+from holoviews.core import Collator, HoloMap, NdOverlay, Overlay, GridSpace
from holoviews.element import Curve
+from holoviews.element.comparison import ComparisonTestCase
-class TestCollation(unittest.TestCase):
+
+class TestCollation(ComparisonTestCase):
def setUp(self):
alphas, betas, deltas = 2, 2, 2
Bs = list(range(100))
@@ -67,3 +69,14 @@ def test_collate_layout_hmap(self):
collated = collated()
self.assertEqual(repr(collated), repr(layout))
self.assertEqual(collated.dimensions(), layout.dimensions())
+
+ def test_overlay_hmap_collate(self):
+ hmap = HoloMap({i: Curve(np.arange(10)*i) for i in range(3)})
+ overlaid = Overlay([hmap, hmap, hmap]).collate()
+ self.assertEqual(overlaid, hmap*hmap*hmap)
+
+ def test_overlay_gridspace_collate(self):
+ grid = GridSpace({(i,j): Curve(np.arange(10)*i) for i in range(3)
+ for j in range(3)})
+ overlaid = Overlay([grid, grid, grid]).collate()
+ self.assertEqual(overlaid, grid*grid*grid)