From fa723eb4f73a4c43b801bc1abcffa7e3ba5944d6 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Thu, 16 Mar 2017 21:15:25 +0000
Subject: [PATCH 1/6] Added support for plotting matplotlib from commandline
---
holoviews/plotting/bokeh/renderer.py | 2 ++
holoviews/plotting/mpl/__init__.py | 9 ---------
holoviews/plotting/mpl/plot.py | 5 +++++
holoviews/plotting/mpl/renderer.py | 30 +++++++++++++++++++++++++++-
4 files changed, 36 insertions(+), 10 deletions(-)
diff --git a/holoviews/plotting/bokeh/renderer.py b/holoviews/plotting/bokeh/renderer.py
index 7f0b97529b..9c5434158c 100644
--- a/holoviews/plotting/bokeh/renderer.py
+++ b/holoviews/plotting/bokeh/renderer.py
@@ -190,4 +190,6 @@ def load_nb(cls, inline=True):
"""
Loads the bokeh notebook resources.
"""
+ import matplotlib.pyplot as plt
+ plt.switch_backend('agg')
load_notebook(hide_banner=True, resources=INLINE if inline else CDN)
diff --git a/holoviews/plotting/mpl/__init__.py b/holoviews/plotting/mpl/__init__.py
index 12974b462c..ece855f26f 100644
--- a/holoviews/plotting/mpl/__init__.py
+++ b/holoviews/plotting/mpl/__init__.py
@@ -1,12 +1,3 @@
-
-try:
- # Switching to 'agg' backend (may be overridden in holoviews.rc)
- import matplotlib.pyplot as plt
- plt.switch_backend('agg')
-except:
- pass
-
-
import os
from distutils.version import LooseVersion
diff --git a/holoviews/plotting/mpl/plot.py b/holoviews/plotting/mpl/plot.py
index 10199034d4..9003b31007 100644
--- a/holoviews/plotting/mpl/plot.py
+++ b/holoviews/plotting/mpl/plot.py
@@ -130,6 +130,11 @@ def __init__(self, fig=None, axis=None, **params):
'finalize_hooks, not both.')
self.finalize_hooks = self.final_hooks
self.handles['bbox_extra_artists'] = []
+ if self.renderer.interactive:
+ plt.ion()
+ self._close_figures = False
+ else:
+ plt.ioff()
def _init_axis(self, fig, axis):
diff --git a/holoviews/plotting/mpl/renderer.py b/holoviews/plotting/mpl/renderer.py
index 424b993eed..78c2014a06 100644
--- a/holoviews/plotting/mpl/renderer.py
+++ b/holoviews/plotting/mpl/renderer.py
@@ -53,12 +53,15 @@ class MPLRenderer(Renderer):
Output render multi-frame (typically animated) format. If
None, no multi-frame rendering will occur.""")
+ interactive = param.Boolean(default=False, doc="""
+ Whether to enable interactive plotting allowing interactive
+ plotting with explicitly calling show.""")
+
mode = param.ObjectSelector(default='default',
objects=['default', 'mpld3', 'nbagg'], doc="""
The 'mpld3' mode uses the mpld3 library whereas the 'nbagg' uses
matplotlib's the experimental nbagg backend. """)
-
# : (animation writer, format, anim_kwargs, extra_args)
ANIMATION_OPTS = {
'webm': ('ffmpeg', 'webm', {},
@@ -112,6 +115,23 @@ def __call__(self, obj, fmt='auto'):
'mime_type':MIME_TYPES[fmt]}
+ def show(self, obj):
+ """
+ Renders the supplied object and displays it using the active
+ GUI backend.
+ """
+ from .plot import MPLPlot
+ MPLPlot._close_figures = False
+ try:
+ plot = self.get_plot(obj)
+ plot.initialize_plot()
+ plt.show(plot.state)
+ except:
+ MPLPlot._close_figures = True
+ raise
+ MPLPlot._close_figures = True
+
+
@classmethod
def plot_options(cls, obj, percent_size):
"""
@@ -279,3 +299,11 @@ def validate(cls, options):
"matplotlib:nbagg.\nSwitching widget mode to 'live'.")
options['widgets'] = 'live'
return options
+
+ @classmethod
+ def load_nb(cls, inline=True):
+ """
+ Initialize matplotlib backend
+ """
+ import matplotlib.pyplot as plt
+ plt.switch_backend('agg')
From e497429e7e3ffc06304dd124d71257827405c2a1 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Thu, 16 Mar 2017 22:01:58 +0000
Subject: [PATCH 2/6] Implemented initial BokehRenderer.show
---
holoviews/plotting/bokeh/renderer.py | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/holoviews/plotting/bokeh/renderer.py b/holoviews/plotting/bokeh/renderer.py
index 9c5434158c..f6e20ed835 100644
--- a/holoviews/plotting/bokeh/renderer.py
+++ b/holoviews/plotting/bokeh/renderer.py
@@ -1,4 +1,6 @@
import uuid
+import time
+import tempfile
import numpy as np
import param
@@ -6,12 +8,13 @@
from bokeh.charts import Chart
from bokeh.document import Document
-from bokeh.embed import notebook_div
+from bokeh.embed import notebook_div, file_html
from bokeh.io import load_notebook, curdoc
from bokeh.models import (Row, Column, Plot, Model, ToolbarBox,
WidgetBox, Div, DataTable, Tabs)
from bokeh.plotting import Figure
from bokeh.resources import CDN, INLINE
+from bokeh.util.browser import view as browser_view
from ...core import Store, HoloMap
from ..comms import JupyterComm, Comm
@@ -117,6 +120,19 @@ def figure_data(self, plot, fmt='html', doc=None, **kwargs):
plot.document = doc
return div
+ def show(self, obj, browser=None, resource=CDN):
+ """
+ Renders the supplied object and displays it using specified browser.
+ """
+ plot = self.get_plot(obj)
+ plot.initialize_plot()
+ html = file_html(plot.state, resource)
+ tf = tempfile.NamedTemporaryFile('w')
+ tf.write(html)
+ tf.seek(0)
+ browser_view(tf.name, browser)
+ time.sleep(5)
+ tf.close()
def diff(self, plot, serialize=True):
"""
From 752efc263b0d9a2b7ff578fbd7289f3f3b29f498 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Fri, 17 Mar 2017 20:08:40 +0000
Subject: [PATCH 3/6] Small fix to interactive plotting with MPLRenderer
---
holoviews/plotting/mpl/renderer.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/holoviews/plotting/mpl/renderer.py b/holoviews/plotting/mpl/renderer.py
index 78c2014a06..5589006a0d 100644
--- a/holoviews/plotting/mpl/renderer.py
+++ b/holoviews/plotting/mpl/renderer.py
@@ -120,16 +120,19 @@ def show(self, obj):
Renders the supplied object and displays it using the active
GUI backend.
"""
+ if self.interactive:
+ return self.get_plot(obj)
+
from .plot import MPLPlot
MPLPlot._close_figures = False
try:
plot = self.get_plot(obj)
- plot.initialize_plot()
plt.show(plot.state)
except:
MPLPlot._close_figures = True
raise
MPLPlot._close_figures = True
+ return plot
@classmethod
From 86bee49a1876c438403ec7d06900a7ca324d7963 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Fri, 17 Mar 2017 20:18:13 +0000
Subject: [PATCH 4/6] Enable interactive plotting before creating first figure
---
holoviews/plotting/mpl/plot.py | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/holoviews/plotting/mpl/plot.py b/holoviews/plotting/mpl/plot.py
index 9003b31007..97554273b7 100644
--- a/holoviews/plotting/mpl/plot.py
+++ b/holoviews/plotting/mpl/plot.py
@@ -119,6 +119,12 @@ def __init__(self, fig=None, axis=None, **params):
if self.fig_latex:
self.fig_rcparams['text.usetex'] = True
+ if self.renderer.interactive:
+ plt.ion()
+ self._close_figures = False
+ else:
+ plt.ioff()
+
with mpl.rc_context(rc=self.fig_rcparams):
fig, axis = self._init_axis(fig, axis)
@@ -130,11 +136,6 @@ def __init__(self, fig=None, axis=None, **params):
'finalize_hooks, not both.')
self.finalize_hooks = self.final_hooks
self.handles['bbox_extra_artists'] = []
- if self.renderer.interactive:
- plt.ion()
- self._close_figures = False
- else:
- plt.ioff()
def _init_axis(self, fig, axis):
From 986cdf32e5f1ca15c45f3caddbf0dbadd9f618ed Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Sat, 18 Mar 2017 00:52:35 +0000
Subject: [PATCH 5/6] MPLRenderer.show allows passing in multiple objects
---
holoviews/plotting/mpl/renderer.py | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/holoviews/plotting/mpl/renderer.py b/holoviews/plotting/mpl/renderer.py
index 5589006a0d..e9f80cd1a8 100644
--- a/holoviews/plotting/mpl/renderer.py
+++ b/holoviews/plotting/mpl/renderer.py
@@ -121,18 +121,23 @@ def show(self, obj):
GUI backend.
"""
if self.interactive:
+ if isinstance(obj, list):
+ return [self.get_plot(o) for o in obj]
return self.get_plot(obj)
from .plot import MPLPlot
MPLPlot._close_figures = False
try:
- plot = self.get_plot(obj)
- plt.show(plot.state)
+ plots = []
+ objects = obj if isinstance(obj, list) else [obj]
+ for o in obj:
+ plots.append(self.get_plot(o))
+ plt.show()
except:
MPLPlot._close_figures = True
raise
MPLPlot._close_figures = True
- return plot
+ return plots[0] if len(plots) == 1 else plots
@classmethod
From 2d4235988a93e5990786c405a21393d40ab7d629 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Sat, 8 Apr 2017 20:43:31 +0100
Subject: [PATCH 6/6] Reverted adding BokehRenderer.show
---
holoviews/plotting/bokeh/renderer.py | 20 +-------------------
1 file changed, 1 insertion(+), 19 deletions(-)
diff --git a/holoviews/plotting/bokeh/renderer.py b/holoviews/plotting/bokeh/renderer.py
index f6e20ed835..7f0b97529b 100644
--- a/holoviews/plotting/bokeh/renderer.py
+++ b/holoviews/plotting/bokeh/renderer.py
@@ -1,6 +1,4 @@
import uuid
-import time
-import tempfile
import numpy as np
import param
@@ -8,13 +6,12 @@
from bokeh.charts import Chart
from bokeh.document import Document
-from bokeh.embed import notebook_div, file_html
+from bokeh.embed import notebook_div
from bokeh.io import load_notebook, curdoc
from bokeh.models import (Row, Column, Plot, Model, ToolbarBox,
WidgetBox, Div, DataTable, Tabs)
from bokeh.plotting import Figure
from bokeh.resources import CDN, INLINE
-from bokeh.util.browser import view as browser_view
from ...core import Store, HoloMap
from ..comms import JupyterComm, Comm
@@ -120,19 +117,6 @@ def figure_data(self, plot, fmt='html', doc=None, **kwargs):
plot.document = doc
return div
- def show(self, obj, browser=None, resource=CDN):
- """
- Renders the supplied object and displays it using specified browser.
- """
- plot = self.get_plot(obj)
- plot.initialize_plot()
- html = file_html(plot.state, resource)
- tf = tempfile.NamedTemporaryFile('w')
- tf.write(html)
- tf.seek(0)
- browser_view(tf.name, browser)
- time.sleep(5)
- tf.close()
def diff(self, plot, serialize=True):
"""
@@ -206,6 +190,4 @@ def load_nb(cls, inline=True):
"""
Loads the bokeh notebook resources.
"""
- import matplotlib.pyplot as plt
- plt.switch_backend('agg')
load_notebook(hide_banner=True, resources=INLINE if inline else CDN)