Skip to main content

pyvista-blender

Render PyVista plotter scenes through Blender (bpy) — photoreal output, full animation export, no file round-trip.

Build the scene once in PyVista. Pick VTK's preview or Blender's Cycles / Eevee Next for the final render. Export entire deforming, colour-evolving, lit animations to a single .blend that plays natively in Blender with no Python script inside.

Showcase

These structural mechanics examples start as PyVista scenes and use Blender for the final render. The transparent animated WebP previews link to the transparent VP9 WebM files.

I-beam bending stress animation Gyroid compression stress animation
I-beam bending
Fedoo stress animation with support and load geometry.
Gyroid compression
Metallic gyroid material revealed through a stress-alpha overlay.

Status

Initial public release (0.1.0). The offline render path, the desktop and browser interactive viewports, the Jupyter inline backend, and the full animation export to .blend are implemented and tested. The full ruff (select = ["ALL"]) + ty + format gate is clean. See the features list in the docs for the full surface and the architecture page for the translation pipeline.

Install

pip install pyvista-blender
# or
uv add pyvista-blender

For the Jupyter inline backend and the Trame-served browser viewport (pl.blender.show(backend="web")), install pyvista[jupyter] alongside; the bridge reuses pyvista's Trame stack rather than shipping its own extras.

pip install pyvista-blender 'pyvista[jupyter]'

Requires Python 3.11 (Blender 4.5 LTS via bpy>=4.5,<5) or 3.13 (Blender 5.x via bpy>=5.0,<6). Python 3.10, 3.12, and 3.14 have no matching bpy wheel on PyPI; requires-python blocks them.

Quick start

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"

# Offline render via Cycles + OptiX denoise. No `import pyvista_blender`
# needed — the namespace registers itself on install through PyVista
# 0.48's plotter-component entry point.
pl.blender.render("frame.png", samples=128)

# Interactive hybrid viewport: VTK 60 fps during drag, Cycles render
# on mouse release. One window, mouse-driven, no auto-exec prompts.
pl.blender.show()

API surface

Entry point What it does
pl.blender.render(path, ...) Render a single frame to PNG via Cycles or Eevee Next.
pl.blender.animate(path, updater, frames, fps=...) Render an animation as gif / mp4 / webm / mov / mkv via imageio + imageio-ffmpeg.
pl.blender.show() Hybrid VTK / Cycles interactive viewport — VTK during drag, settled Cycles on release.
pl.blender.add_glyph(source, geom, *, orient, scale, factor) Geometry-Nodes-instanced glyphs; memory cost scales N + V instead of N · V.
pl.blender.export_blend(path) Save the live PyVista scene as a .blend for finishing in Blender.
pl.blender.export_animation_blend(path, updater, frames, fps, **bake) Bake a full animation into a .blend that plays natively on file open.
pl.blender.orbit_camera(n_frames=...) Build an updater for animate / export_animation_blend.

Three-tier config resolution everywhere: per-call kwarg → component attribute (pl.blender.engine = ...) → module default (pyvista_blender.config.*).

Animation export to .blend

export_animation_blend bakes each animation channel through its own opt-in kwarg. Every backend plays back natively when the file is opened in Blender — no Python in the .blend, no auto-execution prompt, no need to "Run Scripts" on load.

Kwarg Mechanism File layout
bake_camera=True (default) Keyframes on scene.camera.location + rotation_quaternion per frame inside .blend
bake_deformation="shape_keys" One Shape Key per frame, value-keyframed with linear interpolation inside .blend
bake_deformation="mdd" (= True) Lightwave MDD sidecar + MESH_CACHE modifier .blend + __<mesh>.mdd
bake_scalars=True Packed PNG (rows = frames, columns = vertices / cells) + Geometry Nodes graph; works for point-data and cell-data scalars inside .blend
bake_lights=True Per-light keyframes on location, rotation, energy, color inside .blend

Example: full multi-channel animation in one self-contained file.

import numpy as np
import pyvista as pv

pl = pv.Plotter(off_screen=True, window_size=(1280, 720))
plane = pv.Plane(i_resolution=60, j_resolution=60)
plane.cell_data["heat"] = np.zeros(plane.n_cells, dtype=np.float32)
pl.add_mesh(plane, scalars="heat", cmap="inferno", clim=[-1.0, 1.0])

light = pv.Light(position=(5, 0, 4), light_type="scene light", intensity=1.0)
pl.add_light(light)

n_frames = 60
orbit = pl.blender.orbit_camera(n_frames=n_frames)
centers_xy = plane.cell_centers().points[:, :2]


def update(frame: int) -> None:
    orbit(frame)
    angle = -frame * (2.0 * np.pi / n_frames)
    light.position = (5.0 * np.cos(angle), 5.0 * np.sin(angle), 5.0)
    light.intensity = 0.4 + 0.6 * (0.5 + 0.5 * np.sin(frame * 0.3))
    r = np.linalg.norm(centers_xy, axis=1)
    plane.cell_data["heat"] = np.sin(2.0 * r - frame * 0.2).astype(np.float32)


pl.blender.export_animation_blend(
    "scene.blend",
    update,
    frames=range(n_frames),
    fps=30,
    bake_camera=True,
    bake_lights=True,
    bake_scalars=True,
)
pl.close()

Open scene.blend in Blender 4.5+ / 5.x and press Space: camera orbits, the explicit light orbits in the opposite direction while pulsing, the heat field travels as a radial wave with flat per- cell shading. One file, ~500 KB, nothing to ship alongside.

Development

uv sync --group dev --no-install-package bpy  # fast local sync (no 200 MB bpy wheel)
uvx prek install                              # install pre-commit hooks
uv run pytest                                 # ~10 s with bpy installed
uv run ruff check src/ tests/
uv run ruff format --check src/ tests/
uv run ty check

Real bpy is only needed for the @pytest.mark.bpy tests. CI runs the full suite against the live wheel.

License

GPL-3.0-or-later. Forced by bpy's license; every source file carries an SPDX header. See LICENSE.

Metadata

Release files for pyvista-blender 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyvista-blender 0.1.0
File Size Uploaded
pyvista_blender-0.1.0.tar.gz 136.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyvista-blender 0.1.0
File Interpreter ABI Platform
pyvista_blender-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 292.2 kB

Release files / pyvista_blender-0.1.0.tar.gz

Download URL pyvista_blender-0.1.0.tar.gz
Size 136.0 kB
Tags Source
SHA-256 checksum
How to use checksums
00cb7e52aee3485ff9670bd1ebe4a3724489644d6675852ccba39cafcaad7ca0
BLAKE2b-256 checksum
How to use checksums
cbc2acf1f432f2936ce142ab4784b9d3f555c8221130e3e56649804e3b1fe0f9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 6, 2026.

Transparency log

Release files / pyvista_blender-0.1.0-py3-none-any.whl

Download URL pyvista_blender-0.1.0-py3-none-any.whl
Size 156.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6d0bf07dfdda51af183c6d3166bc86dfbc0e8a2a5bd5b66ee72e1d247924b727
BLAKE2b-256 checksum
How to use checksums
94f5d08defd5bfdcc4933da36edc0c8beb143e8cd583450bc503fb899d4caec4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 6, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page