🧊 stpyvista: Show PyVista 3D visualizations in Streamlit

:ice_cube: stpyvista: Show PyVista 3D visualizations in Streamlit.

Github Repo PyPi version Github tests repo

howto-stpyvista
Streamlit App

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:

:outbox_tray: Display your own STL file on Streamlit:

uploadstl-stpyvista

Streamlit App

:bread: Physically Based Rendering (PBR):

textures-stpyvista

Streamlit App


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")

Result:


Also check:

8 Likes

Great job @edsaac !

Feel free to add it to the Components Tracker: Streamlit Components - Community Tracker so we don’t lose track of it!

Have a nice day,
Fanilo

Really cool! Well done!

Very nice work.

I have an curved sufrace object. Can I use the stpyvista to show curvsurf object on streamlit?

ex)
curvsurf = pv.StructuredGrid(xx, yy, zz)

Have a nice day,
kotai2003

Yes, all the formats supported by pyvista should be rendered by stpyvista. For creating a StructuredGrid from scratch:

structuredGrid


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")
1 Like

Thanks so much. Your stpyvista is really awesome!

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:

stpyvista_sphere_slider

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)

love it, thank you!

@edsaac, Is there a way to make the cube transparent?

Sure, you are probably looking for the opacity argument in pyvista.Plotter.add_mesh.

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')
1 Like

@edsaac, this is very useful. I think I will use stpyvista. I have a few questions.

  • I wonder if there is a way to add panning and home button to reset to initial view similar to mpld3 below?
  • Is there a way to rotate cubes as they go up?
  • why isn’t plotter.add_axes not working to show XYZ Coordinates? I used it this way: _ = plotter.add_axes(line_width=5, labels_off=False)

fig_html = mpld3.fig_to_html(fig)
components.html(fig_html, width=width, height=height)

  • 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.

  • Sure! That’s a common transformation in pyvista. For example, check pyvista.DataSet.rotate_x — PyVista 0.39.1 documentation .

  • 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.
    image


I’ve updated a few examples at stpyvista’s demo at https://stpyvista.streamlit.app/

Does someone know how to visualize the colorbar?
plotter.add_scalar_bar() doesn’t seem to work for me.

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.

1 Like

Thank you!

@m_b_33, colorbars are displayed using old versions of holoviz stuff:

panel==0.14.4
bokeh==2.4.3
param==1.12.0

That would be the temporary solution while the issue is addressed (#5809)

The bug has been fixed in panel 1.3.2 :tada: