Skip to content

pyvista-blender

Render PyVista plotter scenes through Blender (bpy) for photoreal output.

Build the scene once in PyVista. Choose VTK's preview or Blender's Cycles / Eevee Next for the final render.

The shape of the API

import pyvista as pv

pl = pv.Plotter(off_screen=True, window_size=(1920, 1080))
pl.add_mesh(pv.read("data.vtu"), scalars="von_mises", cmap="viridis", pbr=True)
pl.add_light(pv.Light(position=(5, -5, 5), light_type="scene light"))
pl.camera_position = "iso"

# No `import pyvista_blender` needed, installing the package registers
# the `bpy` namespace via PyVista 0.48's plotter-component registry.
pl.blender.render("frame.png", samples=128)

For an interactive rendered viewport, pl.blender.show() replaces PyVista's VTK preview with Cycles output in the same window:

pl.blender.show()   # single window, mouse-driven, real-time Cycles

Why does this exist?

VTK's renderer is fast and interactive. Blender's Cycles produces images suitable for paper figures, presentations, and explainer videos. This library is the bridge: same scene in Python, two render quality tiers.

Features

  • Materials: PBR (Principled BSDF), Phong with Walter et al. roughness fit, unlit, double-sided. (recipe)
  • Styles: surface, wireframe, edge overlay, points, Gaussian splats as native bpy.types.PointCloud. (recipe)
  • Lights: SUN / POINT / SPOT / HEADLIGHT / CAMERA_LIGHT, the default vtkLightKit, custom rigs. (recipe)
  • Backgrounds: solid, gradient, HDRI / image-based lighting. (recipe)
  • Datasets: PolyData, UnstructuredGrid, MultiBlock, high-order cells. Point and cell scalars with colormaps and clim.
  • Volume rendering: closed-cube + Cycles Volume Principled atlas, no OpenVDB. (recipe)
  • Glyphs: Geometry-Nodes instancer (N + V verts, not N * V). (recipe)
  • HUD: scalar bars, text, axes triad, bounds box composited over Cycles. (recipe)
  • Subplots: per-tile camera / lights / HUD, PIL composited. (recipe)
  • Cameras: perspective + orthographic, user_matrix, orbit updater.
  • Animation: pl.blender.animate(...) to gif / mp4 / webm; pl.blender.export_animation_blend(...) bakes camera, deformation (MDD or shape keys), scalars, lights, transforms, materials, volumes, and glyphs into a .blend that plays natively on open. (recipe)
  • Interactive: pl.blender.show() for desktop, pl.blender.show(backend="web") for browser, with three sample tiers and idle-promotion. (recipe)
  • Jupyter: pv.set_jupyter_backend("blender") returns an inline IPython.display.Image. (recipe)
  • Authoring: pl.blender.export_blend(path) to finish the scene in Blender. (recipe)

GPU auto-detection walks OptiX, CUDA, HIP, Metal, oneAPI, CPU. Engine and device strings resolve in three tiers: per-call kwarg, component attribute (pl.blender.engine = ...), module default (pyvista_blender.config.*). The identity-keyed Level-1 cache reuses bpy.types.Mesh and material data-blocks across renders on the same plotter.

Where next