Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 00b6eb2

Browse files
committed
fetch arsenovics mpl offline function pr to edit and merge master
2 parents 5c73f4c + a8a68fb commit 00b6eb2

File tree

8 files changed

+353
-315
lines changed

8 files changed

+353
-315
lines changed

CHANGELOG.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,35 @@ This project adheres to [Semantic Versioning](http://semver.org/).
44

55
## [Unreleased]
66

7+
## [1.9.4] - 2015-01-11
8+
### Added
9+
- Offline plotting now works outside of the IPython/Juypter notebook. Here's an example:
10+
```
11+
from plotly.offline import plot
12+
from plotly.graph_objs import Scatter
13+
14+
plot([Scatter(x=[1, 2, 3], y=[3, 1, 6])])
15+
```
16+
17+
This command works entirely locally. It writes to a local HTML file with the necessary [plotly.js](https://plot.ly/javascript) code to render the graph. Your browser will open the file after you make the call.
18+
19+
The call signature is very similar to `plotly.offline.iplot` and `plotly.plotly.plot` and `plotly.plotly.iplot`, so you can basically use these commands interchangeably.
20+
21+
If you want to publish your graphs to the web, use `plotly.plotly.plot`, as in:
22+
23+
```
24+
import plotly.plotly as py
25+
from plotly.graph_objs import Scatter
26+
27+
py.plot([Scatter(x=[1, 2, 3], y=[5, 1, 6])])
28+
```
29+
30+
This will upload the graph to your online plotly account.
31+
32+
## [1.9.3] - 2015-12-08
33+
### Added
34+
- Check for `no_proxy` when determining if the streaming request should pass through a proxy in the chunked_requests submodule. Example: `no_proxy='my_stream_url'` and `http_proxy=my.proxy.ip:1234`, then `my_stream_url` will not get proxied. Previously it would.
35+
736
## [1.9.2] - 2015-11-30
837
**Bug Fix**: Previously, the "Export to plot.ly" link on
938
offline charts would export your figures to the

plotly/graph_reference/default-schema.json

Lines changed: 25 additions & 234 deletions
Large diffs are not rendered by default.

plotly/offline/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
download_plotlyjs,
88
init_notebook_mode,
99
iplot,
10+
plot,
1011
iplot_mpl,
11-
plotly_takeover,
12+
plotly_takeover
1213
)

plotly/offline/offline.py

Lines changed: 191 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import uuid
1111
import warnings
1212
from pkg_resources import resource_string
13+
import webbrowser
1314

1415
import plotly
1516
from plotly import tools, utils
@@ -70,6 +71,72 @@ def init_notebook_mode():
7071
'</script>'))
7172

7273

