PyVista (formerly known as ‘vtki’) is a flexible helper module and a high-level API for the Visualization Toolkit (VTK). It is a streamlined interface for the VTK, enabling mesh analysis and plotting 3D figures using Python code. It was introduced by C. Bane Sullivan and Alexander A. Kaszynski in May 2019 (research paper).
Before going into the details of PyVista, let us have a brief overview of VTK.
What is Visualization Toolkit (VTK)?
VTK is an open-source software developed for image processing, dealing with 3D computer graphics and scientific visualization tasks. It provides a wide range of 2D and 3D plotting capabilities as well as widgets for 3D interaction. This cross-platform toolkit supported by the Kitware team can run on Windows, Mac, Linux and Unix.
Subscribe to our Newsletter
Join our editors every weekday evening as they steer you through the most significant news of the day, introduce you to fresh perspectives, and provide unexpected moments of joy
Your newsletter subscriptions are subject to AIM Privacy Policy and Terms and Conditions.
Visit the official website for detailed information on VTK.
Why PyVista?
VTK is a state-of-the-art toolkit comprising a C++ class library and interpreted interface layers including Java, Python and Tcl/Tk. It combines the execution speed of C++ with the fast prototyping capabilities of Python. However, applications as simple as creating a mesh object requires a lengthy code when dealt with using VTK while the same task can be done with just a few lines of more Pythonic and straightforward code using PyVista. PyVista wraps the VTK through NumPy library, and direct array access enabled through several classes and methods. It facilitates visual integration of spatial datasets, fast-paced prototyping and mesh analysis.
Practical implementation
Here, we demonstrate some use cases of PyVista which references official examples. The implementation is done using Google Colab with Python 3.7.10 and PyVista 0.29.0 versions. For each of the examples, the initial two common steps are as follows:
- Setup the environment for interactive plots
“”” Install Xvfb (X virtual framebuffer): an in-memory display server which lets you run graphical application withouting requiring a display hardware “”” !apt-get install -qq xvfb #Install PyVista library and Panel (a high-level Python library for #creating interactive dashboards and web-apps) !pip install pyvista panel -q import os #for interacting with the Operating System os.system('/usr/bin/Xvfb :99 -screen 0 1024x768x24 &') os.environ['DISPLAY'] = ':99'
IMP NOTE: Failing to set up a headless display as done in this step may cause your
Colab session to get accidentally crashed due to lack of some visualization
dependencies installed.
- Import required libraries
import numpy as np import pyvista as py import panel as pn pn.extension('vtk') #to interact with complex 3D geometry
Plot geometric objects
- Create geometric shapes using built-in methods
cy = pv.Cylinder() arw = pv.Arrow() sph = pv.Sphere() pln = pv.Plane() ln = pv.Line() bx = pv.Box() cn = pv.Cone() pg = pv.Polygon() dc = pv.Disc() #polygonal disk with a central hole
- Plot all the above shapes in a single window
#Plotter() method can be used to plot objects represented by numpy array or vtk mesh p = pv.Plotter(notebook=True, window_size=(600,400),shape=(3, 3)) #’window_size’ specifies the size of output window p.subplot(0, 0) #add disc as 1st element of 1st row p.add_mesh(dc, color="yellow", show_edges=True) p.subplot(0, 1) #add polygon as 2nd element of 1st row p.add_mesh(pg, color="yellow", show_edges=True) p.subplot(0, 2) #add cone as 3rd element of 1st row p.add_mesh(cn, color="yellow", show_edges=True) p.subplot(1, 0) #add box as 1st element of middle row p.add_mesh(bx, color="yellow", show_edges=True) p.subplot(1, 1) #add line as 2nd element of middle row p.add_mesh(ln, color="yellow", line_width=3) p.subplot(1, 2) #add plane as 3rd element of middle row p.add_mesh(pln, color="yellow", show_edges=True) p.subplot(2, 0) #add sphere as 1st element of 3rd row p.add_mesh(sph, color="yellow", show_edges=True) p.subplot(2, 1) #add arrow as 2nd element of 3rd row p.add_mesh(arw, color="yellow", show_edges=True) p.subplot(2, 2) #add cylinder as 3rd element of last row p.add_mesh(cy, color="yellow", show_edges=True) # Render all the shapes p.show()
IMP NOTE: If you miss to specify ‘notebook=True’ parameter in Plotter() method, the code cell may keep on executing for long and your Colab session ma get accidentally crashed.
Output:
Edge extraction
- Download an image of a cow from ‘examples’ module
img = examples.download_cow()
- Extract edges from surface of the downloaded mesh using extract_feature_edges()
edge = mesh.extract_feature_edges(20)
Where, 20 is the feature angle in degrees (default is 30 degrees)
- Plot the mesh with extracted edges
p = pv.Plotter(notebook=True, window_size=(600,400)) #add the downloaded mesh to the plot p.add_mesh(img, color=True) #add the extracted edges; mark them using red colored lines of width 0.5 p.add_mesh(edge, color="red", line_width=5) #camera_position() specifies coordinates of camera position of #active window p.camera_position = [(9.5, 3.0, 5.5), (2.5, 1, 0), (0, 1, 0)] p.show() #display the plot
Output:
Add floor/wall to a mesh
- Download mesh of a horse from ‘examples’ module
m = examples.download_horse()
- Plot the mesh with wall and floor added
p = pv.Plotter(notebook=True, window_size=(600,400)) #add the horse mesh to the plot p.add_mesh(m) #add floor in vertical direction so it will appear as a wall p.add_floor('-y') #add floor to negative z direction p.add_floor('-z') p.show() #display the plot
Output:
Disable mesh lighting
- Download a horse mesh from ‘examples’ module and reduce number of triangles in the mesh using decimate()
h = examples.download_horse().decimate(0.9) #Rotate the mesh about z-axis by 120 degrees h.rotate_z(-120) #’points’ property returns pointer to the points of the mesh as a numpy #object and ‘center’ returns center of the mesh h.points = (h.points - h.center) * 100 #create a copy of the mesh shifted = h.copy() #translate the position of horse by 10 points in y-direction shifted.translate((0, 10, 0))
- Plot the original and shifted mesh
p = pv.Plotter(notebook=True, window_size=(600,400)) #add the horse mesh to the plot p.add_mesh(horse, color='brown') #add translated mesh to the plot p.add_mesh(shifted, color='brown', show_edges=True, lighting=False) p.show() #display the plot
Output:
- Disable the lighting of shifted mesh by setting ‘lighting’ parameter to ‘False’
shifted.plot(notebook=True,color='brown', window_size=(600,400), lighting=False, background="white")
Output:
- Code source
- Google colab notebooks of the above implementations: Geometric objects Edge extraction Add floor/wall to mesh Disable mesh lighting
References
For an in-depth understanding of PyVista, refer to the following sources: