PyVista and Sphinx#
Leverage PyVista to make some awesome interactive web documentation.
Tip
This section of the tutorial was adopted from Plotting Themes and Sphinx PyVista Plot Directive chapter of the PyVista documentation.
Dynamically Generating 3D Plots in your Documentation#
PyVista allows you to generate static or dynamic images directly within Sphinx much like the Matplotlib plot_directive. Rather than manually creating and adding plots after code sections, you can instead dynamically generate images and embed them directly within your documentation. This also works seamlessly with sphinx-gallery, so you can create notebook examples just like the Matplotlib Example Gallery.
As an added side benefit, you can be sure that the documentation you generate matches your project API. If you include this within a GitHub Workflow
This section covers the following topics.
Static Plotting - Sphinx PyVista Plot Directive#
You can generate static images of PyVista plots within sphinx using the
pyvista-plot
directive by adding the following to your conf.py
when building your documentation using Sphinx.
extensions = [
"sphinx.ext.napoleon",
"pyvista.ext.plot_directive",
]
You can then issue the plotting directive within your sphinx documentation files:
.. pyvista-plot::
:caption: A sphere
:include-source: True
>>> import pyvista
>>> sphere = pyvista.Sphere()
>>> out = sphere.plot()
Which will be rendered as:
>>> import pyvista
>>> sphere = pyvista.Sphere()
>>> out = sphere.plot()

This is a default sphere#
Dynamic Plotting Using the Jupyter Sphinx Extension#
PyVista also supports the jupyter-sphinx extension. With this extension you
can execute code blocks within a sphinx *.rst
file using the
jupyter-execute
directive:
.. jupyter-execute::
name = 'world'
print('hello ' + name + '!')
Will be rendered as:
name = 'world'
print('hello ' + name + '!')
hello world!
Likewise, output from PyVista that would normally be rendered within a notebook
will be rendered in the output cell from the jupyter-execute
directive. For
example, here’s a plot using the pythreejs backend:
.. jupyter-execute::
from pyvista import examples
dataset = examples.download_urn()
dataset.plot(color='tan', jupyter_backend='pythreejs', window_size=(700, 400))
Which is rendered as:
from pyvista import examples
dataset = examples.download_urn()
dataset.plot(color='tan', jupyter_backend='pythreejs', window_size=(700, 400))
Using the Panel
backend with PyVista#
PyVista supports the usage of the panel
library as a vtk.js
jupyterlab plotting backend that can be utilized as
either a standalone VTK viewer, or as a tightly integrated pyvista
plotting
backend. For example, within a Jupyter notebook environment, you can pass
jupyter_backend='panel'
to plot
, or Plotter.show
to automatically
enable plotting with Juptyer and panel
.
For example, here’s the PyVista
logo:
.. jupyter-execute::
from pyvista import demos
demos.plot_logo(background='white', jupyter_backend='panel')
Which is shown within the documentation as:
from pyvista import demos
demos.plot_logo(background='white', jupyter_backend='panel')
Examples and Usage#
There are two ways to use panel within
Jupyter notebooks. You can use it on a plot by plot basis by setting the
jupyter_backend
in mesh.plot()
:
.. jupyter-execute::
import pyvista as pv
from pyvista import examples
# create a point cloud from lidar data and add height scalars
dataset = examples.download_lidar()
point_cloud = pv.PolyData(dataset.points[::100])
point_cloud['height'] = point_cloud.points[:, 2]
point_cloud.plot(window_size=[500, 500],
jupyter_backend='panel',
cmap='jet',
point_size=2,
background='w')
And here’s the resulting output in Sphinx:
import pyvista as pv
from pyvista import examples
# create a point cloud from lidar data and add height scalars
dataset = examples.download_lidar()
point_cloud = pv.PolyData(dataset.points[::100])
point_cloud['height'] = point_cloud.points[:, 2]
point_cloud.plot(window_size=[500, 500],
jupyter_backend='panel',
cmap='jet',
point_size=2,
background='w')
Or you can first hide code that sets up the plotting backend and global theme:
.. jupyter-execute::
:hide-code:
import pyvista as pv
# Set the global jupyterlab backend. All plots from this point
# onward will use the ``panel`` backend and do not have to be
# specified in ``show``
pv.set_jupyter_backend('panel')
And now just directly execute plot
on any dataset:
.. jupyter-execute::
from pyvista import examples
dataset = examples.download_dragon()
dataset.plot(cpos="xy")
Which looks like:
from pyvista import examples
dataset = examples.download_dragon()
dataset.plot(cpos="xy")