74+
def _plot_html(figure_or_data, show_link, link_text,
75+
validate, default_width, default_height):
76+
77+
figure = tools.return_figure_from_figure_or_data(figure_or_data, validate)
78+
79+
width = figure.get('layout', {}).get('width', default_width)
80+
height = figure.get('layout', {}).get('height', default_height)
81+
82+
try:
83+
float(width)
84+
except (ValueError, TypeError):
85+
pass
86+
else:
87+
width = str(width) + 'px'
88+
89+
try:
90+
float(width)
91+
except (ValueError, TypeError):
92+
pass
93+
else:
94+
width = str(width) + 'px'
95+
96+
plotdivid = uuid.uuid4()
97+
jdata = json.dumps(figure.get('data', []), cls=utils.PlotlyJSONEncoder)
98+
jlayout = json.dumps(figure.get('layout', {}), cls=utils.PlotlyJSONEncoder)
99+
100+
config = {}
101+
config['showLink'] = show_link
102+
config['linkText'] = link_text
103+
jconfig = json.dumps(config)
104+
105+
# TODO: The get_config 'source of truth' should
106+
# really be somewhere other than plotly.plotly
107+
plotly_platform_url = plotly.plotly.get_config().get('plotly_domain',
108+
'https://plot.ly')
109+
if (plotly_platform_url != 'https://plot.ly' and
110+
link_text == 'Export to plot.ly'):
111+
112+
link_domain = plotly_platform_url\
113+
.replace('https://', '')\
114+
.replace('http://', '')
115+
link_text = link_text.replace('plot.ly', link_domain)
116+
117+
script = 'Plotly.newPlot("{id}", {data}, {layout}, {config})'.format(
118+
id=plotdivid,
119+
data=jdata,
120+
layout=jlayout,
121+
config=jconfig)
122+
123+
plotly_html_div = (
124+
''
125+
'<div id="{id}" style="height: {height}; width: {width};" '
126+
'class="plotly-graph-div">'
127+
'</div>'
128+
'<script type="text/javascript">'
129+
'window.PLOTLYENV=window.PLOTLYENV || {{}};'
130+
'window.PLOTLYENV.BASE_URL="' + plotly_platform_url + '";'
131+
'{script}'
132+
'</script>'
133+
'').format(
134+
id=plotdivid, script=script,
135+
height=height, width=width)
136+
137+
return plotly_html_div, plotdivid, width, height
138+
139+
73140
def iplot(figure_or_data, show_link=True, link_text='Export to plot.ly',
74141
validate=True):
75142
"""
@@ -116,82 +183,145 @@ def iplot(figure_or_data, show_link=True, link_text='Export to plot.ly',
116183
raise ImportError('`iplot` can only run inside an IPython Notebook.')
117184

118185
from IPython.display import HTML, display
119-
figure = tools.return_figure_from_figure_or_data(figure_or_data, validate)
120186

121-
width = figure.get('layout', {}).get('width', '100%')
122-
height = figure.get('layout', {}).get('height', 525)
123-
try:
124-
float(width)
125-
except (ValueError, TypeError):
126-
pass
127-
else:
128-
width = str(width) + 'px'
187+
plot_html, plotdivid, width, height = _plot_html(
188+
figure_or_data, show_link, link_text, validate,
189+
'100%', 525)
129190

130-
try:
131-
float(width)
132-
except (ValueError, TypeError):
133-
pass
134-
else:
135-
width = str(width) + 'px'
191+
display(HTML(plot_html))
136192

137-
plotdivid = uuid.uuid4()
138-
jdata = json.dumps(figure.get('data', []), cls=utils.PlotlyJSONEncoder)
139-
jlayout = json.dumps(figure.get('layout', {}), cls=utils.PlotlyJSONEncoder)
140193

141-
config = {}
142-
config['showLink'] = show_link
143-
config['linkText'] = link_text
144-
jconfig = json.dumps(config)
194+
def plot(figure_or_data,
195+
show_link=True, link_text='Export to plot.ly',
196+
validate=True, output_type='file',
197+
include_plotlyjs=True,
198+
filename='temp-plot.html',
199+
auto_open=True):
200+
""" Create a plotly graph locally as an HTML document or string.
145201
146-
# TODO: The get_config 'source of truth' should
147-
# really be somewhere other than plotly.plotly
148-
plotly_platform_url = plotly.plotly.get_config().get('plotly_domain',
149-
'https://plot.ly')
150-
if (plotly_platform_url != 'https://plot.ly' and
151-
link_text == 'Export to plot.ly'):
202+
Example:
203+
```
204+
from plotly.offline import plot
205+
import plotly.graph_objs as go
152206
153-
link_domain = plotly_platform_url\
154-
.replace('https://', '')\
155-
.replace('http://', '')
156-
link_text = link_text.replace('plot.ly', link_domain)
207+
plot([
208+
go.Scatter(x=[1, 2, 3], y=[3, 2 6])
209+
], filename='my-graph.html')
210+
```
211+
More examples below.
157212
158-
display(HTML(
159-
'<script type="text/javascript">'
160-
'window.PLOTLYENV=window.PLOTLYENV || {};'
161-
'window.PLOTLYENV.BASE_URL="' + plotly_platform_url + '";'
162-
'</script>'
163-
))
164-
165-
script = '\n'.join([
166-
'Plotly.plot("{id}", {data}, {layout}, {config}).then(function() {{',
167-
' $(".{id}.loading").remove();',
168-
'}})'
169-
]).format(id=plotdivid,
170-
data=jdata,
171-
layout=jlayout,
172-
config=jconfig)
173-
174-
display(HTML(''
175-
'<div class="{id} loading" style="color: rgb(50,50,50);">'
176-
'Drawing...</div>'
177-
'<div id="{id}" style="height: {height}; width: {width};" '
178-
'class="plotly-graph-div">'
179-
'</div>'
180-
'<script type="text/javascript">'
181-
'{script}'
182-
'</script>'
183-
''.format(id=plotdivid, script=script,
184-
height=height, width=width)))
213+
figure_or_data -- a plotly.graph_objs.Figure or plotly.graph_objs.Data or
214+
dict or list that describes a Plotly graph.
215+
See https://plot.ly/python/ for examples of
216+
graph descriptions.
217+
218+
Keyword arguments:
219+
show_link (default=True) -- display a link in the bottom-right corner of
220+
of the chart that will export the chart to Plotly Cloud or
221+
Plotly Enterprise
222+
link_text (default='Export to plot.ly') -- the text of export link
223+
validate (default=True) -- validate that all of the keys in the figure
224+
are valid? omit if your version of plotly.js has become outdated
225+
with your version of graph_reference.json or if you need to include
226+
extra, unnecessary keys in your figure.
227+
output_type ('file' | 'div' - default 'file') -- if 'file', then
228+
the graph is saved as a standalone HTML file and `plot`
229+
returns None.
230+
If 'div', then `plot` returns a string that just contains the
231+
HTML <div> that contains the graph and the script to generate the
232+
graph.
233+
Use 'file' if you want to save and view a single graph at a time
234+
in a standalone HTML file.
235+
Use 'div' if you are embedding these graphs in an HTML file with
236+
other graphs or HTML markup, like a HTML report or an website.
237+
include_plotlyjs (default=True) -- If True, include the plotly.js
238+
source code in the output file or string.
239+
Set as False if your HTML file already contains a copy of the plotly.js
240+
library.
241+
filename (default='temp-plot.html') -- The local filename to save the
242+
outputted chart to. If the filename already exists, it will be
243+
overwritten. This argument only applies if `output_type` is 'file'.
244+
auto_open (default=True) -- If True, open the saved file in a
245+
web browser after saving.
246+
This argument only applies if `output_type` is 'file'.
247+
"""
248+
if output_type not in ['div', 'file']:
249+
raise ValueError(
250+
"`output_type` argument must be 'div' or 'file'. "
251+
"You supplied `" + output_type + "``")
252+
if not filename.endswith('.html') and output_type == 'file':
253+
warnings.warn(
254+
"Your filename `" + filename + "` didn't end with .html. "
255+
"Adding .html to the end of your file.")
256+
filename += '.html'
257+
258+
plot_html, plotdivid, width, height = _plot_html(
259+
figure_or_data, show_link, link_text, validate,
260+
'100%', '100%')
261+
262+
figure = tools.return_figure_from_figure_or_data(figure_or_data, validate)
263+
264+
resize_script = ''
265+
if width == '100%' or height == '100%':
266+
resize_script = (
267+
''
268+
'<script type="text/javascript">'
269+
'window.removeEventListener("resize");'
270+
'window.addEventListener("resize", function(){{'
271+
'Plotly.Plots.resize(document.getElementById("{id}"));}});'
272+
'</script>'
273+
).format(id=plotdivid)
274+
275+
if output_type == 'file':
276+
with open(filename, 'w') as f:
277+
if include_plotlyjs:
278+
plotly_js_script = ''.join([
279+
'<script type="text/javascript">',
280+
get_plotlyjs(),
281+
'</script>',
282+
])
283+
else:
284+
plotly_js_script = ''
285+
286+
f.write(''.join([
287+
'<html>',
288+
'<head><meta charset="utf-8" /></head>',
289+
'<body>',
290+
plotly_js_script,
291+
plot_html,
292+
resize_script,
293+
'</body>',
294+
'</html>']))
295+
296+
url = 'file://' + os.path.abspath(filename)
297+
if auto_open:
298+
webbrowser.open(url)
299+
300+
return url
301+
302+
elif output_type == 'div':
303+
if include_plotlyjs:
304+
return ''.join([
305+
'<div>',
306+
'<script type="text/javascript">',
307+
get_plotlyjs(),
308+
'</script>',
309+
plot_html,
310+
'</div>'
311+
])
312+
else:
313+
return plot_html
185314

186315

187316
def iplot_mpl(mpl_fig,mpl_to_plotly_kw={},iplot_kw={}):
188317
'''
189-
Convert a matplotlib figure to plotly dictionary plot inside an
318+
Convert a matplotlib figure to plotly dictionary plot inside an
190319
IPython notebook without connecting to an external server.
191320
'''
192321
plotly_plot = tools.mpl_to_plotly(mpl_fig,**mpl_to_plotly_kw)
193322
return iplot(plotly_plot,**iplot_kw)
194323

324+
195325
def plotly_takeover(**kwargs):
196326
'''
197327
Enable the automatic display of figures in the IPython Notebook.
@@ -200,7 +330,7 @@ def plotly_takeover(**kwargs):
200330
or `%matplotlib inline`. This works by adding an HTML formatter
201331
for Figure objects; the existing SVG/PNG formatters will remain
202332
enabled.
203-
333+
204334
(idea taken from `mpld3._display.enable_notebook`)
205335
'''
206336
if __PLOTLY_OFFLINE_INITIALIZED != True:
@@ -210,10 +340,3 @@ def plotly_takeover(**kwargs):
210340
formatter.for_type(matplotlib.figure.Figure,
211341
lambda fig, kwds=kwargs: iplot_mpl(fig, **kwds))
212342

213-
214-
215-
def plot():
216-
""" Configured to work with localhost Plotly graph viewer
217-
"""
218-
raise NotImplementedError
219-

0 commit comments

Comments
 (0)