How to embed Plotly graphs in Sphinx documentation and nbsphinx

Viewed 2736

I tried using nbsphinx to embed a Jupyter notebook containing plotly plots, but the plots don't show up in the documentation, even though they look fine on the Jupyter notebook.

How can I embed a plotly graph in Sphinx documentation? I could include them as images, but is there a better way? It'd be nice to have the interactivity!

What I want to do is replicate this page. It has Jupyter notebook style in and out blocks, and it shows interactive plots made using plotly. How can I do that?

GitHub issue raised here.

8 Answers

I can see two solutions to embed your notebook cells with plotly figures in a sphinx documentation.

  1. Convert the notebook to html using nbconvert or nbsphinx. Be sure to use the notebook renderer in order to include the plotly javascript bundle (maybe this was the reason why your figures did not display): see https://plot.ly/python/renderers/ for the documentation on plotly renderers. Then you can include the html in your sphinx doc with various solutions (see Include standalone HTML page in sphinx document).
  2. Use sphinx-gallery (https://sphinx-gallery.github.io/) with its plotly scraper. With sphinx-gallery you write your doc page as a python script which is converted to rest by the sphinx-gallery extension of sphinx. In order to configure the scraper see https://sphinx-gallery.github.io/advanced.html#integrate-custom-scrapers-with-sphinx-gallery. We have also a minimal repository showing how to use plotly and sphinx-gallery together in https://github.com/plotly/plotly-sphinx-gallery. https://github.com/plotly/plotly-sphinx-gallery

The graph itself is an HTML inside jupyter notebook file. You can open notebook.ipnb file in any text editor, find where HTML of the graph starts, copy all this html into html file ans save it , say a.html, and then just insert raw html in RST doc.

.. raw:: 
    :file: a.html

From Python, you can generate the HTML code to embed Plotly graphs with the plotly.tools.get_embed function.

import plotly.tools as tls

tls.get_embed('https://plot.ly/~chris/1638')

You can use the Jupyter Sphinx Extension:

.. jupyter-execute::

   import plotly.graph_objects as go

   trace = go.Scatter(
       x=[0, 1, 2, 3, 4],
       y=[0, 1, 4, 9, 16],
   )
   layout = go.Layout(title='Growth')
   figure = go.Figure(data=[trace], layout=layout)
   figure.show()

When Sphinx generate the document it doesn't describe the plotly library, so add the following line into your HTML page:

<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>

then the page will be alive again.

We had this issue for both sphinx_rtd_theme and furo theme. Because how Plotly and Sphinx themes using require.js, the default generated HTML output does not work within Sphinx context. You get various loading errors with require.js or other files.

Here is our solution:

  • Make sure your JavaScript loads at <head> in your theme. If it loads at the end of the <body> no workaround is going to work.
  • Server require.js locally from Sphinx _static folder
  • Configure require by using custom.js

Example conf.py:

html_js_files = [
    "require.min.js",  # Add to your _static
    "custom.js",
]

Example custom.js:

requirejs.config({
    paths: {
        base: '/static/base',
        plotly: 'https://cdn.plot.ly/plotly-2.12.1.min.js?noext',
    },
});

This way

  • Notebook correctly renders interactive diagrams when running in Jupyter
  • Notebook correctly renders interactive diagrams when viewed as static HTML files
  • Notebook correctly renders interactive diagrams when viewed on ReadTheDocs

See the example open-source documentation here and the example notebook.

After trying many workarounds, the solution that worked for me was to add these lines at the beginning of the notebook.

import plotly
plotly.offline.init_notebook_mode()

None of the solutions involving modifying the options nbsphinx_prolog, nbsphinx_requirejs_options and html_js_files in the conf.py, work for me.

I'm ussing the sphinx_rtd_theme html theme and the following versions:

nbsphinx==0.8.9
sphinx-autobuild==2021.3.14
sphinx==4.4.0

Try this at the top of your notebook:

import plotly.io as pio
pio.renderers.default = "sphinx_gallery"

This renderer makes sure your notebook (or cell output, or something, not sure!) includes the javascript resources that your cell output needs to render the plot.

Other renderers, or settings, might achieve this as well. But so far this is the only renderer I've tried where I can build notebooks with sphinx (jupyter book, actually), and the interactive plots show up in the build.

Related