Plotly integration¶
Embed interactive Plotly charts and graphs directly in the GUI interface.
Features:
viser.GuiApi.add_plotly()
for embedding Plotly figuresReal-time chart updates with dynamic data
Interactive charts with zoom, pan, and hover
Multiple chart types (line plots, 3D surfaces, heatmaps)
Source: examples/02_gui/08_plotly_integration.py

Code¶
1import time
2
3import numpy as np
4import plotly.express as px
5import plotly.graph_objects as go
6from PIL import Image
7
8import viser
9
10
11def create_sinusoidal_wave(t: float) -> go.Figure:
12 x_data = np.linspace(t, t + 6 * np.pi, 50)
13 y_data = np.sin(x_data) * 10
14
15 fig = px.line(
16 x=list(x_data),
17 y=list(y_data),
18 labels={"x": "x", "y": "sin(x)"},
19 title="Sinusoidal Wave",
20 )
21
22 # this sets the margins to be tight around the title.
23 fig.layout.title.automargin = True # type: ignore
24 fig.update_layout(
25 margin=dict(l=20, r=20, t=20, b=20),
26 ) # Reduce plot margins.
27
28 return fig
29
30
31def main() -> None:
32 server = viser.ViserServer()
33
34 # Plot type 1: Line plot.
35 line_plot_time = 0.0
36 line_plot = server.gui.add_plotly(figure=create_sinusoidal_wave(line_plot_time))
37
38 # Plot type 2: Image plot.
39 # Use Path to handle relative paths correctly from any working directory
40 from pathlib import Path
41
42 assets_dir = Path(__file__).parent.parent / "assets"
43 fig = px.imshow(Image.open(assets_dir / "Cal_logo.png"))
44 fig.update_layout(
45 margin=dict(l=20, r=20, t=20, b=20),
46 )
47 server.gui.add_plotly(figure=fig, aspect=1.0)
48
49 # Plot type 3: 3D Scatter plot.
50 fig = px.scatter_3d(
51 px.data.iris(),
52 x="sepal_length",
53 y="sepal_width",
54 z="petal_width",
55 color="species",
56 )
57 fig.update_layout(legend=dict(yanchor="top", y=0.99, xanchor="left", x=0.01))
58 fig.update_layout(
59 margin=dict(l=20, r=20, t=20, b=20),
60 )
61 server.gui.add_plotly(figure=fig, aspect=1.0)
62
63 while True:
64 # Update the line plot.
65 line_plot_time += 0.1
66 line_plot.figure = create_sinusoidal_wave(line_plot_time)
67
68 time.sleep(0.01)
69
70
71if __name__ == "__main__":
72 main()