Getting Started with PyVista
What is PyVista?
PyVista is a 3D data management and visualization software. PyVista extends the functionality of the open-source visualization platform the VTK by Kitware Inc.
PyVista has two main modules:
- Core module, which deals with the fundamental data structures for spatially-referenced information
- Plotting module facilitates creating of 3D visualizations of the core data structures.
Data structures
- Geometry is the collection of points and cells
- Topology defines the structure of the dataset. It defines how the points are connected with each other.
- Node data and element data are attributes associated with the nodes and cells.
PolyData
Polydata consists of any 1D or 2D geometry to construct vertices, lines, polygons, and triangles.
PolyData
can represent:
- point clouds
- Digital elevation models (DEMs)
- Sparse data
- Geospatial line sets
- Bounding sourfaces
RectilinearGrid
Implicit geometries along the x, y, and z directions that are rectangular and regular.
UniformGrid
Implicit geometries where cell sizes are uniformly assigned along each axis and the spatial reference is built out from an origin point.
StructuredGrid
A regular lattice of points aligned with an internal coordiante axes such that the connectivity can be defined by a grid ordering. Contains 2D quads or 3D hexahedrons.
UnstructuredGrid
The most general dataset type that can hold any 1D, 2D, or 3D cell geometries. Typically generated by filtering routines ans contains subsets or combinations or the above data types.
Reading Polydata
import pyvista as pv
import numpy as np
pv.set_jupyter_backend('trame')
# from pyvista import themes
pv.set_plot_theme('paraview')
dataset = [
[pv.read("equidistance-order-1.vtp"), pv.read("equidistance-order-2.vtp")],
[pv.read("equidistance-order-3.vtp"), pv.read("equidistance-order-4.vtp")],
]
for row in dataset:
for cell in row:
cell["nodeNumber"] = [f"{i+1}" for i in range(cell.n_points)]
s = (2,2)
order =[[1,2],[3,4]]
from pdb import line_prefix
pl = pv.Plotter(shape=s, border=False, border_width=5)
# pl.window_size=[1000, 1000]
# pl.theme = themes.DarkTheme()
i = -1
for row in dataset:
i = i + 1; j = -1
for cell in row:
j = j + 1
pl.subplot(i, j)
pl.add_text("order = " + str(order[i][j] ), font_size=14)
pl.add_point_labels(cell, "nodeNumber", point_size=10, font_size=16, fill_shape=False, point_color="red", text_color="black")
pl.add_points(cell, point_size=10, color="red")
cube = pv.Cube(center=(0,0,0), x_length=2, y_length=2, z_length=2)
pl.add_mesh(cube, color="lightblue", show_edges=True)
_ = pl.add_axes(line_width=3, labels_off=False)
pl.show()
pl.export_html("../../../../static/elements/hexahedron/equidistance.html")
pl.save_graphic("../figures/equidistance.svg", raster=False)
Results
Plotting structured data
from turtle import position
import pyvista as pv
import numpy as np
pv.set_jupyter_backend("trame")
# from pyvista import themes
pv.set_plot_theme("paraview")
my_prefix = "xyFacetBasis"
html_path = "../../../../static/elements/hexahedron/"
figure_path = "../figures/"
dataset = pv.read(my_prefix + ".vts")
bounds = [0,1,0,1,0,1]
clipped = dataset.clip_box(bounds)
# dataset
s = (1, 2)
pl = pv.Plotter(shape=s, border=False)
# pl.window_size = [1000, 1000]
k = 0
for i in np.arange(s[0]):
for j in np.arange(s[1]):
k += 1
pl.subplot(i, j)
pl.add_text(f"facet={k}", font_size=12)
# pl.add_mesh(
# dataset.copy(),
# scalars=f"{k}",
# color="lightblue",
# show_edges=True,
# show_scalar_bar=False,
# )
# pl.add_mesh(
# dataset,
# style="wireframe",
# color="silver",
# )
pl.add_mesh(
clipped.copy(),
scalars=f"{k}",
show_scalar_bar=False,
show_edges=True,
)
_ = pl.add_axes(
interactive=True,
line_width=2,
labels_off=False,
)
pl.cpos = [
(107.0, 68.5, 204.0),
(128.0, 86.5, 223.5),
(0.45, 0.36, -0.8),
]
# pl.link_views()
_ = pl.add_scalar_bar(
title="value",
vertical=True,
position_x=0.8,
position_y=0.2,
)
pl.show()
pl.export_html( html_path + f"/{my_prefix}.html")
pl.save_graphic( figure_path + f"{my_prefix}.svg", raster=False)
Results