stpyvista: Show PyVista 3D visualizations in Streamlit.
This is a simple component that takes a PyVista plotter object and shows it on Streamlit as an interactive element (as in it can be zoomed in/out, moved and rotated, but the visualization state is not returned). It uses PyVista’s pythreejs backend and it basically takes the plotter, exports it to HTML (https://docs.pyvista.org/api/plotting/_autosummary/pyvista.Plotter.export_html.html) and displays that within an iframe.
Installation:
pip install stpyvista
Demos:
Display your own STL file on Streamlit:
Physically Based Rendering (PBR):
Usage example:
import pyvista as pv
import streamlit as st
from stpyvista import stpyvista
# ipythreejs does not support scalar bars :(
pv.global_theme.show_scalar_bar = False
st.title("A cube")
st.info("""Code adapted from https://docs.pyvista.org/user-guide/jupyter/pythreejs.html#scalars-support""")
## Initialize a plotter object
plotter = pv.Plotter(window_size=[400,400])
## Create a mesh with a cube
mesh = pv.Cube(center=(0,0,0))
## Add some scalar field associated to the mesh
mesh['myscalar'] = mesh.points[:, 2]*mesh.points[:, 0]
## Add mesh to the plotter
plotter.add_mesh(mesh, scalars='myscalar', cmap='bwr', line_width=1)
## Final touches
plotter.view_isometric()
plotter.background_color = 'white'
## Send to streamlit
stpyvista(plotter, key="pv_cube")
Yes, all the formats supported by pyvista should be rendered by stpyvista. For creating a StructuredGrid from scratch:
Code:
import streamlit as st
import pyvista as pv
import numpy as np
from stpyvista import stpyvista
"# 🧱 Structured grid"
## Create coordinate data
x = np.arange(-10, 10, 0.25)
y = np.arange(-10, 10, 0.25)
x, y = np.meshgrid(x, y)
z = np.sin(np.sqrt(x**2 + y**2))
## Set up plotter
plotter = pv.Plotter(window_size=[600,600])
surface = pv.StructuredGrid(x, y, z)
plotter.add_mesh(surface, color='teal', show_edges=True)
## Pass the plotter (not the mesh) to stpyvista
stpyvista(plotter, key="surface")
really love it. For some reason the Slider widget is not working in streamlit, i used the example from Slider Bar Widget — PyVista 0.38.5 documentation and passed it into stpyvista. I just get the Plot but without the slider.
stpyvista takes the pyvista plotter and converts it to a panel object that is embeded within streamlit. My guess is that those sliders are not supported by panel and get stripped away, You can use regular streamlit sliders to achieve a similar behavior:
Code:
import streamlit as st
import pyvista as pv
from stpyvista import stpyvista
res = st.slider("Resolution", 5, 100, 20, 5)
p = pv.Plotter(window_size=[300,300])
sphere = pv.Sphere(phi_resolution=res, theta_resolution=res)
p.add_mesh(sphere, name='sphere', show_edges=True)
p.view_isometric()
p.set_background("white")
stpyvista(p)
import streamlit as st
import pyvista as pv
from stpyvista import stpyvista
## Initialize a plotter object
plotter = pv.Plotter(window_size=[300,600])
## Create a mesh with a cube
for i in range(1, 11):
cube = pv.Cube(center=(0, 0, i), x_length=2, y_length=2, z_length=0.8)
plotter.add_mesh(cube, edge_color='black', color='purple', opacity=i/10, show_edges=True)
## Final touches
plotter.background_color = '#dddddd'
plotter.view_isometric()
## Send to streamlit
"# 🗼 Opacity tower"
stpyvista(plotter, horizontal_align='left')
Panning is done by dragging while pressing the shift key. I am not aware of a way to reset to the initial view, other than re-rendering the element, although there is the option to set an interactive_orientation_widget = True to reset the view to a plane, i.e., xy, yz, etc.
That is one of the things that panel does not support. Axes must be passed directly as a dictionary of tickers. Check the docs here VTK — Panel v1.1.0 for details.
That’s a bug on panel’s side so will have to look for a workaround, like exporting the colors and limits of the pyvista colorbar and put them in an independent image.