From 6022442c6ef3ab12e27759a80e3b0776d70b8cf5 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Wed, 12 Apr 2017 18:20:12 +0100
Subject: [PATCH 01/12] Disabled caching of Renderer parameters on output magic
---
holoviews/ipython/magics.py | 96 ++++++++++++++++++++-----------------
1 file changed, 53 insertions(+), 43 deletions(-)
diff --git a/holoviews/ipython/magics.py b/holoviews/ipython/magics.py
index 5cbf9d8311..d967df3099 100644
--- a/holoviews/ipython/magics.py
+++ b/holoviews/ipython/magics.py
@@ -97,7 +97,6 @@ def get_options(cls, line, options, linemagic):
info = (keyword,value)+allowed
raise ValueError("Value %r for key %r not between %s and %s" % info)
options[keyword] = value
-
return cls._validate(options, items, linemagic)
@classmethod
@@ -231,21 +230,28 @@ class OutputMagic(OptionsMagic):
'max-width', 'min-width', 'max-height',
'min-height', 'outline', 'float']}}
- defaults = OrderedDict([('backend' , 'matplotlib'),
- ('fig' , 'png'),
- ('holomap' , 'widgets'),
- ('widgets' , 'embed'),
- ('fps' , 20),
+ defaults = OrderedDict([('backend' , None),
+ ('fig' , None),
+ ('holomap' , None),
+ ('widgets' , None),
+ ('fps' , None),
('max_frames' , 500),
('max_branches', 2),
- ('size' , 100),
- ('dpi' , 72),
+ ('size' , None),
+ ('dpi' , None),
('charwidth' , 80),
('filename' , None),
('info' , False),
- ('css' , {})])
+ ('css' , None)])
+
+ # Defines the options the OutputMagic remembers the remainder
+ # is simply state on the backend specific Renderer
+ remembered = ['max_frames', 'max_branches', 'charwidth', 'info', 'filename']
+
+ # Remaining backend specific options renderer options
+ render_params = ['fig', 'holomap', 'size', 'fps', 'dpi', 'css', 'widget_mode', 'mode']
- options = OrderedDict(defaults.items())
+ options = OrderedDict()
_backend_options = defaultdict(dict)
# Used to disable info output in testing
@@ -286,22 +292,23 @@ def info(cls, obj):
@classmethod
def _generate_docstring(cls):
+ renderer = Store.renderers[Store.current_backend]
intro = ["Magic for setting HoloViews display options.",
"Arguments are supplied as a series of keywords in any order:", '']
backend = "backend : The backend used by HoloViews %r" % cls.allowed['backend']
fig = "fig : The static figure format %r" % cls.allowed['fig']
holomap = "holomap : The display type for holomaps %r" % cls.allowed['holomap']
- widgets = "widgets : The widget mode for widgets %r" % cls.allowed['widgets']
+ widgets = "widgets : The widget mode for widgets %r" % renderer.widget_mode
fps = ("fps : The frames per second for animations (default %r)"
- % cls.defaults['widgets'])
+ % renderer.fps)
frames= ("max_frames : The max number of frames rendered (default %r)"
% cls.defaults['max_frames'])
branches=("max_branches : The max number of Layout branches rendered (default %r)"
% cls.defaults['max_branches'])
size = ("size : The percentage size of displayed output (default %r)"
- % cls.defaults['size'])
+ % renderer.size)
dpi = ("dpi : The rendered dpi of the figure (default %r)"
- % cls.defaults['dpi'])
+ % renderer.dpi)
chars = ("charwidth : The max character width for displaying the output magic (default %r)"
% cls.defaults['charwidth'])
fname = ("filename : The filename of the saved output, if any (default %r)"
@@ -338,13 +345,18 @@ def output(self, line, cell=None):
return
restore_copy = OrderedDict(OutputMagic.options.items())
+ prev_backend = Store.current_backend
try:
- options = OrderedDict(OutputMagic.options.items())
+ options = OrderedDict([(k, v) for k, v in OutputMagic.options.items()
+ if k in self.remembered])
new_options = self.get_options(line, options, cell is None)
+ if 'backend' not in new_options:
+ new_options['backend'] = Store.current_backend
self._set_render_options(new_options)
OutputMagic.options = new_options
except Exception as e:
- self.update_options(options, {'backend': restore_copy['backend']})
+ backend = self.last_backend if 'backend' in new_options else Store.current_backend
+ self.update_options(options, {'backend': backend})
OutputMagic.options = restore_copy
self._set_render_options(restore_copy)
print('Error: %s' % str(e))
@@ -353,8 +365,8 @@ def output(self, line, cell=None):
if cell is not None:
self.shell.run_cell(cell, store_history=STORE_HISTORY)
- self.update_options(options, {'backend': restore_copy['backend']})
OutputMagic.options = restore_copy
+ self.set_backend(prev_backend)
self._set_render_options(restore_copy)
@@ -369,34 +381,29 @@ def update_options(cls, options, items):
renderer = Store.renderers[Store.current_backend]
prev_backend += ':%s' % renderer.mode
+ if 'backend' not in options:
+ options['backend'] = backend if backend else Store.current_backend
+
available = backend in Store.renderers.keys()
if (not backend) or (not available) or backend == prev_backend:
return options
- cls._backend_options[prev_backend] = cls.options
+ cls._backend_options[prev_backend] = {k: v for k, v in cls.options.items()
+ if k in cls.remembered}
- backend_options = cls._backend_options[backend]
+ backend_options = dict(cls._backend_options[backend])
for p in ['fig', 'holomap']:
- opts = list_formats(p, backend)
- cls.allowed[p] = opts
- cls.defaults[p] = opts[0]
- if p not in backend_options:
- backend_options[p] = opts[0]
+ cls.allowed[p] = list_formats(p, backend)
backend = backend.split(':')[0]
- render_params = ['fig', 'holomap', 'size', 'fps', 'dpi', 'css']
- for p in render_params:
- if p in backend_options:
- opt = backend_options[p]
- cls.defaults[p] = opt
- else:
- opt = cls.defaults[p]
- backend_options[p] = opt
-
for opt in options:
if opt not in backend_options:
backend_options[opt] = options[opt]
+ for opt in cls.remembered:
+ if opt not in backend_options:
+ backend_options[opt] = cls.defaults[opt]
+
cls.set_backend(backend)
return backend_options
@@ -404,14 +411,13 @@ def update_options(cls, options, items):
@classmethod
def initialize(cls, backend_list):
cls.backend_list = backend_list
- backend = cls.options.get('backend', cls.defaults['backend'])
+ backend = cls.options.get('backend', Store.current_backend)
if backend in Store.renderers:
- cls.options = dict(cls.defaults)
- cls._set_render_options(cls.defaults)
+ cls.options = dict({k: cls.defaults[k] for k in cls.remembered})
+ cls._set_render_options({})
cls.set_backend(backend)
else:
cls.options['backend'] = None
- cls.defaults['backend'] = None
cls.set_backend(None)
@classmethod
@@ -425,13 +431,17 @@ def _set_render_options(cls, options):
"""
Set options on current Renderer.
"""
- split = options['backend'].split(':')
- backend, mode = split if len(split)==2 else (split[0], 'default')
+ if 'backend' in options:
+ split = options['backend'].split(':')
+ backend, mode = split if len(split)==2 else (split[0], 'default')
+ options['mode'] = mode
+ else:
+ backend = Store.current_backend
+ if 'widgets' in options:
+ options['widget_mode'] = options['widgets']
renderer = Store.renderers[backend]
- render_params = ['fig', 'holomap', 'size', 'fps', 'dpi', 'css']
- render_options = {k: options[k] for k in render_params}
- renderer.set_param(**dict(render_options, widget_mode=options['widgets'],
- mode=mode))
+ render_options = {k: options[k] for k in cls.render_params if k in options}
+ renderer.set_param(**render_options)
@magics_class
From f1fcfeec0310f088015d00b0de625a73bd6654f8 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Wed, 12 Apr 2017 19:29:29 +0100
Subject: [PATCH 02/12] Ensure the first backend supplied to notebook_extension
is selected
---
holoviews/ipython/__init__.py | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/holoviews/ipython/__init__.py b/holoviews/ipython/__init__.py
index f4dfb03cac..a67c46dcb7 100644
--- a/holoviews/ipython/__init__.py
+++ b/holoviews/ipython/__init__.py
@@ -146,15 +146,22 @@ class notebook_extension(param.ParameterizedFunction):
'plotly': 'plotly'}
def __call__(self, *args, **params):
- imports = [(name, b) for name, b in self._backends.items()
- if name in args or params.get(name, False)]
- if not imports or 'matplotlib' not in Store.renderers:
- imports = imports + [('matplotlib', 'mpl')]
+ # Get requested backends
+ imports = [(arg, self._backends[arg]) for arg in args
+ if arg in self._backends]
+ for p, val in sorted(params.items()):
+ if p in self._backends:
+ imports.append((p, self._backends[p]))
+ if not imports:
+ imports = [('matplotlib', 'mpl')]
args = list(args)
+ selected_backend = None
for backend, imp in imports:
try:
__import__('holoviews.plotting.%s' % imp)
+ if selected_backend is None:
+ selected_backend = backend
except ImportError:
if backend in args:
args.pop(args.index(backend))
@@ -187,7 +194,7 @@ def __call__(self, *args, **params):
ip = get_ipython() if ip is None else ip # noqa (get_ipython)
param_ext.load_ipython_extension(ip, verbose=False)
load_magics(ip)
- OutputMagic.initialize(list( self._backends.keys()))
+ OutputMagic.initialize([backend for backend, _ in imports])
set_display_hooks(ip)
notebook_extension._loaded = True
@@ -209,11 +216,10 @@ def __call__(self, *args, **params):
message = '' if not p.banner else '%s successfully loaded in this cell.' % loaded
load_hvjs(logo=p.banner, JS=('holoviews' in resources), message = message)
+
for r in [r for r in resources if r != 'holoviews']:
Store.renderers[r].load_nb(inline=p.inline)
-
- if resources[-1] != 'holoviews':
- get_ipython().magic(u"output backend=%r" % resources[-1]) # noqa (get_ipython))
+ Store.current_backend = selected_backend
def _get_resources(self, args, params):
From 60195c6131d86338af7f87a6ae8f8b7d44e08996 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Wed, 12 Apr 2017 19:51:54 +0100
Subject: [PATCH 03/12] Fixes for OutputMagic allowed handling
---
holoviews/ipython/magics.py | 39 +++++++++++++++++--------------------
1 file changed, 18 insertions(+), 21 deletions(-)
diff --git a/holoviews/ipython/magics.py b/holoviews/ipython/magics.py
index d967df3099..8f2b828023 100644
--- a/holoviews/ipython/magics.py
+++ b/holoviews/ipython/magics.py
@@ -350,15 +350,12 @@ def output(self, line, cell=None):
options = OrderedDict([(k, v) for k, v in OutputMagic.options.items()
if k in self.remembered])
new_options = self.get_options(line, options, cell is None)
- if 'backend' not in new_options:
- new_options['backend'] = Store.current_backend
- self._set_render_options(new_options)
+ backend = new_options['backend'] if 'backend' in new_options else prev_backend
+ self._set_render_options(new_options, backend)
OutputMagic.options = new_options
except Exception as e:
- backend = self.last_backend if 'backend' in new_options else Store.current_backend
- self.update_options(options, {'backend': backend})
OutputMagic.options = restore_copy
- self._set_render_options(restore_copy)
+ self._set_render_options(restore_copy, prev_backend)
print('Error: %s' % str(e))
print("For help with the %output magic, call %output?\n")
return
@@ -366,8 +363,7 @@ def output(self, line, cell=None):
if cell is not None:
self.shell.run_cell(cell, store_history=STORE_HISTORY)
OutputMagic.options = restore_copy
- self.set_backend(prev_backend)
- self._set_render_options(restore_copy)
+ self._set_render_options(restore_copy, prev_backend)
@classmethod
@@ -376,25 +372,25 @@ def update_options(cls, options, items):
Switch default options and backend if new backend
is supplied in items.
"""
- backend = items.get('backend', '')
+ backend = items.get('backend', Store.current_backend)
prev_backend = Store.current_backend
- renderer = Store.renderers[Store.current_backend]
+ renderer = Store.renderers[prev_backend]
prev_backend += ':%s' % renderer.mode
if 'backend' not in options:
- options['backend'] = backend if backend else Store.current_backend
+ options['backend'] = backend
+
+ for p in ['fig', 'holomap']:
+ cls.allowed[p] = list_formats(p, backend)
available = backend in Store.renderers.keys()
if (not backend) or (not available) or backend == prev_backend:
return options
+ backend_options = dict(cls._backend_options[backend])
cls._backend_options[prev_backend] = {k: v for k, v in cls.options.items()
if k in cls.remembered}
- backend_options = dict(cls._backend_options[backend])
- for p in ['fig', 'holomap']:
- cls.allowed[p] = list_formats(p, backend)
-
backend = backend.split(':')[0]
for opt in options:
if opt not in backend_options:
@@ -404,7 +400,6 @@ def update_options(cls, options, items):
if opt not in backend_options:
backend_options[opt] = cls.defaults[opt]
- cls.set_backend(backend)
return backend_options
@@ -414,12 +409,12 @@ def initialize(cls, backend_list):
backend = cls.options.get('backend', Store.current_backend)
if backend in Store.renderers:
cls.options = dict({k: cls.defaults[k] for k in cls.remembered})
- cls._set_render_options({})
- cls.set_backend(backend)
+ cls._set_render_options({}, backend)
else:
cls.options['backend'] = None
cls.set_backend(None)
+
@classmethod
def set_backend(cls, backend):
cls.last_backend = Store.current_backend
@@ -427,16 +422,18 @@ def set_backend(cls, backend):
@classmethod
- def _set_render_options(cls, options):
+ def _set_render_options(cls, options, backend=None):
"""
Set options on current Renderer.
"""
- if 'backend' in options:
- split = options['backend'].split(':')
+ if backend:
+ split = backend.split(':')
backend, mode = split if len(split)==2 else (split[0], 'default')
options['mode'] = mode
else:
backend = Store.current_backend
+
+ cls.set_backend(backend)
if 'widgets' in options:
options['widget_mode'] = options['widgets']
renderer = Store.renderers[backend]
From cf574dcf2afba0ff53c9ba288470f25a84d05c62 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Wed, 12 Apr 2017 20:18:28 +0100
Subject: [PATCH 04/12] Fixed OutputMagic unit tests
---
tests/testmagics.py | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/tests/testmagics.py b/tests/testmagics.py
index feef8bc860..ba5346e62e 100644
--- a/tests/testmagics.py
+++ b/tests/testmagics.py
@@ -95,7 +95,6 @@ def test_cell_opts_norm(self):
class TestOutputMagic(ExtensionTestCase):
def tearDown(self):
- ipython.OutputMagic.options = ipython.OutputMagic.defaults
super(TestOutputMagic, self).tearDown()
def test_output_svg(self):
@@ -126,7 +125,7 @@ def test_output_size(self):
def test_output_invalid_size(self):
self.line_magic('output', "size=-50")
- self.assertEqual(ipython.OutputMagic.options.get('size', None), 100)
+ self.assertEqual(ipython.OutputMagic.options.get('size', None), None)
class TestCompositorMagic(ExtensionTestCase):
From 152f7d8942988e35d1e5d49b7ee61450ddb822e9 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Wed, 12 Apr 2017 20:33:20 +0100
Subject: [PATCH 05/12] Defined default dpi on Renderer
---
holoviews/plotting/renderer.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/holoviews/plotting/renderer.py b/holoviews/plotting/renderer.py
index 13cec36302..9fa35d580b 100644
--- a/holoviews/plotting/renderer.py
+++ b/holoviews/plotting/renderer.py
@@ -84,7 +84,7 @@ class Renderer(Exporter):
The full, lowercase name of the rendering backend or third
part plotting package used e.g 'matplotlib' or 'cairo'.""")
- dpi=param.Integer(None, allow_None=True, doc="""
+ dpi=param.Integer(72, doc="""
The render resolution in dpi (dots per inch)""")
fig = param.ObjectSelector(default='auto', objects=['auto'], doc="""
From 3fc3a98bba7b05ddefa00829830e3ff74f978baa Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Wed, 12 Apr 2017 20:52:24 +0100
Subject: [PATCH 06/12] Ensure renderer params are restored by OutputMagic
---
holoviews/ipython/magics.py | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/holoviews/ipython/magics.py b/holoviews/ipython/magics.py
index 8f2b828023..515b8f2e7b 100644
--- a/holoviews/ipython/magics.py
+++ b/holoviews/ipython/magics.py
@@ -346,6 +346,9 @@ def output(self, line, cell=None):
restore_copy = OrderedDict(OutputMagic.options.items())
prev_backend = Store.current_backend
+ renderer = Store.renderers[prev_backend]
+ render_params = [(k, v) for k, v in renderer.get_param_values()
+ if k in self.render_params]
try:
options = OrderedDict([(k, v) for k, v in OutputMagic.options.items()
if k in self.remembered])
@@ -355,7 +358,7 @@ def output(self, line, cell=None):
OutputMagic.options = new_options
except Exception as e:
OutputMagic.options = restore_copy
- self._set_render_options(restore_copy, prev_backend)
+ self._set_render_options(dict(render_params, **restore_copy), prev_backend)
print('Error: %s' % str(e))
print("For help with the %output magic, call %output?\n")
return
@@ -363,7 +366,7 @@ def output(self, line, cell=None):
if cell is not None:
self.shell.run_cell(cell, store_history=STORE_HISTORY)
OutputMagic.options = restore_copy
- self._set_render_options(restore_copy, prev_backend)
+ self._set_render_options(dict(render_params, **restore_copy), prev_backend)
@classmethod
From 24822898664d68d11481819d9a18be53eb3ff55c Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Thu, 13 Apr 2017 02:21:24 +0100
Subject: [PATCH 07/12] Moved default dpi definition to MPLRenderer
---
holoviews/plotting/mpl/renderer.py | 3 +++
holoviews/plotting/renderer.py | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/holoviews/plotting/mpl/renderer.py b/holoviews/plotting/mpl/renderer.py
index e9f80cd1a8..10728df9bf 100644
--- a/holoviews/plotting/mpl/renderer.py
+++ b/holoviews/plotting/mpl/renderer.py
@@ -43,6 +43,9 @@ class MPLRenderer(Renderer):
backend = param.String('matplotlib', doc="The backend name.")
+ dpi=param.Integer(72, doc="""
+ The render resolution in dpi (dots per inch)""")
+
fig = param.ObjectSelector(default='auto',
objects=['png', 'svg', 'pdf', 'html', None, 'auto'], doc="""
Output render format for static figures. If None, no figure
diff --git a/holoviews/plotting/renderer.py b/holoviews/plotting/renderer.py
index 9fa35d580b..ad41fddf20 100644
--- a/holoviews/plotting/renderer.py
+++ b/holoviews/plotting/renderer.py
@@ -84,7 +84,7 @@ class Renderer(Exporter):
The full, lowercase name of the rendering backend or third
part plotting package used e.g 'matplotlib' or 'cairo'.""")
- dpi=param.Integer(72, doc="""
+ dpi=param.Integer(None, doc="""
The render resolution in dpi (dots per inch)""")
fig = param.ObjectSelector(default='auto', objects=['auto'], doc="""
From 5e7df5536fbdeb6f09039817707f6c8b423d089b Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Thu, 13 Apr 2017 02:29:35 +0100
Subject: [PATCH 08/12] Small fix to comment in OutputMagic
---
holoviews/ipython/magics.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/holoviews/ipython/magics.py b/holoviews/ipython/magics.py
index 515b8f2e7b..f27c300bd1 100644
--- a/holoviews/ipython/magics.py
+++ b/holoviews/ipython/magics.py
@@ -244,8 +244,8 @@ class OutputMagic(OptionsMagic):
('info' , False),
('css' , None)])
- # Defines the options the OutputMagic remembers the remainder
- # is simply state on the backend specific Renderer
+ # Defines the options the OutputMagic remembers. All other options
+ # are held by the backend specific Renderer.
remembered = ['max_frames', 'max_branches', 'charwidth', 'info', 'filename']
# Remaining backend specific options renderer options
From aa3d88b7cdc2a7e0925e4d4cc9185e424a673376 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Thu, 13 Apr 2017 13:37:31 +0100
Subject: [PATCH 09/12] Completely revised OutputMagic logic
---
holoviews/ipython/magics.py | 83 +++++++++++++++++++++++++------------
1 file changed, 56 insertions(+), 27 deletions(-)
diff --git a/holoviews/ipython/magics.py b/holoviews/ipython/magics.py
index f27c300bd1..2453ae5b2d 100644
--- a/holoviews/ipython/magics.py
+++ b/holoviews/ipython/magics.py
@@ -344,29 +344,48 @@ def output(self, line, cell=None):
print("\nFor help with the %output magic, call %output?")
return
- restore_copy = OrderedDict(OutputMagic.options.items())
+ # Make backup of previous options
prev_backend = Store.current_backend
- renderer = Store.renderers[prev_backend]
- render_params = [(k, v) for k, v in renderer.get_param_values()
- if k in self.render_params]
+ prev_renderer = Store.renderers[prev_backend]
+ prev_mode = prev_renderer.mode
+ prev_params = {k: v for k, v in prev_renderer.get_param_values()
+ if k in self.render_params}
+ prev_restore = dict(OutputMagic.options)
try:
- options = OrderedDict([(k, v) for k, v in OutputMagic.options.items()
- if k in self.remembered])
- new_options = self.get_options(line, options, cell is None)
- backend = new_options['backend'] if 'backend' in new_options else prev_backend
- self._set_render_options(new_options, backend)
+ # Process magic
+ new_options = self.get_options(line, {}, cell is None)
+
+ # Make backup of options on selected renderer
+ if 'backend' in new_options:
+ backend = new_options['backend']
+ if ':' not in backend:
+ backend += ':default'
+ else:
+ backend = prev_backend+':'+prev_mode
+ renderer = Store.renderers[backend.split(':')[0]]
+ render_params = {k: v for k, v in renderer.get_param_values()
+ if k in self.render_params}
+
+ # Set options on selected renderer and set display hook options
OutputMagic.options = new_options
+ self._set_render_options(new_options, backend)
except Exception as e:
- OutputMagic.options = restore_copy
- self._set_render_options(dict(render_params, **restore_copy), prev_backend)
+ # If setting options failed ensure they are reset
+ OutputMagic.options = prev_restore
+ self.set_backend(prev_backend)
print('Error: %s' % str(e))
print("For help with the %output magic, call %output?\n")
return
if cell is not None:
self.shell.run_cell(cell, store_history=STORE_HISTORY)
- OutputMagic.options = restore_copy
- self._set_render_options(dict(render_params, **restore_copy), prev_backend)
+ # After cell magic restore previous options and restore
+ # temporarily selected renderer
+ OutputMagic.options = prev_restore
+ self._set_render_options(render_params, backend)
+ if backend.split(':')[0] != prev_backend:
+ self.set_backend(prev_backend)
+ self._set_render_options(prev_params, prev_backend+':'+prev_mode)
@classmethod
@@ -375,34 +394,46 @@ def update_options(cls, options, items):
Switch default options and backend if new backend
is supplied in items.
"""
- backend = items.get('backend', Store.current_backend)
+ # Get previous backend
prev_backend = Store.current_backend
renderer = Store.renderers[prev_backend]
prev_backend += ':%s' % renderer.mode
- if 'backend' not in options:
- options['backend'] = backend
+ # Get new backend
+ backend = items.get('backend', Store.current_backend)
+ split = backend.split(':')
+ core_backend, mode = split if len(split)==2 else (split[0], 'default')
+ if ':' not in backend:
+ backend += ':default'
+ # Update allowed formats
for p in ['fig', 'holomap']:
cls.allowed[p] = list_formats(p, backend)
- available = backend in Store.renderers.keys()
- if (not backend) or (not available) or backend == prev_backend:
+ # Return if backend invalid and let validation error
+ if core_backend not in Store.renderers:
+ options['backend'] = core_backend
return options
+ # Get backend specific options
backend_options = dict(cls._backend_options[backend])
cls._backend_options[prev_backend] = {k: v for k, v in cls.options.items()
if k in cls.remembered}
- backend = backend.split(':')[0]
- for opt in options:
- if opt not in backend_options:
- backend_options[opt] = options[opt]
-
+ # Fill in remembered options with defaults
for opt in cls.remembered:
if opt not in backend_options:
backend_options[opt] = cls.defaults[opt]
+ # Switch format if mode does not allow it
+ for p in ['fig', 'holomap']:
+ if backend_options.get(p) not in cls.allowed[p]:
+ backend_options[p] = cls.allowed[p][0]
+
+ # Ensure backend and mode are set
+ backend_options['mode'] = mode
+ backend_options['backend'] = backend
+
return backend_options
@@ -412,7 +443,7 @@ def initialize(cls, backend_list):
backend = cls.options.get('backend', Store.current_backend)
if backend in Store.renderers:
cls.options = dict({k: cls.defaults[k] for k in cls.remembered})
- cls._set_render_options({}, backend)
+ cls.set_backend(backend)
else:
cls.options['backend'] = None
cls.set_backend(None)
@@ -430,9 +461,7 @@ def _set_render_options(cls, options, backend=None):
Set options on current Renderer.
"""
if backend:
- split = backend.split(':')
- backend, mode = split if len(split)==2 else (split[0], 'default')
- options['mode'] = mode
+ backend = backend.split(':')[0]
else:
backend = Store.current_backend
From 9f4a82e98ef0280669c1b7ca616e6a414f1db78d Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Thu, 13 Apr 2017 18:13:22 +0100
Subject: [PATCH 10/12] Ensure notebook_extension displays baseclass Renderer
assets
---
holoviews/plotting/renderer.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/holoviews/plotting/renderer.py b/holoviews/plotting/renderer.py
index ad41fddf20..e78dba8d98 100644
--- a/holoviews/plotting/renderer.py
+++ b/holoviews/plotting/renderer.py
@@ -387,7 +387,7 @@ def html_assets(cls, core=True, extras=True, backends=None):
backends = [cls.backend] if cls.backend else []
# Get all the widgets and find the set of required js widget files
- widgets = [wdgt for r in Renderer.__subclasses__()
+ widgets = [wdgt for r in [Renderer]+Renderer.__subclasses__()
for wdgt in r.widgets.values()]
css = list({wdgt.css for wdgt in widgets})
basejs = list({wdgt.basejs for wdgt in widgets})
From bfdd81ac8bd7f6f846f3d448abc50fcc1a102572 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Thu, 13 Apr 2017 18:14:57 +0100
Subject: [PATCH 11/12] Small fix for notebook_extension backend loading
---
holoviews/ipython/__init__.py | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/holoviews/ipython/__init__.py b/holoviews/ipython/__init__.py
index a67c46dcb7..f33f9c2b32 100644
--- a/holoviews/ipython/__init__.py
+++ b/holoviews/ipython/__init__.py
@@ -206,6 +206,11 @@ def __call__(self, *args, **params):
if css:
display(HTML(css))
+ for r in [r for r in resources if r != 'holoviews']:
+ Store.renderers[r].load_nb(inline=p.inline)
+ if selected_backend is not None:
+ Store.current_backend = selected_backend
+
resources = list(resources)
if len(resources) == 0: return
@@ -217,9 +222,6 @@ def __call__(self, *args, **params):
message = '' if not p.banner else '%s successfully loaded in this cell.' % loaded
load_hvjs(logo=p.banner, JS=('holoviews' in resources), message = message)
- for r in [r for r in resources if r != 'holoviews']:
- Store.renderers[r].load_nb(inline=p.inline)
- Store.current_backend = selected_backend
def _get_resources(self, args, params):
From e4031b4ab2c7f975ed64503a369b755a0ab96915 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Thu, 13 Apr 2017 18:15:37 +0100
Subject: [PATCH 12/12] Improved naming of variables in OutputMagic
---
holoviews/ipython/magics.py | 50 ++++++++++++++++++-------------------
1 file changed, 25 insertions(+), 25 deletions(-)
diff --git a/holoviews/ipython/magics.py b/holoviews/ipython/magics.py
index 2453ae5b2d..9af6d22537 100644
--- a/holoviews/ipython/magics.py
+++ b/holoviews/ipython/magics.py
@@ -347,7 +347,7 @@ def output(self, line, cell=None):
# Make backup of previous options
prev_backend = Store.current_backend
prev_renderer = Store.renderers[prev_backend]
- prev_mode = prev_renderer.mode
+ prev_backend_spec = prev_backend+':'+prev_renderer.mode
prev_params = {k: v for k, v in prev_renderer.get_param_values()
if k in self.render_params}
prev_restore = dict(OutputMagic.options)
@@ -357,18 +357,18 @@ def output(self, line, cell=None):
# Make backup of options on selected renderer
if 'backend' in new_options:
- backend = new_options['backend']
- if ':' not in backend:
- backend += ':default'
+ backend_spec = new_options['backend']
+ if ':' not in backend_spec:
+ backend_spec += ':default'
else:
- backend = prev_backend+':'+prev_mode
- renderer = Store.renderers[backend.split(':')[0]]
+ backend_spec = prev_backend_spec
+ renderer = Store.renderers[backend_spec.split(':')[0]]
render_params = {k: v for k, v in renderer.get_param_values()
if k in self.render_params}
# Set options on selected renderer and set display hook options
OutputMagic.options = new_options
- self._set_render_options(new_options, backend)
+ self._set_render_options(new_options, backend_spec)
except Exception as e:
# If setting options failed ensure they are reset
OutputMagic.options = prev_restore
@@ -382,10 +382,10 @@ def output(self, line, cell=None):
# After cell magic restore previous options and restore
# temporarily selected renderer
OutputMagic.options = prev_restore
- self._set_render_options(render_params, backend)
- if backend.split(':')[0] != prev_backend:
+ self._set_render_options(render_params, backend_spec)
+ if backend_spec.split(':')[0] != prev_backend:
self.set_backend(prev_backend)
- self._set_render_options(prev_params, prev_backend+':'+prev_mode)
+ self._set_render_options(prev_params, prev_backend_spec)
@classmethod
@@ -394,31 +394,31 @@ def update_options(cls, options, items):
Switch default options and backend if new backend
is supplied in items.
"""
+ # Get new backend
+ backend_spec = items.get('backend', Store.current_backend)
+ split = backend_spec.split(':')
+ backend, mode = split if len(split)==2 else (split[0], 'default')
+ if ':' not in backend_spec:
+ backend_spec += ':default'
+
# Get previous backend
prev_backend = Store.current_backend
renderer = Store.renderers[prev_backend]
- prev_backend += ':%s' % renderer.mode
-
- # Get new backend
- backend = items.get('backend', Store.current_backend)
- split = backend.split(':')
- core_backend, mode = split if len(split)==2 else (split[0], 'default')
- if ':' not in backend:
- backend += ':default'
+ prev_backend_spec = prev_backend+':'+renderer.mode
# Update allowed formats
for p in ['fig', 'holomap']:
- cls.allowed[p] = list_formats(p, backend)
+ cls.allowed[p] = list_formats(p, backend_spec)
# Return if backend invalid and let validation error
- if core_backend not in Store.renderers:
- options['backend'] = core_backend
+ if backend not in Store.renderers:
+ options['backend'] = backend_spec
return options
# Get backend specific options
- backend_options = dict(cls._backend_options[backend])
- cls._backend_options[prev_backend] = {k: v for k, v in cls.options.items()
- if k in cls.remembered}
+ backend_options = dict(cls._backend_options[backend_spec])
+ cls._backend_options[prev_backend_spec] = {k: v for k, v in cls.options.items()
+ if k in cls.remembered}
# Fill in remembered options with defaults
for opt in cls.remembered:
@@ -431,8 +431,8 @@ def update_options(cls, options, items):
backend_options[p] = cls.allowed[p][0]
# Ensure backend and mode are set
+ backend_options['backend'] = backend_spec
backend_options['mode'] = mode
- backend_options['backend'] = backend
return backend_options