-
-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Description
I've been thinking about an easy way to import and plot 3D filetypes in matplotlib for a while now, and just found the excellent meshio library which handles all the heavy lifting and file format compatibility. Filetypes supported: .inp, .msh, .avs, .cgns, .xml, .e, .exo, .f3grid, .h5m, .mdpa, .mesh, .meshb, .med, .bdf, .fem, .nas, .vol, .vol.gz, .obj, .off, .post, .post.gz, .dato, .dato.gz, .ply, .stl, .dat, .node, .ele, .svg, .su2, .ugrid, .vtk, .vtu, .wkt, .xdmf, .xmf
I think this would be a useful example to include in the gallery, and something that people would want to do quite often. But I'm not sure about our policy on adding 3rd party dependencies like this for the purposes of building the docs, and it doesn't look like the repo has seen activity over the past year.
Alternatively, I've opened up an issue over there asking if a matplotlib example could be added to the readme, and we could point to it in the 3rd party libraries. But that is less discoverable. Thoughts?
#!/usr/bin/env -S uv run --script
# /// script
# dependencies = [
# "matplotlib",
# "meshio",
# "scipy >= 1.16.0",
# "numpy",
# ]
# ///
import meshio
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
from scipy.spatial.transform import RigidTransform as RT, Rotation as R
from pathlib import Path
# Load the mesh for the Utah Teapot, can download from:
# https://graphics.stanford.edu/courses/cs148-10-summer/as3/code/as3/teapot.obj
file_path = Path(__file__).parent / "teapot.obj"
mesh = meshio.read(file_path)
points = mesh.points
faces = mesh.cells[0].data
# (Optional) adjust the location and orientation of the teapot
rotation = R.from_euler("xyz", [90, 0, 0], degrees=True)
translation = np.array([0.0, 0.0, 0.0])
transform = RT.from_components(rotation=rotation, translation=translation)
points = transform.apply(points)
# Create the matplotlib polygons
polys = Poly3DCollection(points[faces], facecolor="gray", edgecolor="k", linewidths=0.1)
# Plot the mesh
fig, ax = plt.subplots(figsize=(8, 6), subplot_kw={'projection': '3d'})
ax.add_collection3d(polys)
ax.set_aspect("equal")
ax.set(title="Utah Teapot", xlabel='X', ylabel='Y', zlabel='Z')
plt.show()