Choosing your plotting backend#

DiffeRT supports various backends for plotting scenes and related-objects:

  • VisPy, a high-performance interactive visualization library that leverages the power of modern GPUs through OpenGL. Installing VisPy on its own is not sufficient and you will need at least one of the VisPy backends to be installed: https://vispy.org/installation.html. If available, VisPy will be used by default as it provides the best user experience, especially on large scenes.

  • Matplotlib, a very user-friendly and popular tool for creating plots in Python.

  • Plotly, a Python library for building beautiful interactive plots for the web.

Additionally, all those backends can be used within Jupyter notebooks. For VisPy, you will need jupyter_rfb and a recent JupyterLab installation, that you can obtain with pip install differt[jupyter].

from differt.geometry import TriangleMesh

mesh_file = "bruxelles.obj"
mesh = TriangleMesh.load_obj(mesh_file)

VisPy#

VisPy is the default plotting backend, and supports all plotting utilities.

Because this is the default backend, you do not have to specify it, unless you changed the default backend.

Pros#

  • Performances;

  • Has a relatively good documentation;

  • Integrates well with Qt applications;

  • Implements all plotting utilities.

Cons#

  • Does not support interactive offline rendering (i.e., a static snapshot is shown);

  • Requires an additional and possibly large dependency (e.g., PyQt6).

canvas = mesh.plot(backend="vispy")
canvas
WARNING: QOpenGLWidget is not supported on this platform.
snapshot

Matplotlib#

Matplotlib is probably the most-used Python plotting library.

Pros#

  • Has excellent online documentation;

  • Can be integrated with Qt applications;

  • Support a lot of configuration options and output formats;

  • Simple and user-friendly API.

Cons#

  • Does not support interactive offline rendering (i.e., a static snapshot is shown);

  • Poor 3D graphics support;

  • Interactive and 3D plots are slow.

%matplotlib widget

fig = mesh.plot(
    backend="matplotlib", alpha=0.5, shade=True, linewidth=0.2, antialiased=True
)
fig.gca().axis("equal");
Figure

Plotly#

Pros#

  • Has excellent interactive mode;

  • Provides beautiful plots with almost zero-configuration needed;

  • Supports interactive offline rendering (i.e., plots can be fully contained in HTML pages).

Cons#

  • Has a no-so-good online documentation (i.e., using functions that do not have usage examples is quite hard);

  • Does not support interactive offline rendering (i.e., a static snapshot is shown);

  • Slow 3D graphics and relatively glitchy.

fig = mesh.plot(backend="plotly", opacity=0.5)
fig.update_scenes(aspectmode="data")

Changing the default backend#

When not specified, the backend parameter defaults to None, which in turn indicates that you will use the default backend. So mesh.plot() is equivalent to mesh.plot(backend="vispy").

If you want to use another backend by default, you can do so by importing differt.plotting and calling use with the desired backend name.

import differt.plotting as dplt

dplt.set_defaults("plotly")

fig = mesh.plot(opacity=0.5)
fig.update_scenes(aspectmode="data")

Composing with multiple plot utilities#

Of course, using a single plot function is often not enough to reach the desired output.

Each of the backends we support provides a way to easily reuse the previous plot to draw additional content on top, see differt.plotting’s documentation for more details.

Below, we show how to add a 2D heatmap on the ground[1] of our scene.

import numpy as np

vx = mesh.vertices[..., 0]
vy = mesh.vertices[..., 1]
x = np.linspace(np.min(vx), np.max(vx))
y = np.linspace(np.min(vy), np.max(vy))
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)

dplt.draw_image(data=Z, x=x, y=y, z0=1.0, figure=fig)