From 6d2575d73d021103204fcf392c417045bd3a4405 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Tue, 11 Apr 2017 01:42:54 +0100
Subject: [PATCH 1/2] Simplified DynamicMap reindex as it is handled
automatically
---
holoviews/core/spaces.py | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/holoviews/core/spaces.py b/holoviews/core/spaces.py
index 3168cba410..99b0983192 100644
--- a/holoviews/core/spaces.py
+++ b/holoviews/core/spaces.py
@@ -1096,13 +1096,7 @@ def reindex(self, kdims=[], force=False):
if dropped:
raise ValueError("DynamicMap does not allow dropping dimensions, "
"reindex may only be used to reorder dimensions.")
- reindexed = super(DynamicMap, self).reindex(kdims, force)
- def reindex(*args, **kwargs):
- keymap = {kd.name: arg for kd, arg in zip(self.kdims, args)}
- keymap.update(kwargs)
- args = tuple(keymap[kd.name] for kd in kdims)
- return reindexed[args]
- return reindexed.clone(callback=Callable(reindex, inputs=[self]))
+ return super(DynamicMap, self).reindex(kdims, force)
def drop_dimension(self, dimensions):
From 8ef0b8a27858dddb8033a47a7cfeda950a875948 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Tue, 11 Apr 2017 02:20:35 +0100
Subject: [PATCH 2/2] Ensure DynamicMap.clone Callable references original
DynamicMap
---
holoviews/core/spaces.py | 29 ++++++++++++++++++++++++++---
holoviews/core/util.py | 20 ++++++++++++++++++++
holoviews/streams.py | 25 +++----------------------
3 files changed, 49 insertions(+), 25 deletions(-)
diff --git a/holoviews/core/spaces.py b/holoviews/core/spaces.py
index 99b0983192..275a25561e 100644
--- a/holoviews/core/spaces.py
+++ b/holoviews/core/spaces.py
@@ -446,6 +446,19 @@ def __init__(self, callable, **params):
def argspec(self):
return util.argspec(self.callable)
+
+ def clone(self, callable=None, **overrides):
+ """
+ Allows making a copy of the Callable optionally overriding
+ the callable and other parameters.
+ """
+ old = {k: v for k, v in self.get_param_values()
+ if k not in ['callable', 'name']}
+ params = dict(old, **overrides)
+ callable = self.callable if callable is None else callable
+ return self.__class__(callable, **params)
+
+
def __call__(self, *args, **kwargs):
inputs = [i for i in self.inputs if isinstance(i, DynamicMap)]
streams = []
@@ -667,9 +680,19 @@ def clone(self, data=None, shared_data=True, new_type=None, *args, **overrides):
"""
if data is None and shared_data:
data = self.data
- return super(UniformNdMapping, self).clone(overrides.pop('callback', self.callback),
- shared_data, new_type,
- *(data,) + args, **overrides)
+ clone = super(UniformNdMapping, self).clone(overrides.pop('callback', self.callback),
+ shared_data, new_type,
+ *(data,) + args, **overrides)
+
+ # Ensure the clone references this object to ensure
+ # stream sources are inherited
+ if clone.callback is self.callback:
+ clone.callback = self.callback.clone()
+ if self not in clone.callback.inputs:
+ with util.disable_constant(clone.callback):
+ clone.callback.inputs = clone.callback.inputs+[self]
+ return clone
+
def reset(self):
"""
diff --git a/holoviews/core/util.py b/holoviews/core/util.py
index 19055216e4..1ec9ad3ce1 100644
--- a/holoviews/core/util.py
+++ b/holoviews/core/util.py
@@ -7,6 +7,7 @@
import datetime as dt
from collections import defaultdict, Counter
from functools import partial
+from contextlib import contextmanager
import numpy as np
import param
@@ -982,6 +983,25 @@ def get_param_values(data):
return params
+@contextmanager
+def disable_constant(parameterized):
+ """
+ Temporarily set parameters on Parameterized object to
+ constant=False.
+ """
+ params = parameterized.params().values()
+ constants = [p.constant for p in params]
+ for param in params:
+ param.constant = False
+ try:
+ yield
+ except:
+ raise
+ finally:
+ for (param, const) in zip(params, constants):
+ param.constant = const
+
+
def get_ndmapping_label(ndmapping, attr):
"""
Function to get the first non-auxiliary object
diff --git a/holoviews/streams.py b/holoviews/streams.py
index 95423badba..c99a6734ce 100644
--- a/holoviews/streams.py
+++ b/holoviews/streams.py
@@ -32,25 +32,6 @@ def triggering_streams(streams):
stream._triggering = False
-@contextmanager
-def disable_constant(parameterized):
- """
- Temporarily set parameters on Parameterized object to
- constant=False.
- """
- params = parameterized.params().values()
- constants = [p.constant for p in params]
- for param in params:
- param.constant = False
- try:
- yield
- except:
- raise
- finally:
- for (param, const) in zip(params, constants):
- param.constant = const
-
-
class Stream(param.Parameterized):
"""
A Stream is simply a parameterized object with parameters that
@@ -118,7 +99,7 @@ def trigger(cls, streams):
subscriber(**dict(union))
for stream in streams:
- with disable_constant(stream):
+ with util.disable_constant(stream):
if stream.transient:
stream.reset()
@@ -175,7 +156,7 @@ def reset(self):
"""
Resets stream parameters to their defaults.
"""
- with disable_constant(self):
+ with util.disable_constant(self):
for k, p in self.params().items():
if k != 'name':
setattr(self, k, p.default)
@@ -250,7 +231,7 @@ def _set_stream_parameters(self, **kwargs):
Sets the stream parameters which are expected to be declared
constant.
"""
- with disable_constant(self) as constant:
+ with util.disable_constant(self) as constant:
self.set_param(**kwargs)