From f6a5af8992a282f82b80d4240c8d23b5cb997c6d Mon Sep 17 00:00:00 2001 From: Emmanuelle Gouillart Date: Fri, 24 May 2019 08:37:47 +0200 Subject: [PATCH 01/16] scraper function for sphinx-gallery, in plotly.io scraper function + skeleton of sphinx doc with minimal gallery (two examples) --- doc/Makefile | 28 ++++ doc/api.rst | 15 ++ doc/conf.py | 199 ++++++++++++++++++++++++ doc/index.rst | 24 +++ doc/tutorial.rst | 4 + examples/README.txt | 4 + examples/plot_plotly.py | 36 +++++ examples/plot_plotly_3d.py | 31 ++++ plotly/io/_sg_scraper.py | 118 ++++++++++++++ plotly/tests/test_io/test_sg_scraper.py | 49 ++++++ 10 files changed, 508 insertions(+) create mode 100644 doc/Makefile create mode 100644 doc/api.rst create mode 100644 doc/conf.py create mode 100644 doc/index.rst create mode 100644 doc/tutorial.rst create mode 100644 examples/README.txt create mode 100644 examples/plot_plotly.py create mode 100644 examples/plot_plotly_3d.py create mode 100644 plotly/io/_sg_scraper.py create mode 100644 plotly/tests/test_io/test_sg_scraper.py diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 00000000000..2d90182d282 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,28 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +PYTHON ?= python3 +SPHINXOPTS ?= -j $(shell nproc || getconf _NPROCESSORS_ONLN || 1) +SPHINXBUILD ?= $(PYTHON) -m sphinx +SPHINXPROJ = plotly +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + + +clean: + rm -rf $(BUILDDIR)/* + rm -rf auto_examples/ + rm -rf gen_modules/ + diff --git a/doc/api.rst b/doc/api.rst new file mode 100644 index 00000000000..9599f0d861b --- /dev/null +++ b/doc/api.rst @@ -0,0 +1,15 @@ +API documentation +================= + +API below is generated, a lot of room for customizing the design + + +.. automodule:: plotly.plotly + :members: + +.. automodule:: plotly.graph_objs + :members: + +.. automodule:: plotly.tools + :members: + diff --git a/doc/conf.py b/doc/conf.py new file mode 100644 index 00000000000..2362e0b918d --- /dev/null +++ b/doc/conf.py @@ -0,0 +1,199 @@ +# -*- coding: utf-8 -*- +# +# plotly documentation build configuration file, created by +# sphinx-quickstart on Wed May 1 15:00:57 2019. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +sys.path.insert(0, os.path.abspath('..')) +sys.setrecursionlimit(1500) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'numpydoc', + 'sphinx.ext.autosummary', + 'sphinx.ext.doctest', + 'sphinx.ext.intersphinx', + 'sphinx.ext.todo', + 'sphinx.ext.coverage', + 'sphinx.ext.mathjax', + 'sphinx_gallery.gen_gallery', + ] + +autosummary_generate = True + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'plotly' +copyright = u'2019, Plotly' +author = u'Plotly' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +import plotly +version = '3.8' #plotly.__version__ + +# The full version, including alpha/beta/rc tags. +release = '3.8' #plotly.__version__ + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# This is required for the alabaster theme +# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars +html_sidebars = { + '**': [ + 'relations.html', # needs 'show_related': True theme option to display + 'searchbox.html', + ] +} + + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'plotlydoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'plotly.tex', u'plotly Documentation', + u'Plotly', 'manual'), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'plotly', u'plotly Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'plotly', u'plotly Documentation', + author, 'plotly', 'One line description of project.', + 'Miscellaneous'), +] + + + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'https://docs.python.org/': None} + +from plotly.io._sg_scraper import plotly_sg_scraper +image_scrapers = ('matplotlib', plotly_sg_scraper,) + + +sphinx_gallery_conf = { + 'doc_module': ('plotly',), + 'examples_dirs': '../examples', # path to your example scripts + 'backreferences_dir': 'api', + 'reference_url': {'plotly': None, + }, + 'image_scrapers': image_scrapers, +} + diff --git a/doc/index.rst b/doc/index.rst new file mode 100644 index 00000000000..3b1f7542677 --- /dev/null +++ b/doc/index.rst @@ -0,0 +1,24 @@ +.. plotly documentation master file, created by + sphinx-quickstart on Wed May 1 15:00:57 2019. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to plotly's documentation! +================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + auto_examples/index + api + tutorial + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/doc/tutorial.rst b/doc/tutorial.rst new file mode 100644 index 00000000000..597eb1a3529 --- /dev/null +++ b/doc/tutorial.rst @@ -0,0 +1,4 @@ +Narrative documentation +======================= + +goes here diff --git a/examples/README.txt b/examples/README.txt new file mode 100644 index 00000000000..1d53129d52c --- /dev/null +++ b/examples/README.txt @@ -0,0 +1,4 @@ +Gallery of examples +=================== + +Some examples using plotly. diff --git a/examples/plot_plotly.py b/examples/plot_plotly.py new file mode 100644 index 00000000000..7bab80b14a9 --- /dev/null +++ b/examples/plot_plotly.py @@ -0,0 +1,36 @@ +""" +A simple scatter plot +===================== + +A scatter plot is created with the plotly library. The figure is interactive, +information are displayed on hover and it is possible to zoom and pan through +the figure. +""" +import plotly.graph_objs as go +import plotly + +# Create random data with numpy +import numpy as np + +N = 200 +random_x = np.random.randn(N) +random_y_0 = np.random.randn(N) +random_y_1 = np.random.randn(N) - 1 + +# Create traces +trace_0 = go.Scatter( + x=random_x, + y=random_y_0, + mode='markers', + name='Above', +) +trace_1 = go.Scatter( + x=random_x, + y=random_y_1, + mode='markers', + name='Below', +) + +data = [trace_0, trace_1] +res = plotly.offline.plot(data) + diff --git a/examples/plot_plotly_3d.py b/examples/plot_plotly_3d.py new file mode 100644 index 00000000000..8b37c54db75 --- /dev/null +++ b/examples/plot_plotly_3d.py @@ -0,0 +1,31 @@ +""" +Topographical 3D Surface Plot +============================= + +A 3D surface plot showing the topograph of Mount Bruno (Quebec). Try to +rotate (left button and drag) and scale (scroll) this animated 3D plot. +""" +import plotly +import plotly.graph_objs as go + +import pandas as pd + +# Read data from a csv +z_data = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv') + +data = [go.Surface(z=z_data) + ] +layout = go.Layout( + title='Mt Bruno Elevation', + autosize=False, + width=600, + height=600, + margin=dict( + l=65, + r=50, + b=65, + t=90 + ) +) +fig = go.Figure(data=data, layout=layout) +plotly.offline.plot(fig) diff --git a/plotly/io/_sg_scraper.py b/plotly/io/_sg_scraper.py new file mode 100644 index 00000000000..905db3dc76e --- /dev/null +++ b/plotly/io/_sg_scraper.py @@ -0,0 +1,118 @@ +# This module defines an image scraper for sphinx-gallery +# https://sphinx-gallery.github.io/ +# which can be used by projects using plotly in their documentation. +# This module monkey-patches plotly.offline.plot, so we do not +# import it in __init__.py +import inspect, os + +import plotly +plotly_plot = plotly.offline.plot +from glob import glob +import shutil + +def _patched_plotly_plot(*args, **kwargs): + """ + Monkey-patched version of plotly.offline.plot, in order to save + html file with the same name as python script. Also, a static + png file is saved. + """ + stack = inspect.stack() + # Name of script from which plot function was called is retrieved + filename = stack[1].filename # let's hope this is robust... + filename_root, _ = os.path.splitext(filename) + filename_html = filename_root + '.html' + filename_png = filename_root + '.png' + figure = plotly.tools.return_figure_from_figure_or_data(*args, True) + res = plotly_plot(*args, auto_open=False, + filename=filename_html) + plotly.io.write_image(figure, filename_png) + return res + +plotly.offline.plot = _patched_plotly_plot + + +def plotly_sg_scraper(block, block_vars, gallery_conf, **kwargs): + """Scrape Plotly figures. + + Since the monkey-patched version of plotly.offline.plot generates + both html and static png files, we simply crawl these files and give + them the appropriate path. + + Parameters + ---------- + block : tuple + A tuple containing the (label, content, line_number) of the block. + block_vars : dict + Dict of block variables. + gallery_conf : dict + Contains the configuration of Sphinx-Gallery + **kwargs : dict + Additional keyword arguments to pass to + :meth:`~matplotlib.figure.Figure.savefig`, e.g. ``format='svg'``. + The ``format`` kwarg in particular is used to set the file extension + of the output file (currently only 'png' and 'svg' are supported). + + Returns + ------- + rst : str + The ReSTructuredText that will be rendered to HTML containing + the images. + """ + examples_dirs = gallery_conf['examples_dirs'] + if isinstance(examples_dirs, (list, tuple)): + examples_dirs = examples_dirs[0] + pngs = sorted(glob(os.path.join(examples_dirs, + '*.png'))) + htmls = sorted(glob(os.path.join(examples_dirs, + '*.html'))) + image_path_iterator = block_vars['image_path_iterator'] + image_names = list() + seen = set() + for html, png in zip(htmls, pngs): + if png not in seen: + seen |= set(png) + this_image_path_png = image_path_iterator.__next__() + this_image_path_html = (os.path.splitext( + this_image_path_png)[0] + '.html') + image_names.append(this_image_path_html) + shutil.move(png, this_image_path_png) + shutil.move(html, this_image_path_html) + # Use the `figure_rst` helper function to generate rST for image files + return figure_rst(image_names, gallery_conf['src_dir']) + + +def figure_rst(figure_list, sources_dir): + """Generate RST for a list of PNG filenames. + + Depending on whether we have one or more figures, we use a + single rst call to 'image' or a horizontal list. + + Parameters + ---------- + figure_list : list + List of strings of the figures' absolute paths. + sources_dir : str + absolute path of Sphinx documentation sources + + Returns + ------- + images_rst : str + rst code to embed the images in the document + """ + + figure_paths = [os.path.relpath(figure_path, sources_dir) + .replace(os.sep, '/').lstrip('/') + for figure_path in figure_list] + images_rst = "" + figure_name = figure_paths[0] + ext = os.path.splitext(figure_name)[1] + figure_path = os.path.join('images', os.path.basename(figure_name)) + images_rst = SINGLE_HTML % figure_path + return images_rst + + +SINGLE_HTML = """ +.. raw:: html + :file: %s +""" + diff --git a/plotly/tests/test_io/test_sg_scraper.py b/plotly/tests/test_io/test_sg_scraper.py new file mode 100644 index 00000000000..b9cf5aea15b --- /dev/null +++ b/plotly/tests/test_io/test_sg_scraper.py @@ -0,0 +1,49 @@ +import plotly +plotly_plot = plotly.offline.plot +import os +import shutil + +def execute_plotly_example(): + """ + Some typical code which would go inside a gallery example. + """ + import plotly.graph_objs as go + + # Create random data with numpy + import numpy as np + + N = 200 + random_x = np.random.randn(N) + random_y_0 = np.random.randn(N) + random_y_1 = np.random.randn(N) - 1 + + # Create traces + trace_0 = go.Scatter( + x=random_x, + y=random_y_0, + mode='markers', + name='Above', + ) + + data = [trace_0] + res = plotly.offline.plot(data) + + +def test_monkey_patching(): + from plotly.io._sg_scraper import plotly_sg_scraper + # test that monkey-patching worked ok + assert plotly_plot != plotly.offline.plot + # Use dummy values for arguments of plotly_sg_scraper + block = '' # we don't need actually code + import tempfile + tempdir = tempfile.mkdtemp() + gallery_conf = {'src_dir':tempdir, + 'examples_dirs':'plotly/tests/test_io'} + names = iter(['0', '1', '2']) + block_vars = {'image_path_iterator':names} + execute_plotly_example() + res = plotly_sg_scraper(block, block_vars, gallery_conf) + shutil.rmtree(tempdir) + assert ".. raw:: html" in res + plotly.offline.plot = plotly_plot + assert plotly_plot == plotly.offline.plot From 343f2b269b88fd171d53e39798766b1af3c2185d Mon Sep 17 00:00:00 2001 From: Emmanuelle Gouillart Date: Fri, 24 May 2019 10:18:58 +0200 Subject: [PATCH 02/16] added psutil dep to tox.ini --- tox.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/tox.ini b/tox.ini index 4a8d0d19135..1b6bd10c38d 100644 --- a/tox.ini +++ b/tox.ini @@ -74,6 +74,7 @@ deps= optional: matplotlib==2.2.3 optional: xarray==0.10.9 optional: scikit-image==0.13.1 + optional: psutil==5.6.2 plot_ly: pandas==0.23.2 plot_ly: numpy==1.14.3 plot_ly: ipywidgets==7.2.0 From 0e7e209395a3d8acfb5dd3a20e70be98596e391b Mon Sep 17 00:00:00 2001 From: Emmanuelle Gouillart Date: Fri, 24 May 2019 10:39:04 +0200 Subject: [PATCH 03/16] python 2 compatibility --- plotly/io/_sg_scraper.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plotly/io/_sg_scraper.py b/plotly/io/_sg_scraper.py index 905db3dc76e..aa6dfaa97c0 100644 --- a/plotly/io/_sg_scraper.py +++ b/plotly/io/_sg_scraper.py @@ -22,7 +22,8 @@ def _patched_plotly_plot(*args, **kwargs): filename_root, _ = os.path.splitext(filename) filename_html = filename_root + '.html' filename_png = filename_root + '.png' - figure = plotly.tools.return_figure_from_figure_or_data(*args, True) + fig_or_data = + figure = plotly.tools.return_figure_from_figure_or_data(*(args, True)) res = plotly_plot(*args, auto_open=False, filename=filename_html) plotly.io.write_image(figure, filename_png) @@ -57,6 +58,10 @@ def plotly_sg_scraper(block, block_vars, gallery_conf, **kwargs): rst : str The ReSTructuredText that will be rendered to HTML containing the images. + + Notes + ----- + Add this function to the image scrapers """ examples_dirs = gallery_conf['examples_dirs'] if isinstance(examples_dirs, (list, tuple)): From dd4cc35b7861107f1e6797d50771d9fe6cf49291 Mon Sep 17 00:00:00 2001 From: Emmanuelle Gouillart Date: Fri, 24 May 2019 10:45:26 +0200 Subject: [PATCH 04/16] added orca dep to package.json for tests --- plotly/tests/test_optional/test_jupyter/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plotly/tests/test_optional/test_jupyter/package.json b/plotly/tests/test_optional/test_jupyter/package.json index c99e7062d7a..3ecac4d5a5f 100644 --- a/plotly/tests/test_optional/test_jupyter/package.json +++ b/plotly/tests/test_optional/test_jupyter/package.json @@ -15,6 +15,7 @@ "ecstatic": "^2.1.0", "tap-parser": "^2.0.0", "tape": "^4.6.0", - "xhr": "^2.2.2" + "xhr": "^2.2.2", + "orca": "^1.2.1" } } From 2ea2feab82af2f5ea3d34120078cfe7e158981e4 Mon Sep 17 00:00:00 2001 From: Emmanuelle Gouillart Date: Fri, 24 May 2019 10:46:54 +0200 Subject: [PATCH 05/16] removed typo --- plotly/io/_sg_scraper.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plotly/io/_sg_scraper.py b/plotly/io/_sg_scraper.py index aa6dfaa97c0..290255e7a3f 100644 --- a/plotly/io/_sg_scraper.py +++ b/plotly/io/_sg_scraper.py @@ -22,7 +22,6 @@ def _patched_plotly_plot(*args, **kwargs): filename_root, _ = os.path.splitext(filename) filename_html = filename_root + '.html' filename_png = filename_root + '.png' - fig_or_data = figure = plotly.tools.return_figure_from_figure_or_data(*(args, True)) res = plotly_plot(*args, auto_open=False, filename=filename_html) From 6909d766c14f82b1f12b211ec090bb40902787f7 Mon Sep 17 00:00:00 2001 From: Emmanuelle Gouillart Date: Fri, 24 May 2019 10:50:01 +0200 Subject: [PATCH 06/16] corrected bug --- plotly/io/_sg_scraper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plotly/io/_sg_scraper.py b/plotly/io/_sg_scraper.py index 290255e7a3f..45b8919b64a 100644 --- a/plotly/io/_sg_scraper.py +++ b/plotly/io/_sg_scraper.py @@ -22,7 +22,7 @@ def _patched_plotly_plot(*args, **kwargs): filename_root, _ = os.path.splitext(filename) filename_html = filename_root + '.html' filename_png = filename_root + '.png' - figure = plotly.tools.return_figure_from_figure_or_data(*(args, True)) + figure = plotly.tools.return_figure_from_figure_or_data(args[0], True) res = plotly_plot(*args, auto_open=False, filename=filename_html) plotly.io.write_image(figure, filename_png) From 795061ad198b442e28d067fcf5832b203e503e1e Mon Sep 17 00:00:00 2001 From: Emmanuelle Gouillart Date: Fri, 24 May 2019 11:47:01 +0200 Subject: [PATCH 07/16] python 2 compatibility --- plotly/io/_sg_scraper.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plotly/io/_sg_scraper.py b/plotly/io/_sg_scraper.py index 45b8919b64a..7323d389a58 100644 --- a/plotly/io/_sg_scraper.py +++ b/plotly/io/_sg_scraper.py @@ -18,7 +18,10 @@ def _patched_plotly_plot(*args, **kwargs): """ stack = inspect.stack() # Name of script from which plot function was called is retrieved - filename = stack[1].filename # let's hope this is robust... + try: + filename = stack[1].filename # let's hope this is robust... + except: #python 2 + filename = stack[1][1] filename_root, _ = os.path.splitext(filename) filename_html = filename_root + '.html' filename_png = filename_root + '.png' From 6654b462bb1c822eb954b2f13bce2407100e2103 Mon Sep 17 00:00:00 2001 From: Emmanuelle Gouillart Date: Fri, 24 May 2019 12:38:36 +0200 Subject: [PATCH 08/16] added electron --- plotly/tests/test_optional/test_jupyter/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/plotly/tests/test_optional/test_jupyter/package.json b/plotly/tests/test_optional/test_jupyter/package.json index 3ecac4d5a5f..f6551f00beb 100644 --- a/plotly/tests/test_optional/test_jupyter/package.json +++ b/plotly/tests/test_optional/test_jupyter/package.json @@ -16,6 +16,7 @@ "tap-parser": "^2.0.0", "tape": "^4.6.0", "xhr": "^2.2.2", + "electron": "^1.8.4", "orca": "^1.2.1" } } From b9767529046fe4311db5f0c9daa7b35aadd6d909 Mon Sep 17 00:00:00 2001 From: Emmanuelle Gouillart Date: Fri, 24 May 2019 12:54:56 +0200 Subject: [PATCH 09/16] try to configure orca --- plotly/tests/test_io/test_sg_scraper.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/plotly/tests/test_io/test_sg_scraper.py b/plotly/tests/test_io/test_sg_scraper.py index b9cf5aea15b..bf0586cb0a5 100644 --- a/plotly/tests/test_io/test_sg_scraper.py +++ b/plotly/tests/test_io/test_sg_scraper.py @@ -2,6 +2,20 @@ plotly_plot = plotly.offline.plot import os import shutil +import pytest + + +# Fixtures +# -------- +@pytest.fixture() +def setup(): + # Reset orca state + plotly.io.orca.config.restore_defaults(reset_server=False) + + +# Run setup before every test function in this file +pytestmark = pytest.mark.usefixtures("setup") + def execute_plotly_example(): """ From 65ea73fa7bb86cf0d2d3ed8a1671f8489584e93f Mon Sep 17 00:00:00 2001 From: Emmanuelle Gouillart Date: Fri, 31 May 2019 08:14:57 +0200 Subject: [PATCH 10/16] Moved test file so that it's tested by the orca build only. --- plotly/tests/{test_io => test_orca}/test_sg_scraper.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename plotly/tests/{test_io => test_orca}/test_sg_scraper.py (100%) diff --git a/plotly/tests/test_io/test_sg_scraper.py b/plotly/tests/test_orca/test_sg_scraper.py similarity index 100% rename from plotly/tests/test_io/test_sg_scraper.py rename to plotly/tests/test_orca/test_sg_scraper.py From 6433175da1e0d5e6a8e20f90d9fe26b8b5d991d5 Mon Sep 17 00:00:00 2001 From: Emmanuelle Gouillart Date: Fri, 31 May 2019 13:42:40 +0200 Subject: [PATCH 11/16] use custom renderer for sphinx-gallery --- examples/plot_plotly.py | 4 ++-- examples/plot_plotly_3d.py | 2 +- plotly/io/_base_renderers.py | 22 ++++++++++++++++++++- plotly/io/_renderers.py | 4 +++- plotly/io/_sg_scraper.py | 24 +---------------------- plotly/tests/test_orca/test_sg_scraper.py | 13 +++++------- 6 files changed, 33 insertions(+), 36 deletions(-) diff --git a/examples/plot_plotly.py b/examples/plot_plotly.py index 7bab80b14a9..c306c70c810 100644 --- a/examples/plot_plotly.py +++ b/examples/plot_plotly.py @@ -31,6 +31,6 @@ name='Below', ) -data = [trace_0, trace_1] -res = plotly.offline.plot(data) +fig = go.Figure(data=[trace_0, trace_1]) +plotly.io.show(fig) diff --git a/examples/plot_plotly_3d.py b/examples/plot_plotly_3d.py index 8b37c54db75..ae3eac75780 100644 --- a/examples/plot_plotly_3d.py +++ b/examples/plot_plotly_3d.py @@ -28,4 +28,4 @@ ) ) fig = go.Figure(data=data, layout=layout) -plotly.offline.plot(fig) +plotly.io.show(fig) diff --git a/plotly/io/_base_renderers.py b/plotly/io/_base_renderers.py index 9dbc3a222f1..02d891d33c2 100644 --- a/plotly/io/_base_renderers.py +++ b/plotly/io/_base_renderers.py @@ -6,10 +6,12 @@ import os import six -from plotly.io import to_json, to_image +from plotly.io import to_json, to_image, write_image from plotly import utils, optional_imports from plotly.io._orca import ensure_server from plotly.offline.offline import _get_jconfig, get_plotlyjs +from plotly.offline import plot +from plotly.tools import return_figure_from_figure_or_data ipython_display = optional_imports.get_module('IPython.display') IPython = optional_imports.get_module('IPython') @@ -631,3 +633,21 @@ def render(self, fig_dict): default_height='100%', ) open_html_in_browser(html, self.using, self.new, self.autoraise) + + +class SphinxGalleryRenderer(ExternalRenderer): + + def render(self, fig_dict): + stack = inspect.stack() + # Name of script from which plot function was called is retrieved + try: + filename = stack[3].filename # let's hope this is robust... + except: #python 2 + filename = stack[3][1] + filename_root, _ = os.path.splitext(filename) + filename_html = filename_root + '.html' + filename_png = filename_root + '.png' + figure = return_figure_from_figure_or_data(fig_dict, True) + _ = plot(fig_dict, auto_open=False, + filename=filename_html) + write_image(figure, filename_png) diff --git a/plotly/io/_renderers.py b/plotly/io/_renderers.py index 293f75e9bbf..09a68a639a6 100644 --- a/plotly/io/_renderers.py +++ b/plotly/io/_renderers.py @@ -12,7 +12,8 @@ from plotly.io._base_renderers import ( MimetypeRenderer, ExternalRenderer, PlotlyRenderer, NotebookRenderer, KaggleRenderer, ColabRenderer, JsonRenderer, PngRenderer, JpegRenderer, - SvgRenderer, PdfRenderer, BrowserRenderer, IFrameRenderer) + SvgRenderer, PdfRenderer, BrowserRenderer, IFrameRenderer, + SphinxGalleryRenderer) from plotly.io._utils import validate_coerce_fig_to_dict ipython = optional_imports.get_module('IPython') @@ -394,6 +395,7 @@ def show(fig, renderer=None, validate=True, **kwargs): renderers['chrome'] = BrowserRenderer(config=config, using='chrome') renderers['chromium'] = BrowserRenderer(config=config, using='chromium') renderers['iframe'] = IFrameRenderer(config=config) +renderers['sphinx'] = SphinxGalleryRenderer() # Set default renderer # -------------------- diff --git a/plotly/io/_sg_scraper.py b/plotly/io/_sg_scraper.py index 7323d389a58..bbf909a3746 100644 --- a/plotly/io/_sg_scraper.py +++ b/plotly/io/_sg_scraper.py @@ -6,32 +6,10 @@ import inspect, os import plotly -plotly_plot = plotly.offline.plot from glob import glob import shutil -def _patched_plotly_plot(*args, **kwargs): - """ - Monkey-patched version of plotly.offline.plot, in order to save - html file with the same name as python script. Also, a static - png file is saved. - """ - stack = inspect.stack() - # Name of script from which plot function was called is retrieved - try: - filename = stack[1].filename # let's hope this is robust... - except: #python 2 - filename = stack[1][1] - filename_root, _ = os.path.splitext(filename) - filename_html = filename_root + '.html' - filename_png = filename_root + '.png' - figure = plotly.tools.return_figure_from_figure_or_data(args[0], True) - res = plotly_plot(*args, auto_open=False, - filename=filename_html) - plotly.io.write_image(figure, filename_png) - return res - -plotly.offline.plot = _patched_plotly_plot +plotly.io.renderers.default = 'sphinx' def plotly_sg_scraper(block, block_vars, gallery_conf, **kwargs): diff --git a/plotly/tests/test_orca/test_sg_scraper.py b/plotly/tests/test_orca/test_sg_scraper.py index bf0586cb0a5..4c468fe9803 100644 --- a/plotly/tests/test_orca/test_sg_scraper.py +++ b/plotly/tests/test_orca/test_sg_scraper.py @@ -1,5 +1,4 @@ import plotly -plotly_plot = plotly.offline.plot import os import shutil import pytest @@ -39,25 +38,23 @@ def execute_plotly_example(): name='Above', ) - data = [trace_0] - res = plotly.offline.plot(data) + fig = go.Figure(data=[trace_0]) + plotly.io.show(fig) -def test_monkey_patching(): +def test_scraper(): from plotly.io._sg_scraper import plotly_sg_scraper # test that monkey-patching worked ok - assert plotly_plot != plotly.offline.plot + assert plotly.io.renderers.default == 'sphinx' # Use dummy values for arguments of plotly_sg_scraper block = '' # we don't need actually code import tempfile tempdir = tempfile.mkdtemp() gallery_conf = {'src_dir':tempdir, - 'examples_dirs':'plotly/tests/test_io'} + 'examples_dirs':'plotly/tests/test_orca'} names = iter(['0', '1', '2']) block_vars = {'image_path_iterator':names} execute_plotly_example() res = plotly_sg_scraper(block, block_vars, gallery_conf) shutil.rmtree(tempdir) assert ".. raw:: html" in res - plotly.offline.plot = plotly_plot - assert plotly_plot == plotly.offline.plot From c353bc4213d16dafda903959e9e220a84dc33592 Mon Sep 17 00:00:00 2001 From: Emmanuelle Gouillart Date: Sun, 2 Jun 2019 13:28:02 +0200 Subject: [PATCH 12/16] removed sphinx files which are now in plotly-sphinx-gallery + changed name of renderer sphinx -> sphinx-gallery, and changed wording of documentation --- doc/Makefile | 28 ------ doc/api.rst | 15 --- doc/conf.py | 199 ------------------------------------- doc/index.rst | 24 ----- doc/tutorial.rst | 4 - examples/README.txt | 4 - examples/plot_plotly.py | 36 ------- examples/plot_plotly_3d.py | 31 ------ plotly/io/_renderers.py | 2 +- plotly/io/_sg_scraper.py | 15 +-- 10 files changed, 9 insertions(+), 349 deletions(-) delete mode 100644 doc/Makefile delete mode 100644 doc/api.rst delete mode 100644 doc/conf.py delete mode 100644 doc/index.rst delete mode 100644 doc/tutorial.rst delete mode 100644 examples/README.txt delete mode 100644 examples/plot_plotly.py delete mode 100644 examples/plot_plotly_3d.py diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index 2d90182d282..00000000000 --- a/doc/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line. -PYTHON ?= python3 -SPHINXOPTS ?= -j $(shell nproc || getconf _NPROCESSORS_ONLN || 1) -SPHINXBUILD ?= $(PYTHON) -m sphinx -SPHINXPROJ = plotly -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - - -clean: - rm -rf $(BUILDDIR)/* - rm -rf auto_examples/ - rm -rf gen_modules/ - diff --git a/doc/api.rst b/doc/api.rst deleted file mode 100644 index 9599f0d861b..00000000000 --- a/doc/api.rst +++ /dev/null @@ -1,15 +0,0 @@ -API documentation -================= - -API below is generated, a lot of room for customizing the design - - -.. automodule:: plotly.plotly - :members: - -.. automodule:: plotly.graph_objs - :members: - -.. automodule:: plotly.tools - :members: - diff --git a/doc/conf.py b/doc/conf.py deleted file mode 100644 index 2362e0b918d..00000000000 --- a/doc/conf.py +++ /dev/null @@ -1,199 +0,0 @@ -# -*- coding: utf-8 -*- -# -# plotly documentation build configuration file, created by -# sphinx-quickstart on Wed May 1 15:00:57 2019. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -import os -import sys -sys.path.insert(0, os.path.abspath('..')) -sys.setrecursionlimit(1500) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -# -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx.ext.autodoc', - 'numpydoc', - 'sphinx.ext.autosummary', - 'sphinx.ext.doctest', - 'sphinx.ext.intersphinx', - 'sphinx.ext.todo', - 'sphinx.ext.coverage', - 'sphinx.ext.mathjax', - 'sphinx_gallery.gen_gallery', - ] - -autosummary_generate = True - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'plotly' -copyright = u'2019, Plotly' -author = u'Plotly' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -import plotly -version = '3.8' #plotly.__version__ - -# The full version, including alpha/beta/rc tags. -release = '3.8' #plotly.__version__ - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This patterns also effect to html_static_path and html_extra_path -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = True - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = 'alabaster' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# -# html_theme_options = {} - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Custom sidebar templates, must be a dictionary that maps document names -# to template names. -# -# This is required for the alabaster theme -# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars -html_sidebars = { - '**': [ - 'relations.html', # needs 'show_related': True theme option to display - 'searchbox.html', - ] -} - - -# -- Options for HTMLHelp output ------------------------------------------ - -# Output file base name for HTML help builder. -htmlhelp_basename = 'plotlydoc' - - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'plotly.tex', u'plotly Documentation', - u'Plotly', 'manual'), -] - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'plotly', u'plotly Documentation', - [author], 1) -] - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'plotly', u'plotly Documentation', - author, 'plotly', 'One line description of project.', - 'Miscellaneous'), -] - - - - -# Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'https://docs.python.org/': None} - -from plotly.io._sg_scraper import plotly_sg_scraper -image_scrapers = ('matplotlib', plotly_sg_scraper,) - - -sphinx_gallery_conf = { - 'doc_module': ('plotly',), - 'examples_dirs': '../examples', # path to your example scripts - 'backreferences_dir': 'api', - 'reference_url': {'plotly': None, - }, - 'image_scrapers': image_scrapers, -} - diff --git a/doc/index.rst b/doc/index.rst deleted file mode 100644 index 3b1f7542677..00000000000 --- a/doc/index.rst +++ /dev/null @@ -1,24 +0,0 @@ -.. plotly documentation master file, created by - sphinx-quickstart on Wed May 1 15:00:57 2019. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to plotly's documentation! -================================== - -.. toctree:: - :maxdepth: 2 - :caption: Contents: - - auto_examples/index - api - tutorial - - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/doc/tutorial.rst b/doc/tutorial.rst deleted file mode 100644 index 597eb1a3529..00000000000 --- a/doc/tutorial.rst +++ /dev/null @@ -1,4 +0,0 @@ -Narrative documentation -======================= - -goes here diff --git a/examples/README.txt b/examples/README.txt deleted file mode 100644 index 1d53129d52c..00000000000 --- a/examples/README.txt +++ /dev/null @@ -1,4 +0,0 @@ -Gallery of examples -=================== - -Some examples using plotly. diff --git a/examples/plot_plotly.py b/examples/plot_plotly.py deleted file mode 100644 index c306c70c810..00000000000 --- a/examples/plot_plotly.py +++ /dev/null @@ -1,36 +0,0 @@ -""" -A simple scatter plot -===================== - -A scatter plot is created with the plotly library. The figure is interactive, -information are displayed on hover and it is possible to zoom and pan through -the figure. -""" -import plotly.graph_objs as go -import plotly - -# Create random data with numpy -import numpy as np - -N = 200 -random_x = np.random.randn(N) -random_y_0 = np.random.randn(N) -random_y_1 = np.random.randn(N) - 1 - -# Create traces -trace_0 = go.Scatter( - x=random_x, - y=random_y_0, - mode='markers', - name='Above', -) -trace_1 = go.Scatter( - x=random_x, - y=random_y_1, - mode='markers', - name='Below', -) - -fig = go.Figure(data=[trace_0, trace_1]) -plotly.io.show(fig) - diff --git a/examples/plot_plotly_3d.py b/examples/plot_plotly_3d.py deleted file mode 100644 index ae3eac75780..00000000000 --- a/examples/plot_plotly_3d.py +++ /dev/null @@ -1,31 +0,0 @@ -""" -Topographical 3D Surface Plot -============================= - -A 3D surface plot showing the topograph of Mount Bruno (Quebec). Try to -rotate (left button and drag) and scale (scroll) this animated 3D plot. -""" -import plotly -import plotly.graph_objs as go - -import pandas as pd - -# Read data from a csv -z_data = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv') - -data = [go.Surface(z=z_data) - ] -layout = go.Layout( - title='Mt Bruno Elevation', - autosize=False, - width=600, - height=600, - margin=dict( - l=65, - r=50, - b=65, - t=90 - ) -) -fig = go.Figure(data=data, layout=layout) -plotly.io.show(fig) diff --git a/plotly/io/_renderers.py b/plotly/io/_renderers.py index 32665f61763..d2aefbe5a0c 100644 --- a/plotly/io/_renderers.py +++ b/plotly/io/_renderers.py @@ -395,7 +395,7 @@ def show(fig, renderer=None, validate=True, **kwargs): renderers['chrome'] = BrowserRenderer(config=config, using='chrome') renderers['chromium'] = BrowserRenderer(config=config, using='chromium') renderers['iframe'] = IFrameRenderer(config=config) -renderers['sphinx'] = SphinxGalleryRenderer() +renderers['sphinx_gallery'] = SphinxGalleryRenderer() # Set default renderer # -------------------- diff --git a/plotly/io/_sg_scraper.py b/plotly/io/_sg_scraper.py index bbf909a3746..155158b28a4 100644 --- a/plotly/io/_sg_scraper.py +++ b/plotly/io/_sg_scraper.py @@ -1,23 +1,24 @@ # This module defines an image scraper for sphinx-gallery # https://sphinx-gallery.github.io/ # which can be used by projects using plotly in their documentation. -# This module monkey-patches plotly.offline.plot, so we do not -# import it in __init__.py import inspect, os import plotly from glob import glob import shutil -plotly.io.renderers.default = 'sphinx' +plotly.io.renderers.default = 'sphinx_gallery' def plotly_sg_scraper(block, block_vars, gallery_conf, **kwargs): - """Scrape Plotly figures. + """Scrape Plotly figures for galleries of examples using + sphinx-gallery. - Since the monkey-patched version of plotly.offline.plot generates - both html and static png files, we simply crawl these files and give - them the appropriate path. + Examples should use ``plotly.io.show()`` to display the figure with + the custom sphinx_gallery renderer. + + Since the sphinx_gallery renderer generates both html and static png + files, we simply crawl these files and give them the appropriate path. Parameters ---------- From b210bc54155662be03aad36f5118e238e23a92cd Mon Sep 17 00:00:00 2001 From: Emmanuelle Gouillart Date: Sun, 2 Jun 2019 13:49:48 +0200 Subject: [PATCH 13/16] Modified test with new renderer name --- plotly/tests/test_orca/test_sg_scraper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plotly/tests/test_orca/test_sg_scraper.py b/plotly/tests/test_orca/test_sg_scraper.py index 4c468fe9803..e53ab6b59d7 100644 --- a/plotly/tests/test_orca/test_sg_scraper.py +++ b/plotly/tests/test_orca/test_sg_scraper.py @@ -45,7 +45,7 @@ def execute_plotly_example(): def test_scraper(): from plotly.io._sg_scraper import plotly_sg_scraper # test that monkey-patching worked ok - assert plotly.io.renderers.default == 'sphinx' + assert plotly.io.renderers.default == 'sphinx_gallery' # Use dummy values for arguments of plotly_sg_scraper block = '' # we don't need actually code import tempfile From e6f183e85d7ad12777e08bd1c761feb23819e1b9 Mon Sep 17 00:00:00 2001 From: Emmanuelle Gouillart Date: Sun, 2 Jun 2019 14:15:16 +0200 Subject: [PATCH 14/16] try to fix py2 compatibility --- plotly/io/_sg_scraper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plotly/io/_sg_scraper.py b/plotly/io/_sg_scraper.py index 155158b28a4..5e57c85a5f0 100644 --- a/plotly/io/_sg_scraper.py +++ b/plotly/io/_sg_scraper.py @@ -57,7 +57,7 @@ def plotly_sg_scraper(block, block_vars, gallery_conf, **kwargs): for html, png in zip(htmls, pngs): if png not in seen: seen |= set(png) - this_image_path_png = image_path_iterator.__next__() + this_image_path_png = next(image_path_iterator) this_image_path_html = (os.path.splitext( this_image_path_png)[0] + '.html') image_names.append(this_image_path_html) From 8b87a188ea1c2a4ed45b569ba3ba98220e81c3f9 Mon Sep 17 00:00:00 2001 From: Emmanuelle Gouillart Date: Tue, 2 Jul 2019 16:36:33 +0200 Subject: [PATCH 15/16] write_html instead of offline.plot --- plotly/io/_base_renderers.py | 6 ++---- plotly/tests/test_optional/test_jupyter/package.json | 4 +--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/plotly/io/_base_renderers.py b/plotly/io/_base_renderers.py index 11a095da6a5..652bbc817ad 100644 --- a/plotly/io/_base_renderers.py +++ b/plotly/io/_base_renderers.py @@ -6,11 +6,10 @@ import os import six -from plotly.io import to_json, to_image, write_image +from plotly.io import to_json, to_image, write_image, write_html from plotly import utils, optional_imports from plotly.io._orca import ensure_server from plotly.offline.offline import _get_jconfig, get_plotlyjs -from plotly.offline import plot from plotly.tools import return_figure_from_figure_or_data ipython_display = optional_imports.get_module('IPython.display') @@ -654,6 +653,5 @@ def render(self, fig_dict): filename_html = filename_root + '.html' filename_png = filename_root + '.png' figure = return_figure_from_figure_or_data(fig_dict, True) - _ = plot(fig_dict, auto_open=False, - filename=filename_html) + _ = write_html(fig_dict, file=filename_html) write_image(figure, filename_png) diff --git a/plotly/tests/test_optional/test_jupyter/package.json b/plotly/tests/test_optional/test_jupyter/package.json index f6551f00beb..c99e7062d7a 100644 --- a/plotly/tests/test_optional/test_jupyter/package.json +++ b/plotly/tests/test_optional/test_jupyter/package.json @@ -15,8 +15,6 @@ "ecstatic": "^2.1.0", "tap-parser": "^2.0.0", "tape": "^4.6.0", - "xhr": "^2.2.2", - "electron": "^1.8.4", - "orca": "^1.2.1" + "xhr": "^2.2.2" } } From 3d881ab7248e443e9ec14c1d162a1da229fe9167 Mon Sep 17 00:00:00 2001 From: Emmanuelle Gouillart Date: Tue, 2 Jul 2019 17:55:59 +0200 Subject: [PATCH 16/16] change import order --- plotly/io/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plotly/io/__init__.py b/plotly/io/__init__.py index c0478c70ac0..7b26dbfb297 100644 --- a/plotly/io/__init__.py +++ b/plotly/io/__init__.py @@ -5,8 +5,9 @@ from ._templates import templates, to_templated +from ._html import to_html, write_html + from ._renderers import renderers, show from . import base_renderers -from ._html import to_html, write_html