From a0771341f08024d81677b3440b47fcb8da6fda1c Mon Sep 17 00:00:00 2001 From: chriddyp Date: Tue, 29 Dec 2015 23:46:35 -0500 Subject: [PATCH 01/10] :fireworks: offline `plot` command --- plotly/offline/__init__.py | 3 +- plotly/offline/offline.py | 237 +++++++++++++++++++++++++++---------- 2 files changed, 175 insertions(+), 65 deletions(-) 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 From 539415648f7c806f03fb0a184c01f300a0eb1561 Mon Sep 17 00:00:00 2001 From: chriddyp Date: Fri, 8 Jan 2016 14:18:51 -0500 Subject: [PATCH 02/10] be safe with newPlot calls --- plotly/offline/offline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plotly/offline/offline.py b/plotly/offline/offline.py index 694202127ef..0c9b4d1022e 100644 --- a/plotly/offline/offline.py +++ b/plotly/offline/offline.py @@ -101,7 +101,7 @@ def _plot_html(figure_or_data, show_link, link_text, .replace('http://', '') link_text = link_text.replace('plot.ly', link_domain) - script = 'Plotly.plot("{id}", {data}, {layout}, {config})'.format( + script = 'Plotly.newPlot("{id}", {data}, {layout}, {config})'.format( id=plotdivid, data=jdata, layout=jlayout, From a68a72af4f72c75517a60d400a2cd51905daafc0 Mon Sep 17 00:00:00 2001 From: chriddyp Date: Fri, 8 Jan 2016 14:19:00 -0500 Subject: [PATCH 03/10] input argument checking --- plotly/offline/offline.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/plotly/offline/offline.py b/plotly/offline/offline.py index 0c9b4d1022e..ad5f6393512 100644 --- a/plotly/offline/offline.py +++ b/plotly/offline/offline.py @@ -230,6 +230,16 @@ def plot(figure_or_data, web browser after saving. This argument only applies if `output_type` is 'file'. """ + if output_type not in ['div', 'file']: + raise ValueError( + "`output_type` argument must be 'div' or 'file'. " + "You supplied `" + output_type + "``") + if not filename.endswith('.html') and output_type == 'file': + warnings.warn( + "Your filename `" + filename + "` didn't end with .html. " + "Adding .html to the end of your file.") + filename += '.html' + plot_html, plotdivid, width, height = _plot_html( figure_or_data, show_link, link_text, validate, '100%', '100%') From 6e9bdb3c101449e01ed8f2dc55dc7f691cf9be9d Mon Sep 17 00:00:00 2001 From: chriddyp Date: Fri, 8 Jan 2016 14:19:09 -0500 Subject: [PATCH 04/10] :boom: remove console.log --- plotly/offline/offline.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plotly/offline/offline.py b/plotly/offline/offline.py index ad5f6393512..55aaeb5fa70 100644 --- a/plotly/offline/offline.py +++ b/plotly/offline/offline.py @@ -253,7 +253,6 @@ def plot(figure_or_data, '' ).format(id=plotdivid) From 754a1be6c4540458cdebfdad6d2a3e7ca4c6180b Mon Sep 17 00:00:00 2001 From: chriddyp Date: Fri, 8 Jan 2016 14:19:23 -0500 Subject: [PATCH 05/10] return a (local file) url, just like py.plot --- plotly/offline/offline.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plotly/offline/offline.py b/plotly/offline/offline.py index 55aaeb5fa70..528e759dc52 100644 --- a/plotly/offline/offline.py +++ b/plotly/offline/offline.py @@ -279,8 +279,11 @@ def plot(figure_or_data, '', ''])) + url = 'file://' + os.path.abspath(filename) if auto_open: - webbrowser.open('file://' + os.path.abspath(filename)) + webbrowser.open(url) + + return url elif output_type == 'div': if include_plotlyjs: From cb6e87f34c60981ac1ac0f4b6c5d4495538fcb55 Mon Sep 17 00:00:00 2001 From: chriddyp Date: Fri, 8 Jan 2016 14:19:28 -0500 Subject: [PATCH 06/10] tests --- .../test_core/test_offline/test_offline.py | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 plotly/tests/test_core/test_offline/test_offline.py diff --git a/plotly/tests/test_core/test_offline/test_offline.py b/plotly/tests/test_core/test_offline/test_offline.py new file mode 100644 index 00000000000..34684322e92 --- /dev/null +++ b/plotly/tests/test_core/test_offline/test_offline.py @@ -0,0 +1,80 @@ +""" +test__offline + +""" +from __future__ import absolute_import + +from nose.tools import raises +from unittest import TestCase +import json + +import plotly + +fig = { + 'data': [ + plotly.graph_objs.Scatter(x=[1, 2, 3], y=[10, 20, 30]) + ], + 'layout': plotly.graph_objs.Layout( + title='offline plot' + ) +} + +PLOTLYJS = plotly.offline.offline.get_plotlyjs() + +class PlotlyOfflineTestCase(TestCase): + def setUp(self): + pass + + def _read_html(self, file_url): + """ Read and return the HTML contents from a file_url + in the form e.g. file:///Users/chriddyp/Repos/plotly.py/plotly-temp.html + """ + with open(file_url.replace('file://', '').replace(' ', '')) as f: + return f.read() + + def test_default_plot_generates_expected_html(self): + data_json = json.dumps(fig['data'], cls=plotly.utils.PlotlyJSONEncoder) + layout_json = json.dumps( + fig['layout'], + cls=plotly.utils.PlotlyJSONEncoder) + + html = self._read_html(plotly.offline.plot(fig)) + + # I don't really want to test the entire script output, so + # instead just make sure a few of the parts are in here? + self.assertTrue('Plotly.newPlot' in html) # plot command is in there + self.assertTrue(data_json in html) # data is in there + self.assertTrue(layout_json in html) # so is layout + self.assertTrue(PLOTLYJS in html) # and the source code + # and it's an doc + self.assertTrue(html.startswith('') and html.endswith('')) + + def test_including_plotlyjs(self): + html = self._read_html(plotly.offline.plot(fig, include_plotlyjs=False)) + self.assertTrue(PLOTLYJS not in html) + + def test_div_output(self): + html = plotly.offline.plot(fig, output_type='div') + + self.assertTrue('' not in html and '' not in html) + self.assertTrue(html.startswith('
') and html.endswith('
')) + + def test_autoresizing(self): + resize_code_strings = [ + 'window.addEventListener("resize", ', + 'Plotly.Plots.resize(' + ] + # If width or height wasn't specified, then we add a window resizer + html = self._read_html(plotly.offline.plot(fig)) + for resize_code_string in resize_code_strings: + self.assertTrue(resize_code_string in html) + + # If width or height was specified, then we don't resize + html = plotly.offline.plot({ + 'data': fig['data'], + 'layout': { + 'width': 500, 'height': 500 + } + }) + for resize_code_string in resize_code_strings: + self.assertTrue(resize_code_string not in html) From 3af50393ed5325c105cf20183cd24da82f232ee6 Mon Sep 17 00:00:00 2001 From: chriddyp Date: Fri, 8 Jan 2016 14:26:11 -0500 Subject: [PATCH 07/10] update plot with new _plot_html output arguments --- plotly/offline/offline.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plotly/offline/offline.py b/plotly/offline/offline.py index 528e759dc52..3d79cff2e88 100644 --- a/plotly/offline/offline.py +++ b/plotly/offline/offline.py @@ -171,9 +171,11 @@ def iplot(figure_or_data, show_link=True, link_text='Export to plot.ly', from IPython.display import HTML, display - display(HTML(_plot_html( + plot_html, plotdivid, width, height = _plot_html( figure_or_data, show_link, link_text, validate, - '100%', 525))) + '100%', 525) + + display(HTML(plot_html)) def plot(figure_or_data, From 65f264551b885ab4705fc5f58ecf90580607afa1 Mon Sep 17 00:00:00 2001 From: chriddyp Date: Fri, 8 Jan 2016 14:26:22 -0500 Subject: [PATCH 08/10] filename as an input argument --- plotly/offline/offline.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plotly/offline/offline.py b/plotly/offline/offline.py index 3d79cff2e88..4944b4e7f17 100644 --- a/plotly/offline/offline.py +++ b/plotly/offline/offline.py @@ -260,7 +260,6 @@ def plot(figure_or_data, ).format(id=plotdivid) if output_type == 'file': - filename = 'plotly-temp.html' with open(filename, 'w') as f: if include_plotlyjs: plotly_js_script = ''.join([ From 1b083eb381f433caf8261a376b0265739bae904f Mon Sep 17 00:00:00 2001 From: chriddyp Date: Mon, 11 Jan 2016 09:58:09 -0500 Subject: [PATCH 09/10] update graph reference --- plotly/graph_reference/default-schema.json | 257 ++------------------- 1 file changed, 24 insertions(+), 233 deletions(-) diff --git a/plotly/graph_reference/default-schema.json b/plotly/graph_reference/default-schema.json index d9285f84ec6..f238807bf48 100644 --- a/plotly/graph_reference/default-schema.json +++ b/plotly/graph_reference/default-schema.json @@ -445,7 +445,7 @@ "description": "Sets the global font. Note that fonts used in traces and other layout components inherit from the global font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", - "dflt": "\"Open sans\", verdana, arial, sans-serif", + "dflt": "\"Open Sans\", verdana, arial, sans-serif", "noBlank": true, "role": "style", "strict": true, @@ -6424,17 +6424,6 @@ "role": "info", "valType": "number" }, - "zsmooth": { - "description": "Picks a smoothing algorithm use to smooth `z` data.", - "dflt": false, - "role": "style", - "valType": "enumerated", - "values": [ - "fast", - "best", - false - ] - }, "zsrc": { "description": "Sets the source reference on plot.ly for z .", "role": "info", @@ -7044,18 +7033,6 @@ "role": "style", "valType": "boolean" }, - "dx": { - "description": "Sets the x coordinate step. See `x0` for more info.", - "dflt": 1, - "role": "info", - "valType": "number" - }, - "dy": { - "description": "Sets the y coordinate step. See `y0` for more info.", - "dflt": 1, - "role": "info", - "valType": "number" - }, "error_x": { "_deprecated": { "opacity": { @@ -7337,9 +7314,10 @@ "valType": "number" }, "color": { + "arrayOk": true, "description": "Sets the marker color.", - "role": "data", - "valType": "data_array" + "role": "style", + "valType": "color" }, "colorbar": { "bgcolor": { @@ -7740,6 +7718,7 @@ "width": { "arrayOk": true, "description": "Sets the width (in px) of the lines bounding the marker points.", + "dflt": 0, "min": 0, "role": "style", "valType": "number" @@ -7800,16 +7779,6 @@ "h" ] }, - "r": { - "description": "For polar chart only.Sets the radial coordinates.", - "role": "data", - "valType": "data_array" - }, - "rsrc": { - "description": "Sets the source reference on plot.ly for r .", - "role": "info", - "valType": "string" - }, "showlegend": { "description": "Determines whether or not an item corresponding to this trace is shown in the legend.", "dflt": true, @@ -7832,11 +7801,6 @@ "valType": "string" } }, - "t": { - "description": "For polar chart only.Sets the angular coordinates.", - "role": "data", - "valType": "data_array" - }, "text": { "arrayOk": true, "description": "Sets text elements associated with each (x,y) pair. If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (x,y) coordinates.", @@ -7849,11 +7813,6 @@ "role": "info", "valType": "string" }, - "tsrc": { - "description": "Sets the source reference on plot.ly for t .", - "role": "info", - "valType": "string" - }, "type": "histogram", "uid": { "dflt": "", @@ -7876,12 +7835,6 @@ "role": "data", "valType": "data_array" }, - "x0": { - "description": "Alternate to `x`. Builds a linear space of x coordinates. Use with `dx` where `x0` is the starting coordinate and `dx` the step.", - "dflt": 0, - "role": "info", - "valType": "any" - }, "xaxis": { "description": "Sets a reference between this trace's x coordinates and a 2D cartesian x axis. If *x* (the default value), the x coordinates refer to `layout.xaxis`. If *x2*, the x coordinates refer to `layout.xaxis2`, and so on.", "dflt": "x", @@ -7919,12 +7872,6 @@ "role": "data", "valType": "data_array" }, - "y0": { - "description": "Alternate to `y`. Builds a linear space of y coordinates. Use with `dy` where `y0` is the starting coordinate and `dy` the step.", - "dflt": 0, - "role": "info", - "valType": "any" - }, "yaxis": { "description": "Sets a reference between this trace's y coordinates and a 2D cartesian y axis. If *y* (the default value), the y coordinates refer to `layout.yaxis`. If *y2*, the y coordinates refer to `layout.xaxis2`, and so on.", "dflt": "y", @@ -7956,16 +7903,6 @@ "description": "Sets the source reference on plot.ly for y .", "role": "info", "valType": "string" - }, - "z": { - "description": "Sets the aggregation data.", - "role": "data", - "valType": "data_array" - }, - "zsrc": { - "description": "Sets the source reference on plot.ly for z .", - "role": "info", - "valType": "string" } }, "description": "The sample data from which statistics are computed is set in `x` for vertically spanning histograms and in `y` for horizontally spanning histograms. Binning options are set `xbins` and `ybins` respectively if no aggregation data is provided.", @@ -8372,24 +8309,6 @@ "role": "style", "valType": "colorscale" }, - "connectgaps": { - "description": "Determines whether or not gaps (i.e. {nan} or missing values) in the `z` data are filled in.", - "dflt": false, - "role": "info", - "valType": "boolean" - }, - "dx": { - "description": "Sets the x coordinate step. See `x0` for more info.", - "dflt": 1, - "role": "info", - "valType": "number" - }, - "dy": { - "description": "Sets the y coordinate step. See `y0` for more info.", - "dflt": 1, - "role": "info", - "valType": "number" - }, "histfunc": { "description": "Specifies the binning function used for this histogram trace. If *count*, the histogram values are computed by counting the number of values lying inside each bin. If *sum*, *avg*, *min*, *max*, the histogram values are computed using the sum, the average, the minimum or the maximum of the values lying inside each bin respectively.", "dflt": "count", @@ -8441,6 +8360,7 @@ }, "marker": { "color": { + "description": "Sets the aggregation data.", "role": "data", "valType": "data_array" }, @@ -8478,15 +8398,6 @@ "role": "style", "valType": "number" }, - "orientation": { - "description": "Sets the orientation of the bars. With *v* (*h*), the value of the each bar spans along the vertical (horizontal).", - "role": "info", - "valType": "enumerated", - "values": [ - "v", - "h" - ] - }, "reversescale": { "description": "Reverses the colorscale.", "dflt": false, @@ -8521,22 +8432,6 @@ "valType": "string" } }, - "text": { - "description": "Sets the text elements associated with each z value.", - "role": "data", - "valType": "data_array" - }, - "textsrc": { - "description": "Sets the source reference on plot.ly for text .", - "role": "info", - "valType": "string" - }, - "transpose": { - "description": "Transposes the z data.", - "dflt": false, - "role": "info", - "valType": "boolean" - }, "type": "histogram2d", "uid": { "dflt": "", @@ -8559,12 +8454,6 @@ "role": "data", "valType": "data_array" }, - "x0": { - "description": "Alternate to `x`. Builds a linear space of x coordinates. Use with `dx` where `x0` is the starting coordinate and `dx` the step.", - "dflt": 0, - "role": "info", - "valType": "any" - }, "xaxis": { "description": "Sets a reference between this trace's x coordinates and a 2D cartesian x axis. If *x* (the default value), the x coordinates refer to `layout.xaxis`. If *x2*, the x coordinates refer to `layout.xaxis2`, and so on.", "dflt": "x", @@ -8597,26 +8486,11 @@ "role": "info", "valType": "string" }, - "xtype": { - "description": "If *array*, the heatmap's x coordinates are given by *x* (the default behavior when `x` is provided). If *scaled*, the heatmap's x coordinates are given by *x0* and *dx* (the default behavior when `x` is not provided).", - "role": "info", - "valType": "enumerated", - "values": [ - "array", - "scaled" - ] - }, "y": { "description": "Sets the sample data to be binned on the y axis.", "role": "data", "valType": "data_array" }, - "y0": { - "description": "Alternate to `y`. Builds a linear space of y coordinates. Use with `dy` where `y0` is the starting coordinate and `dy` the step.", - "dflt": 0, - "role": "info", - "valType": "any" - }, "yaxis": { "description": "Sets a reference between this trace's y coordinates and a 2D cartesian y axis. If *y* (the default value), the y coordinates refer to `layout.yaxis`. If *y2*, the y coordinates refer to `layout.xaxis2`, and so on.", "dflt": "y", @@ -8649,15 +8523,6 @@ "role": "info", "valType": "string" }, - "ytype": { - "description": "If *array*, the heatmap's y coordinates are given by *y* (the default behavior when `y` is provided) If *scaled*, the heatmap's y coordinates are given by *y0* and *dy* (the default behavior when `y` is not provided)", - "role": "info", - "valType": "enumerated", - "values": [ - "array", - "scaled" - ] - }, "z": { "description": "Sets the aggregation data.", "role": "data", @@ -9070,12 +8935,6 @@ "role": "style", "valType": "colorscale" }, - "connectgaps": { - "description": "Determines whether or not gaps (i.e. {nan} or missing values) in the `z` data are filled in.", - "dflt": false, - "role": "info", - "valType": "boolean" - }, "contours": { "coloring": { "description": "Determines the coloring method showing the contour values. If *fill*, coloring is done evenly between each contour level If *heatmap*, a heatmap gradient is coloring is applied between each contour level. If *lines*, coloring is done on the contour lines. If *none*, no coloring is applied on this trace.", @@ -9115,18 +8974,6 @@ "valType": "number" } }, - "dx": { - "description": "Sets the x coordinate step. See `x0` for more info.", - "dflt": 1, - "role": "info", - "valType": "number" - }, - "dy": { - "description": "Sets the y coordinate step. See `y0` for more info.", - "dflt": 1, - "role": "info", - "valType": "number" - }, "histfunc": { "description": "Specifies the binning function used for this histogram trace. If *count*, the histogram values are computed by counting the number of values lying inside each bin. If *sum*, *avg*, *min*, *max*, the histogram values are computed using the sum, the average, the minimum or the maximum of the values lying inside each bin respectively.", "dflt": "count", @@ -9215,6 +9062,7 @@ }, "marker": { "color": { + "description": "Sets the aggregation data.", "role": "data", "valType": "data_array" }, @@ -9258,15 +9106,6 @@ "role": "style", "valType": "number" }, - "orientation": { - "description": "Sets the orientation of the bars. With *v* (*h*), the value of the each bar spans along the vertical (horizontal).", - "role": "info", - "valType": "enumerated", - "values": [ - "v", - "h" - ] - }, "reversescale": { "description": "Reverses the colorscale.", "dflt": false, @@ -9301,22 +9140,6 @@ "valType": "string" } }, - "text": { - "description": "Sets the text elements associated with each z value.", - "role": "data", - "valType": "data_array" - }, - "textsrc": { - "description": "Sets the source reference on plot.ly for text .", - "role": "info", - "valType": "string" - }, - "transpose": { - "description": "Transposes the z data.", - "dflt": false, - "role": "info", - "valType": "boolean" - }, "type": "histogram2dcontour", "uid": { "dflt": "", @@ -9339,12 +9162,6 @@ "role": "data", "valType": "data_array" }, - "x0": { - "description": "Alternate to `x`. Builds a linear space of x coordinates. Use with `dx` where `x0` is the starting coordinate and `dx` the step.", - "dflt": 0, - "role": "info", - "valType": "any" - }, "xaxis": { "description": "Sets a reference between this trace's x coordinates and a 2D cartesian x axis. If *x* (the default value), the x coordinates refer to `layout.xaxis`. If *x2*, the x coordinates refer to `layout.xaxis2`, and so on.", "dflt": "x", @@ -9377,26 +9194,11 @@ "role": "info", "valType": "string" }, - "xtype": { - "description": "If *array*, the heatmap's x coordinates are given by *x* (the default behavior when `x` is provided). If *scaled*, the heatmap's x coordinates are given by *x0* and *dx* (the default behavior when `x` is not provided).", - "role": "info", - "valType": "enumerated", - "values": [ - "array", - "scaled" - ] - }, "y": { "description": "Sets the sample data to be binned on the y axis.", "role": "data", "valType": "data_array" }, - "y0": { - "description": "Alternate to `y`. Builds a linear space of y coordinates. Use with `dy` where `y0` is the starting coordinate and `dy` the step.", - "dflt": 0, - "role": "info", - "valType": "any" - }, "yaxis": { "description": "Sets a reference between this trace's y coordinates and a 2D cartesian y axis. If *y* (the default value), the y coordinates refer to `layout.yaxis`. If *y2*, the y coordinates refer to `layout.xaxis2`, and so on.", "dflt": "y", @@ -9429,15 +9231,6 @@ "role": "info", "valType": "string" }, - "ytype": { - "description": "If *array*, the heatmap's y coordinates are given by *y* (the default behavior when `y` is provided) If *scaled*, the heatmap's y coordinates are given by *y0* and *dy* (the default behavior when `y` is not provided)", - "role": "info", - "valType": "enumerated", - "values": [ - "array", - "scaled" - ] - }, "z": { "description": "Sets the aggregation data.", "role": "data", @@ -9461,17 +9254,6 @@ "role": "info", "valType": "number" }, - "zsmooth": { - "description": "Picks a smoothing algorithm use to smooth `z` data.", - "dflt": false, - "role": "style", - "valType": "enumerated", - "values": [ - "fast", - "best", - false - ] - }, "zsrc": { "description": "Sets the source reference on plot.ly for z .", "role": "info", @@ -9484,11 +9266,13 @@ "mesh3d": { "attributes": { "alphahull": { + "description": "Sets the shape of the mesh If *-1*, Delaunay triangulation is used If *>0*, the alpha-shape algorithm is used If *0*, the convex-hull algorithm is used An alternative to the `i`, `j`, `k` indices triplets.", "dflt": -1, "role": "style", "valType": "number" }, "color": { + "description": "Sets the color of the whole mesh", "role": "style", "valType": "color" }, @@ -9843,6 +9627,7 @@ }, "role": "object", "show": { + "description": "Sets whether or not dynamic contours are shown on hover", "dflt": false, "role": "info", "valType": "boolean" @@ -9856,6 +9641,7 @@ } }, "delaunayaxis": { + "description": "Sets the Delaunay axis from which the triangulation of the mesh takes place. An alternative to setting the `i`, `j`, `k` indices triplets.", "dflt": "z", "role": "info", "valType": "enumerated", @@ -9866,6 +9652,7 @@ ] }, "facecolor": { + "description": "Sets the color of each face Overrides *color* and *vertexcolor*.", "role": "data", "valType": "data_array" }, @@ -9875,6 +9662,7 @@ "valType": "string" }, "flatshading": { + "description": "Determines whether or not normal smoothing is applied to the meshes, creating meshes with a low-poly look.", "dflt": false, "role": "style", "valType": "boolean" @@ -9897,10 +9685,12 @@ "valType": "flaglist" }, "i": { + "description": "Sets the indices of x coordinates of the vertices", "role": "data", "valType": "data_array" }, "intensity": { + "description": "Sets the vertex intensity values, used for plotting fields on meshes", "role": "data", "valType": "data_array" }, @@ -9915,6 +9705,7 @@ "valType": "string" }, "j": { + "description": "Sets the indices of y coordinates of the vertices", "role": "data", "valType": "data_array" }, @@ -9924,6 +9715,7 @@ "valType": "string" }, "k": { + "description": "Sets the indices of z coordinates of the vertices", "role": "data", "valType": "data_array" }, @@ -10035,6 +9827,7 @@ "valType": "string" }, "vertexcolor": { + "description": "Sets the color of each vertex Overrides *color*.", "role": "data", "valType": "data_array" }, @@ -10055,6 +9848,7 @@ ] }, "x": { + "description": "Sets the x coordinates of the vertices", "role": "data", "valType": "data_array" }, @@ -10064,6 +9858,7 @@ "valType": "string" }, "y": { + "description": "Sets the y coordinates of the vertices", "role": "data", "valType": "data_array" }, @@ -10073,6 +9868,7 @@ "valType": "string" }, "z": { + "description": "Sets the z coordinates of the vertices", "role": "data", "valType": "data_array" }, @@ -10082,7 +9878,7 @@ "valType": "string" } }, - "description": "" + "description": "Draws sets of triangles with coordinates given by three 1-dimensional arrays in `x`, `y`, `z` and (1) a sets of `i`, `j`, `k` indices (2) Delaunay triangulation or (3) the Alpha-shape algorithm or (4) the Convex-hull algorithm" }, "pie": { "attributes": { @@ -12576,18 +12372,13 @@ } }, "opacity": { - "arrayOk": true, - "description": "Sets the marker opacity.", + "arrayOk": false, + "description": "Sets the marker opacity. Note that the marker opacity for scatter3d traces must be a scalar value for performance reasons. To set a blending opacity value (i.e. which is not transparent), set *marker.color* to an rgba color and use its alpha channel.", "max": 1, "min": 0, "role": "style", "valType": "number" }, - "opacitysrc": { - "description": "Sets the source reference on plot.ly for opacity .", - "role": "info", - "valType": "string" - }, "reversescale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Reverses the colorscale.", "dflt": false, From 9212e84803585d436dc5808c367d9ed6a34c60ab Mon Sep 17 00:00:00 2001 From: chriddyp Date: Mon, 11 Jan 2016 10:05:33 -0500 Subject: [PATCH 10/10] V1.9.4 - Offline mode without ipython/jupyter --- CHANGELOG.md | 25 +++++++++++++++++++++++++ plotly/version.py | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c823a8728a9..bbf46486078 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,31 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +## [1.9.4] - 2015-01-11 +### Added +- Offline plotting now works outside of the IPython/Juypter notebook. Here's an example: +``` +from plotly.offline import plot +from plotly.graph_objs import Scatter + +plot([Scatter(x=[1, 2, 3], y=[3, 1, 6])]) +``` + +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. + +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. + +If you want to publish your graphs to the web, use `plotly.plotly.plot`, as in: + +``` +import plotly.plotly as py +from plotly.graph_objs import Scatter + +py.plot([Scatter(x=[1, 2, 3], y=[5, 1, 6])]) +``` + +This will upload the graph to your online plotly account. + ## [1.9.3] - 2015-12-08 ### Added - 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. diff --git a/plotly/version.py b/plotly/version.py index be0b610758e..6c08d428eb4 100644 --- a/plotly/version.py +++ b/plotly/version.py @@ -1 +1 @@ -__version__ = '1.9.3' +__version__ = '1.9.4'