diff --git a/plotly/offline/__init__.py b/plotly/offline/__init__.py index df04b62cc01..30da5a36c18 100644 --- a/plotly/offline/__init__.py +++ b/plotly/offline/__init__.py @@ -6,5 +6,6 @@ from . offline import ( download_plotlyjs, init_notebook_mode, - iplot + iplot, + plot ) diff --git a/plotly/offline/offline.py b/plotly/offline/offline.py index cb9e3762bed..694202127ef 100644 --- a/plotly/offline/offline.py +++ b/plotly/offline/offline.py @@ -10,6 +10,7 @@ import uuid import warnings from pkg_resources import resource_string +import webbrowser import plotly from plotly import tools, utils @@ -57,6 +58,72 @@ def init_notebook_mode(): '')) +def _plot_html(figure_or_data, show_link, link_text, + validate, default_width, default_height): + + figure = tools.return_figure_from_figure_or_data(figure_or_data, validate) + + width = figure.get('layout', {}).get('width', default_width) + height = figure.get('layout', {}).get('height', default_height) + + try: + float(width) + except (ValueError, TypeError): + pass + else: + width = str(width) + 'px' + + try: + float(width) + except (ValueError, TypeError): + pass + else: + width = str(width) + 'px' + + plotdivid = uuid.uuid4() + jdata = json.dumps(figure.get('data', []), cls=utils.PlotlyJSONEncoder) + jlayout = json.dumps(figure.get('layout', {}), cls=utils.PlotlyJSONEncoder) + + config = {} + config['showLink'] = show_link + config['linkText'] = link_text + jconfig = json.dumps(config) + + # TODO: The get_config 'source of truth' should + # really be somewhere other than plotly.plotly + plotly_platform_url = plotly.plotly.get_config().get('plotly_domain', + 'https://plot.ly') + if (plotly_platform_url != 'https://plot.ly' and + link_text == 'Export to plot.ly'): + + link_domain = plotly_platform_url\ + .replace('https://', '')\ + .replace('http://', '') + link_text = link_text.replace('plot.ly', link_domain) + + script = 'Plotly.plot("{id}", {data}, {layout}, {config})'.format( + id=plotdivid, + data=jdata, + layout=jlayout, + config=jconfig) + + plotly_html_div = ( + '' + '
' + '
' + '' + '').format( + id=plotdivid, script=script, + height=height, width=width) + + return plotly_html_div, plotdivid, width, height + + def iplot(figure_or_data, show_link=True, link_text='Export to plot.ly', validate=True): """ @@ -103,76 +170,118 @@ def iplot(figure_or_data, show_link=True, link_text='Export to plot.ly', raise ImportError('`iplot` can only run inside an IPython Notebook.') from IPython.display import HTML, display - figure = tools.return_figure_from_figure_or_data(figure_or_data, validate) - width = figure.get('layout', {}).get('width', '100%') - height = figure.get('layout', {}).get('height', 525) - try: - float(width) - except (ValueError, TypeError): - pass - else: - width = str(width) + 'px' + display(HTML(_plot_html( + figure_or_data, show_link, link_text, validate, + '100%', 525))) - try: - float(width) - except (ValueError, TypeError): - pass - else: - width = str(width) + 'px' - plotdivid = uuid.uuid4() - jdata = json.dumps(figure.get('data', []), cls=utils.PlotlyJSONEncoder) - jlayout = json.dumps(figure.get('layout', {}), cls=utils.PlotlyJSONEncoder) +def plot(figure_or_data, + show_link=True, link_text='Export to plot.ly', + validate=True, output_type='file', + include_plotlyjs=True, + filename='temp-plot.html', + auto_open=True): + """ Create a plotly graph locally as an HTML document or string. - config = {} - config['showLink'] = show_link - config['linkText'] = link_text - jconfig = json.dumps(config) + Example: + ``` + from plotly.offline import plot + import plotly.graph_objs as go - # TODO: The get_config 'source of truth' should - # really be somewhere other than plotly.plotly - plotly_platform_url = plotly.plotly.get_config().get('plotly_domain', - 'https://plot.ly') - if (plotly_platform_url != 'https://plot.ly' and - link_text == 'Export to plot.ly'): + plot([ + go.Scatter(x=[1, 2, 3], y=[3, 2 6]) + ], filename='my-graph.html') + ``` + More examples below. - link_domain = plotly_platform_url\ - .replace('https://', '')\ - .replace('http://', '') - link_text = link_text.replace('plot.ly', link_domain) + figure_or_data -- a plotly.graph_objs.Figure or plotly.graph_objs.Data or + dict or list that describes a Plotly graph. + See https://plot.ly/python/ for examples of + graph descriptions. - display(HTML( - '' - )) - - script = '\n'.join([ - 'Plotly.plot("{id}", {data}, {layout}, {config}).then(function() {{', - ' $(".{id}.loading").remove();', - '}})' - ]).format(id=plotdivid, - data=jdata, - layout=jlayout, - config=jconfig) - - display(HTML('' - '
' - 'Drawing...
' - '
' - '
' - '' - ''.format(id=plotdivid, script=script, - height=height, width=width))) - - -def plot(): - """ Configured to work with localhost Plotly graph viewer + Keyword arguments: + show_link (default=True) -- display a link in the bottom-right corner of + of the chart that will export the chart to Plotly Cloud or + Plotly Enterprise + link_text (default='Export to plot.ly') -- the text of export link + validate (default=True) -- validate that all of the keys in the figure + are valid? omit if your version of plotly.js has become outdated + with your version of graph_reference.json or if you need to include + extra, unnecessary keys in your figure. + output_type ('file' | 'div' - default 'file') -- if 'file', then + the graph is saved as a standalone HTML file and `plot` + returns None. + If 'div', then `plot` returns a string that just contains the + HTML
that contains the graph and the script to generate the + graph. + Use 'file' if you want to save and view a single graph at a time + in a standalone HTML file. + Use 'div' if you are embedding these graphs in an HTML file with + other graphs or HTML markup, like a HTML report or an website. + include_plotlyjs (default=True) -- If True, include the plotly.js + source code in the output file or string. + Set as False if your HTML file already contains a copy of the plotly.js + library. + filename (default='temp-plot.html') -- The local filename to save the + outputted chart to. If the filename already exists, it will be + overwritten. This argument only applies if `output_type` is 'file'. + auto_open (default=True) -- If True, open the saved file in a + web browser after saving. + This argument only applies if `output_type` is 'file'. """ - raise NotImplementedError + plot_html, plotdivid, width, height = _plot_html( + figure_or_data, show_link, link_text, validate, + '100%', '100%') + + figure = tools.return_figure_from_figure_or_data(figure_or_data, validate) + + resize_script = '' + if width == '100%' or height == '100%': + resize_script = ( + '' + '' + ).format(id=plotdivid) + + if output_type == 'file': + filename = 'plotly-temp.html' + with open(filename, 'w') as f: + if include_plotlyjs: + plotly_js_script = ''.join([ + '', + ]) + else: + plotly_js_script = '' + + f.write(''.join([ + '', + '', + '', + plotly_js_script, + plot_html, + resize_script, + '', + ''])) + + if auto_open: + webbrowser.open('file://' + os.path.abspath(filename)) + elif output_type == 'div': + if include_plotlyjs: + return ''.join([ + '
', + '', + plot_html, + '
' + ]) + else: + return plot_html