Skip to content

Commit 31ca2c7

Browse files
committed
Merge pull request #386 from plotly/mpl_offline
mpl_to_plotly offline
2 parents a8a68fb + 7f6298a commit 31ca2c7

File tree

5 files changed

+249
-6
lines changed

5 files changed

+249
-6
lines changed

plotly/graph_reference/default-schema.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -426,12 +426,14 @@
426426
]
427427
},
428428
"dragmode": {
429-
"description": "Determines the mode of drag interactions.",
429+
"description": "Determines the mode of drag interactions. *select* and *lasso* apply only to scatter traces with markers or text. *orbit* and *turntable* apply only to 3D scenes.",
430430
"role": "info",
431431
"valType": "enumerated",
432432
"values": [
433433
"zoom",
434434
"pan",
435+
"select",
436+
"lasso",
435437
"orbit",
436438
"turntable"
437439
]

plotly/offline/__init__.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
"""
66
from . offline import (
77
download_plotlyjs,
8+
enable_mpl_offline,
89
init_notebook_mode,
910
iplot,
10-
plot
11+
iplot_mpl,
12+
plot,
13+
plot_mpl
1114
)

plotly/offline/offline.py

+175-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,19 @@
1717
from plotly.exceptions import PlotlyError
1818

1919

20+
try:
21+
import IPython
22+
_ipython_imported = True
23+
except ImportError:
24+
_ipython_imported = False
25+
26+
try:
27+
import matplotlib
28+
_matplotlib_imported = True
29+
except ImportError:
30+
_matplotlib_imported = False
31+
32+
2033
__PLOTLY_OFFLINE_INITIALIZED = False
2134

2235

@@ -191,9 +204,7 @@ def plot(figure_or_data,
191204
from plotly.offline import plot
192205
import plotly.graph_objs as go
193206
194-
plot([
195-
go.Scatter(x=[1, 2, 3], y=[3, 2 6])
196-
], filename='my-graph.html')
207+
plot([go.Scatter(x=[1, 2, 3], y=[3, 2, 6])], filename='my-graph.html')
197208
```
198209
More examples below.
199210
@@ -298,3 +309,164 @@ def plot(figure_or_data,
298309
])
299310
else:
300311
return plot_html
312+
313+
314+
def plot_mpl(mpl_fig, resize=False, strip_style=False,
315+
verbose=False, show_link=True, link_text='Export to plot.ly',
316+
validate=True, output_type='file', include_plotlyjs=True,
317+
filename='temp-plot.html', auto_open=True):
318+
"""
319+
Convert a matplotlib figure to a Plotly graph stored locally as HTML.
320+
321+
For more information on converting matplotlib visualizations to plotly
322+
graphs, call help(plotly.tools.mpl_to_plotly)
323+
324+
For more information on creating plotly charts locally as an HTML document
325+
or string, call help(plotly.offline.plot)
326+
327+
mpl_fig -- a matplotlib figure object to convert to a plotly graph
328+
329+
Keyword arguments:
330+
resize (default=False) -- allow plotly to choose the figure size.
331+
strip_style (default=False) -- allow plotly to choose style options.
332+
verbose (default=False) -- print message.
333+
show_link (default=True) -- display a link in the bottom-right corner of
334+
of the chart that will export the chart to Plotly Cloud or
335+
Plotly Enterprise
336+
link_text (default='Export to plot.ly') -- the text of export link
337+
validate (default=True) -- validate that all of the keys in the figure
338+
are valid? omit if your version of plotly.js has become outdated
339+
with your version of graph_reference.json or if you need to include
340+
extra, unnecessary keys in your figure.
341+
output_type ('file' | 'div' - default 'file') -- if 'file', then
342+
the graph is saved as a standalone HTML file and `plot`
343+
returns None.
344+
If 'div', then `plot` returns a string that just contains the
345+
HTML <div> that contains the graph and the script to generate the
346+
graph.
347+
Use 'file' if you want to save and view a single graph at a time
348+
in a standalone HTML file.
349+
Use 'div' if you are embedding these graphs in an HTML file with
350+
other graphs or HTML markup, like a HTML report or an website.
351+
include_plotlyjs (default=True) -- If True, include the plotly.js
352+
source code in the output file or string.
353+
Set as False if your HTML file already contains a copy of the plotly.js
354+
library.
355+
filename (default='temp-plot.html') -- The local filename to save the
356+
outputted chart to. If the filename already exists, it will be
357+
overwritten. This argument only applies if `output_type` is 'file'.
358+
auto_open (default=True) -- If True, open the saved file in a
359+
web browser after saving.
360+
This argument only applies if `output_type` is 'file'.
361+
362+
Example:
363+
```
364+
from plotly.offline import init_notebook_mode, plot_mpl
365+
import matplotlib.pyplot as plt
366+
367+
init_notebook_mode()
368+
369+
fig = plt.figure()
370+
x = [10, 15, 20, 25, 30]
371+
y = [100, 250, 200, 150, 300]
372+
plt.plot(x, y, "o")
373+
374+
plot_mpl(fig)
375+
```
376+
"""
377+
plotly_plot = tools.mpl_to_plotly(mpl_fig, resize, strip_style, verbose)
378+
return plot(plotly_plot, show_link, link_text, validate, output_type,
379+
include_plotlyjs, filename, auto_open)
380+
381+
382+
def iplot_mpl(mpl_fig, resize=False, strip_style=False,
383+
verbose=False, show_link=True,
384+
link_text='Export to plot.ly', validate=True):
385+
"""
386+
Convert a matplotlib figure to a plotly graph and plot inside an IPython
387+
notebook without connecting to an external server.
388+
389+
To save the chart to Plotly Cloud or Plotly Enterprise, use
390+
`plotly.plotly.plot_mpl`.
391+
392+
For more information on converting matplotlib visualizations to plotly
393+
graphs call `help(plotly.tools.mpl_to_plotly)`
394+
395+
For more information on plotting plotly charts offline in an Ipython
396+
notebook call `help(plotly.offline.iplot)`
397+
398+
mpl_fig -- a matplotlib.figure to convert to a plotly graph
399+
400+
Keyword arguments:
401+
resize (default=False) -- allow plotly to choose the figure size.
402+
strip_style (default=False) -- allow plotly to choose style options.
403+
verbose (default=False) -- print message.
404+
show_link (default=True) -- display a link in the bottom-right corner of
405+
of the chart that will export the chart to Plotly Cloud or
406+
Plotly Enterprise
407+
show_link (default=True) -- display a link in the bottom-right corner of
408+
of the chart that will export the chart to
409+
Plotly Cloud or Plotly Enterprise
410+
link_text (default='Export to plot.ly') -- the text of export link
411+
validate (default=True) -- validate that all of the keys in the figure
412+
are valid? omit if your version of plotly.js
413+
has become outdated with your version of
414+
graph_reference.json or if you need to include
415+
extra, unnecessary keys in your figure.
416+
417+
Example:
418+
```
419+
from plotly.offline import init_notebook_mode, iplot_mpl
420+
import matplotlib.pyplot as plt
421+
422+
init_notebook_mode()
423+
424+
fig = plt.figure()
425+
x = [10, 15, 20, 25, 30]
426+
y = [100, 250, 200, 150, 300]
427+
plt.plot(x, y, "o")
428+
429+
iplot_mpl(fig)
430+
```
431+
"""
432+
plotly_plot = tools.mpl_to_plotly(mpl_fig, resize, strip_style, verbose)
433+
return iplot(plotly_plot, show_link, link_text, validate)
434+
435+
436+
def enable_mpl_offline(resize=False, strip_style=False,
437+
verbose=False, show_link=True,
438+
link_text='Export to plot.ly', validate=True):
439+
"""
440+
Convert mpl plots to locally hosted HTML documents.
441+
442+
This function should be used with the inline matplotlib backend
443+
that ships with IPython that can be enabled with `%pylab inline`
444+
or `%matplotlib inline`. This works by adding an HTML formatter
445+
for Figure objects; the existing SVG/PNG formatters will remain
446+
enabled.
447+
448+
(idea taken from `mpld3._display.enable_notebook`)
449+
450+
Example:
451+
```
452+
from plotly.offline import init_notebook_mode, plotly_takeover
453+
import matplotlib.pyplot as plt
454+
455+
init_notebook_mode()
456+
enable_mpl_offline()
457+
458+
fig = plt.figure()
459+
x = [10, 15, 20, 25, 30]
460+
y = [100, 250, 200, 150, 300]
461+
plt.plot(x, y, "o")
462+
fig
463+
```
464+
"""
465+
if not __PLOTLY_OFFLINE_INITIALIZED:
466+
init_notebook_mode()
467+
ip = IPython.core.getipython.get_ipython()
468+
formatter = ip.display_formatter.formatters['text/html']
469+
formatter.for_type(matplotlib.figure.Figure,
470+
lambda fig: iplot_mpl(fig, resize, strip_style, verbose,
471+
show_link, link_text, validate))
472+

plotly/tests/test_optional/test_offline/test_offline.py

+66
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,25 @@
55
from __future__ import absolute_import
66

77
from nose.tools import raises
8+
from nose.plugins.attrib import attr
9+
810
from unittest import TestCase
11+
import json
912

1013
import plotly
1114

15+
# TODO: matplotlib-build-wip
16+
from plotly.tools import _matplotlylib_imported
17+
18+
if _matplotlylib_imported:
19+
import matplotlib
20+
# Force matplotlib to not use any Xwindows backend.
21+
matplotlib.use('Agg')
22+
import matplotlib.pyplot as plt
23+
24+
25+
PLOTLYJS = plotly.offline.offline.get_plotlyjs()
26+
1227

1328
class PlotlyOfflineTestCase(TestCase):
1429
def setUp(self):
@@ -22,3 +37,54 @@ def test_iplot_works_after_you_call_init_notebook_mode(self):
2237
plotly.tools._ipython_imported = True
2338
plotly.offline.init_notebook_mode()
2439
plotly.offline.iplot([{}])
40+
41+
@attr('matplotlib')
42+
def test_iplot_mpl_works_after_you_call_init_notebook_mode(self):
43+
# Generate matplotlib plot for tests
44+
fig = plt.figure()
45+
46+
x = [10, 20, 30]
47+
y = [100, 200, 300]
48+
plt.plot(x, y, "o")
49+
50+
plotly.tools._ipython_imported = True
51+
plotly.offline.init_notebook_mode()
52+
plotly.offline.iplot_mpl(fig)
53+
54+
55+
class PlotlyOfflineMPLTestCase(TestCase):
56+
def setUp(self):
57+
pass
58+
59+
def _read_html(self, file_url):
60+
""" Read and return the HTML contents from a file_url in the
61+
form e.g. file:///Users/chriddyp/Repos/plotly.py/plotly-temp.html
62+
"""
63+
with open(file_url.replace('file://', '').replace(' ', '')) as f:
64+
return f.read()
65+
66+
@attr('matplotlib')
67+
def test_default_mpl_plot_generates_expected_html(self):
68+
# Generate matplotlib plot for tests
69+
fig = plt.figure()
70+
71+
x = [10, 20, 30]
72+
y = [100, 200, 300]
73+
plt.plot(x, y, "o")
74+
75+
figure = plotly.tools.mpl_to_plotly(fig)
76+
data = figure['data']
77+
layout = figure['layout']
78+
data_json = json.dumps(data, cls=plotly.utils.PlotlyJSONEncoder)
79+
layout_json = json.dumps(layout, cls=plotly.utils.PlotlyJSONEncoder)
80+
html = self._read_html(plotly.offline.plot_mpl(fig))
81+
82+
# just make sure a few of the parts are in here
83+
# like PlotlyOfflineTestCase(TestCase) in test_core
84+
self.assertTrue('Plotly.newPlot' in html) # plot command is in there
85+
self.assertTrue(data_json in html) # data is in there
86+
self.assertTrue(layout_json in html) # layout is in there too
87+
self.assertTrue(PLOTLYJS in html) # and the source code
88+
# and it's an <html> doc
89+
self.assertTrue(html.startswith('<html>') and html.endswith('</html>'))
90+

plotly/version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '1.9.4'
1+
__version__ = '1.9.5'

0 commit comments

Comments
 (0)