From 74ce7cc07894bd5aeb7d36067be5607ff7aff6f7 Mon Sep 17 00:00:00 2001 From: jlstevens Date: Fri, 4 Dec 2015 14:17:40 +0000 Subject: [PATCH 1/8] Fixed and updated Options tutorial --- doc/Tutorials/Options.ipynb | 56 +++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/doc/Tutorials/Options.ipynb b/doc/Tutorials/Options.ipynb index b31b97b412..e3bd347a64 100644 --- a/doc/Tutorials/Options.ipynb +++ b/doc/Tutorials/Options.ipynb @@ -405,7 +405,7 @@ "\n", "In this way, it is possible to build complex objects with arbitrary customization, step by step. As mentioned above, it is also possible to customize objects already combined into a complex container, just by specifying an option for a suitable key (e.g. ``'Image.Function.Sine'`` above). This flexible system should allow for any level of customization that is needed.\n", "\n", - "Finally, there is one more way to apply options that is a mix of the above approaches -- temporarily assign a new ID to the object and apply a set of customizations during a specific portion of the code:" + "Finally, there is one more way to apply options that is a mix of the above approaches -- temporarily assign a new ID to the object and apply a set of customizations during a specific portion of the code. To illustrate this, we'll create a new Image object called 'Cosine':" ] }, { @@ -416,7 +416,57 @@ }, "outputs": [], "source": [ - "with hv.StoreOptions.options(green_sine, options={'Image':{'style':{'cmap':'Reds'}}}):\n", + "cosine = hv.Image(np.cos(x**2+y**2), group=\"Function\", label=\"Cosine\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "with hv.StoreOptions.options(cosine, options={'Image':{'style':{'cmap':'Reds'}}}):\n", + " data, info = renderer(cosine)\n", + "print(info)\n", + "SVG(data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here the result is in red as it was generated in the context of a 'Reds' colormap but if we display cosine again outside the scope of the with statement, it retains the default settings:m" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "cosine" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that if we want to use this context manager to set new options on the existing green_sine object, you must specify that the options apply to a specific Image by stating the applicable group and label:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "with hv.StoreOptions.options(green_sine, options={'Image.Function.Sine':{'style':{'cmap':'Purples'}}}):\n", " data, info = renderer(green_sine)\n", "print(info)\n", "SVG(data)" @@ -426,7 +476,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here the result is red, because it was rendered within the options context above, but were we to render the ``green_sine`` again it would still be green; the options are applied only within the scope of the ``with`` statement." + "Now the result inside the context is purple but elswhere green_sine remains green. If the group and label had not been specified above, the specific customization applied earlier (setting the green colormap) would take precedence over the general settings of Image. For this reason, it is important to know the appropriate precedence of new customizations and you can always specify the object group and label to make sure the new settings override the old ones." ] }, { From f42049ce7f381b0f569c46def1a0d5e651f3c206 Mon Sep 17 00:00:00 2001 From: jlstevens Date: Fri, 4 Dec 2015 14:23:18 +0000 Subject: [PATCH 2/8] Updated reference_data submodule reference --- doc/reference_data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/reference_data b/doc/reference_data index e9cfc49d19..f7a709800e 160000 --- a/doc/reference_data +++ b/doc/reference_data @@ -1 +1 @@ -Subproject commit e9cfc49d1959dc451d8188dc56ff222cab86e77b +Subproject commit f7a709800e0e2a053c32454af7ba4a589c2287b0 From 9f760c87d9eb3079f0d63530d6ca3cd55d9387aa Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Fri, 4 Dec 2015 13:59:03 +0000 Subject: [PATCH 3/8] Fixes for bokeh dev version compatibility --- holoviews/plotting/bokeh/element.py | 2 +- holoviews/plotting/bokeh/renderer.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/holoviews/plotting/bokeh/element.py b/holoviews/plotting/bokeh/element.py index 5d8e0eb7e4..c01e96bc59 100644 --- a/holoviews/plotting/bokeh/element.py +++ b/holoviews/plotting/bokeh/element.py @@ -262,7 +262,7 @@ def _plot_properties(self, key, plot, element): if self.show_title: plot_props['title'] = self._format_title(key, separator=' ') if self.bgcolor: - plot_props['background_fill'] = self.bgcolor + plot_props['background_fill_color'] = self.bgcolor if self.border is not None: plot_props['min_border'] = self.border lod = dict(self.defaults()['lod'], **self.lod) diff --git a/holoviews/plotting/bokeh/renderer.py b/holoviews/plotting/bokeh/renderer.py index 4a187e8775..227ef1c2c3 100644 --- a/holoviews/plotting/bokeh/renderer.py +++ b/holoviews/plotting/bokeh/renderer.py @@ -59,6 +59,8 @@ def __call__(self, obj, fmt=None): plotobjects = [h for handles in plot.traverse(lambda x: x.current_handles) for h in handles] data = OrderedDict() + if not old_bokeh: + data['root'] = plot.state._id for plotobj in plotobjects: if old_bokeh: json = plotobj.vm_serialize(changed_only=True) From bd7031f1d5837d12d1b13bfe7aebf70ee839c283 Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Fri, 4 Dec 2015 15:10:05 +0000 Subject: [PATCH 4/8] Allowed specifying ticks as tuples --- holoviews/plotting/bokeh/element.py | 2 +- holoviews/plotting/mpl/element.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/holoviews/plotting/bokeh/element.py b/holoviews/plotting/bokeh/element.py index c01e96bc59..7650666c31 100644 --- a/holoviews/plotting/bokeh/element.py +++ b/holoviews/plotting/bokeh/element.py @@ -308,7 +308,7 @@ def _axis_properties(self, axis, key, plot, element): axis_props['ticker'] = ticker elif isinstance(ticker, int): axis_props['ticker'] = BasicTicker(desired_num_ticks=ticker) - elif isinstance(ticker, list): + elif isinstance(ticker, (tuple, list)): if all(isinstance(t, tuple) for t in ticker): pass else: diff --git a/holoviews/plotting/mpl/element.py b/holoviews/plotting/mpl/element.py index bf44a186d7..191ba798ad 100644 --- a/holoviews/plotting/mpl/element.py +++ b/holoviews/plotting/mpl/element.py @@ -301,7 +301,7 @@ def _finalize_ticks(self, axis, view, xticks, yticks, zticks): else: locator = ticker.MaxNLocator(self.xticks) axis.xaxis.set_major_locator(locator) - elif isinstance(self.xticks, list): + elif isinstance(self.xticks, (list, tuple)): if all(isinstance(t, tuple) for t in self.xticks): xticks, xlabels = zip(*self.xticks) else: @@ -330,7 +330,7 @@ def _finalize_ticks(self, axis, view, xticks, yticks, zticks): else: locator = ticker.MaxNLocator(self.yticks) axis.yaxis.set_major_locator(locator) - elif isinstance(self.yticks, list): + elif isinstance(self.yticks, (list, tuple)): if all(isinstance(t, tuple) for t in self.yticks): yticks, ylabels = zip(*self.yticks) else: @@ -361,7 +361,7 @@ def _finalize_ticks(self, axis, view, xticks, yticks, zticks): else: locator = ticker.MaxNLocator(self.zticks) axis.zaxis.set_major_locator(locator) - elif isinstance(self.zticks, list): + elif isinstance(self.zticks, (list, tuple)): if all(isinstance(t, tuple) for t in self.zticks): zticks, zlabels = zip(*self.zticks) else: From a0246945650301fe50030043f41917a7b8497b81 Mon Sep 17 00:00:00 2001 From: jlstevens Date: Fri, 4 Dec 2015 15:39:38 +0000 Subject: [PATCH 5/8] Updated reference_data submodule reference --- doc/reference_data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/reference_data b/doc/reference_data index f7a709800e..5c1a418648 160000 --- a/doc/reference_data +++ b/doc/reference_data @@ -1 +1 @@ -Subproject commit f7a709800e0e2a053c32454af7ba4a589c2287b0 +Subproject commit 5c1a41864823ffd042c890fe9a307d9f592c9f55 From bf23c01ce8dcd6831f097492959378557ca2db58 Mon Sep 17 00:00:00 2001 From: jlstevens Date: Fri, 4 Dec 2015 16:02:05 +0000 Subject: [PATCH 6/8] Added support for 'labels' key in fontsize dictionary --- holoviews/plotting/plot.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/holoviews/plotting/plot.py b/holoviews/plotting/plot.py index 7609a8fc5d..1615e5562e 100644 --- a/holoviews/plotting/plot.py +++ b/holoviews/plotting/plot.py @@ -135,7 +135,10 @@ class DimensionedPlot(Plot): Finer control is available by supplying a dictionary where any unmentioned keys reverts to the default sizes, e.g: - {'ticks':20, 'title':15, 'ylabel':5, 'xlabel':5}""") + {'ticks':20, 'title':15, 'ylabel':5, 'xlabel':5} + + You can set the fontsize of both 'ylabel' and 'xlabel' together + using the 'labels' key.""") show_title = param.Boolean(default=True, doc=""" Whether to display the plot title.""") @@ -257,10 +260,13 @@ def _fontsize(self, key, label='fontsize', common=True): if not self.fontsize: return {} if isinstance(self.fontsize, dict): - if key not in self.fontsize: - return {} - else: + if key in self.fontsize: return {label:self.fontsize[key]} + elif key in ['ylabel', 'xlabel'] and 'labels' in self.fontsize: + return {label:self.fontsize['labels']} + else: + return {} + return {label:self.fontsize} if common else {} From bdf5cc2d6adc8075f983cf0b9b40fb0700c4c21a Mon Sep 17 00:00:00 2001 From: jlstevens Date: Fri, 4 Dec 2015 17:22:09 +0000 Subject: [PATCH 7/8] Updated reference_data submodule reference --- doc/reference_data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/reference_data b/doc/reference_data index 5c1a418648..a5afddb7f5 160000 --- a/doc/reference_data +++ b/doc/reference_data @@ -1 +1 @@ -Subproject commit 5c1a41864823ffd042c890fe9a307d9f592c9f55 +Subproject commit a5afddb7f5ac525eb44798831c4110fc36fad134 From 131287d1a6216c988b086392b620de33714c2e31 Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Fri, 4 Dec 2015 17:30:36 +0000 Subject: [PATCH 8/8] Added save_frames function in plotting.util --- holoviews/plotting/util.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/holoviews/plotting/util.py b/holoviews/plotting/util.py index 6d91e58fe4..86602005a0 100644 --- a/holoviews/plotting/util.py +++ b/holoviews/plotting/util.py @@ -1,7 +1,7 @@ import param from ..core import (HoloMap, DynamicMap, CompositeOverlay, Layout, - GridSpace, NdLayout) + GridSpace, NdLayout, Store) from ..core.util import match_spec @@ -130,3 +130,17 @@ def get_dynamic_mode(composite): return dynamic_modes[0] else: return None + + +def save_frames(obj, filename, fmt=None, backend=None, options=None): + """ + Utility to export object to files frame by frame, numbered individually. + Will use default backend and figure format by default. + """ + backend = Store.current_backend if backend is None else backend + renderer = Store.renderers[backend] + fmt = renderer.params('fig').objects[0] if fmt is None else fmt + plot = renderer.get_plot(obj) + for i in range(len(plot)): + plot.update(i) + renderer.save(plot, '%s_%s' % (filename, i), fmt=fmt, options=options)