Getting started
manim-marimo adds a Manim animation starter to marimo-studio. Studio builds named views of a marimo notebook, and manim-marimo's views render ManimGL scenes from the notebook's values.
Install
ManimGL renders with OpenGL, draws text with Pango, and encodes video with FFmpeg. manim-marimo renders scenes in the notebook's pixi environment, where conda-forge provides those libraries on macOS and Linux. Declare the environment in the notebook's script metadata, the # /// script block at the top of analysis.py:
# /// script
# requires-python = ">=3.10,<3.15"
# dependencies = [
# "manim-marimo[render]",
# ]
#
# [tool.pixi.workspace]
# channels = ["conda-forge"]
# platforms = ["linux-64", "linux-aarch64", "osx-64", "osx-arm64"]
#
# [tool.pixi.dependencies]
# manimpango = ">=0.6"
#
# [tool.pixi.target.linux.dependencies]
# mesalib = ">=25"
# libegl = ">=1.7"
# libgl = ">=1.7"
# fonts-conda-ecosystem = "*"
# ///| Table | Installs |
|---|---|
dependencies | manim-marimo, and through its render extra ManimGL and FFmpeg |
tool.pixi.workspace | conda-forge as the channel, and the platforms pixi solves for |
tool.pixi.dependencies | manimpango, ManimGL's text renderer, built against Pango |
tool.pixi.target.linux.dependencies | Mesa's software OpenGL and fonts |
macOS provides OpenGL itself. On Linux, manim-marimo renders through Mesa's EGL driver when no display is set, so scenes render on servers without a GPU.
Add an Animation view
Open the notebook in a pixi sandbox, with Studio and manim-marimo in the marimo server:
uvx --with manim-marimo marimo edit analysis.py --sandbox=pixi --watchuv's uvx runs marimo with manim-marimo and Studio, and needs pixi on PATH. --sandbox=pixi installs the notebook's environment and runs its kernel there. Studio runs the commands views need from the same environment first, so every scene renders with the ManimGL, Pango, and Mesa the metadata declares. The first start downloads Python and those libraries.
Click Add view, choose Manim animation in the New view dialog, give the view a title, and create it. Or create it from a terminal:
uvx --with manim-marimo \
marimo-studio view create animation --target analysis.py \
--starter manim-marimo/manim:default --title "Random walk"Studio writes the view project beside the notebook:
studio/analysis/animation/
view.toml provider = "manim-marimo/manim"
scene.py the Manim scene
index.html the page that plays the movie, headed by the title
style.css
player.js
AGENTS.md instructions for coding agentsNotebook and Preview open side by side, and Preview plays the starter's animation.
Animate a notebook value
Give the notebook a value to animate, such as a random walk:
@app.cell
def walk(np):
steps = np.random.default_rng(7).normal(size=(60, 2)) * 0.3
trajectory = steps.cumsum(axis=0)
return (trajectory,)Read it in scene.py with value():
import numpy as np
from manimlib import Scene, ShowCreation, VMobject
from manim_marimo import value
class Animation(Scene):
def construct(self):
points = np.asarray(value("trajectory", default=[[0, 0], [1, 1]]), dtype=float)
curve = VMobject()
curve.set_points_as_corners(np.column_stack((points, np.zeros(len(points)))))
self.play(ShowCreation(curve), run_time=3)
self.wait(0.5)Save the scene. Studio builds the view, renders the scene with the notebook's trajectory, and Preview plays the new movie. Run the walk cell with another seed, and the movie renders again.
Next steps
- Scenes and notebook results covers
value(),output(), andcell(). - Pages and players puts several scenes and notebook controls on one page.
- Author with agents lets a coding agent write the notebook and the scenes.