Manim: Create Math Animations With Python
Manim is a Python library for programmatic math animations. Here's how to create beautiful STEM visualizations — from basic shapes to 3D calculus animations.
Manim (Mathematical Animation Engine) is a Python library for creating precise, beautiful mathematical animations programmatically. Originally created by 3Blue1Brown for his YouTube channel, Manim Community Edition (the maintained fork) is what I use in QuantumSketch to generate STEM videos from AI prompts. Here's the complete guide.
Installation
# Manim Community Edition
pip install manim
# System dependencies (macOS)
brew install cairo ffmpeg py3cairo
# System dependencies (Ubuntu)
apt-get install libcairo2-dev libpango1.0-dev ffmpeg
Test installation:
manim --version
# Manim Community v0.18.1
Your first animation
# hello.py
from manim import *
class HelloWorld(Scene):
def construct(self):
text = Text("Hello, Manim!")
self.play(Write(text))
self.wait(2)
manim -pql hello.py HelloWorld
# -p: preview (open when done)
# -q: quality (l=low, m=medium, h=high, k=4K)
# -l: low quality (faster for testing)
Core objects: Mobjects
Everything in Manim is a Mobject (Mathematical Object):
class Shapes(Scene):
def construct(self):
# Geometric shapes
circle = Circle(radius=1, color=BLUE)
square = Square(side_length=2, color=RED)
triangle = Triangle(color=GREEN)
# Text
label = Text("Shapes", font_size=36)
# Math (LaTeX rendered)
equation = MathTex(r"e^{i\pi} + 1 = 0", font_size=48)
# Positioning
circle.move_to(LEFT * 3)
square.move_to(ORIGIN)
triangle.move_to(RIGHT * 3)
label.to_edge(UP)
equation.to_edge(DOWN)
# Animate
self.play(
Create(circle),
Create(square),
Create(triangle),
Write(label),
Write(equation),
)
self.wait(2)
Animations: the core animations
class AnimationShowcase(Scene):
def construct(self):
dot = Dot(color=YELLOW)
circle = Circle(radius=2, color=BLUE)
# Create: draws the object
self.play(Create(circle))
# Write: for text and equations
text = Text("Moving dot")
self.play(Write(text))
self.play(FadeOut(text))
# Move
self.play(Create(dot))
self.play(dot.animate.move_to(circle.point_at_angle(0)))
# Move along a path
self.play(MoveAlongPath(dot, circle), run_time=3)
# Transform: morph one object into another
square = Square(color=RED)
self.play(Transform(circle, square))
# FadeIn / FadeOut
self.play(FadeOut(dot, square))
Graphing functions
class PlotFunctions(Scene):
def construct(self):
# Create axes
axes = Axes(
x_range=[-3, 3, 1],
y_range=[-2, 2, 0.5],
axis_config={"color": GREY},
).add_coordinates()
# Plot a function
sin_graph = axes.plot(np.sin, color=BLUE, x_range=[-3, 3])
cos_graph = axes.plot(np.cos, color=RED, x_range=[-3, 3])
# Labels
sin_label = axes.get_graph_label(sin_graph, label=r"\sin(x)", x_val=2)
cos_label = axes.get_graph_label(cos_graph, label=r"\cos(x)", x_val=1.5)
self.play(Create(axes))
self.play(Create(sin_graph), Write(sin_label))
self.play(Create(cos_graph), Write(cos_label))
self.wait(2)
# Animate a moving dot along the graph
dot = Dot(color=YELLOW)
self.play(Create(dot))
self.play(
MoveAlongPath(dot, sin_graph),
run_time=4,
rate_func=linear
)
3D animations with ThreeDScene
class ThreeDSurface(ThreeDScene):
def construct(self):
self.set_camera_orientation(phi=75 * DEGREES, theta=-45 * DEGREES)
axes = ThreeDAxes()
# Parametric surface
surface = Surface(
lambda u, v: axes.c2p(u, v, np.sin(u) * np.cos(v)),
u_range=[-3, 3],
v_range=[-3, 3],
resolution=(30, 30),
fill_opacity=0.8,
)
surface.set_color_by_gradient(BLUE, GREEN)
self.play(Create(axes))
self.play(Create(surface))
# Rotate the camera
self.begin_ambient_camera_rotation(rate=0.3)
self.wait(5)
self.stop_ambient_camera_rotation()
Manim in QuantumSketch: LLM-generated animations
In QuantumSketch, Claude generates Manim code from a prompt. Key constraints I've found necessary:
SAFE_MANIM_IMPORTS = {
"manim", "numpy", "math" # nothing else allowed
}
BANNED_CALLS = {
"subprocess", "os.system", "os.popen", "exec",
"eval", "open", "__import__", "importlib"
}
MAX_SCENE_DURATION = 60 # seconds
LLM-generated Manim code runs in a Docker container with no network access. The validator catches most dangerous patterns before render.
Common LLM failures with Manim:
- Using deprecated API methods (pre-CE Manim had different method names)
- Creating
ThreeDScenewithout setting camera orientation (results in a flat view) - Not using
self.wait()at the end (video cuts off before animation completes) - Using non-existent colors (Manim has a specific color palette; random hex codes often don't work)
Rendering for production
# Medium quality (720p, good for web)
manim -qm scene.py MainScene
# High quality (1080p)
manim -qh scene.py MainScene
# 4K
manim -qk scene.py MainScene
# Output format
manim --format mp4 scene.py MainScene
manim --format gif scene.py MainScene # for sharing
For QuantumSketch's render pipeline: medium quality (-qm) at 30fps. At this setting, a 60-second animation renders in 15–45 seconds on a t3.medium.
FAQ
What is Manim? Manim (Mathematical Animation Engine) is a Python library for creating precise, programmatic mathematical animations. Originally created by 3Blue1Brown, the community-maintained fork (Manim Community Edition) is actively developed and used for STEM education.
What's the difference between Manim and Manim Community Edition? The original Manim is 3Blue1Brown's personal tool (not actively maintained for public use). Manim Community Edition (CE) is a community fork with active development, better documentation, and more stable APIs. Use Manim CE for new projects.
How long does Manim take to render? A 60-second animation at medium quality (720p) takes 15–60 seconds on a modern CPU. Complex 3D scenes with many objects take longer. High quality (1080p) takes 2–3× longer.
Can I use Manim for non-math animations? Yes — Manim handles general animations, not just math. It's excellent for any data visualization, diagram animation, or sequence that benefits from programmatic precision.
Is Manim suitable for production use? Yes — QuantumSketch uses Manim CE in production Docker containers. Key requirement: isolate Manim renders (it can execute arbitrary Python code via the scene class), use resource limits, and validate generated code before rendering.
Written by Shihab Shahriar Antor — AI Engineer & Founder of Shahriar Labs. See also: Building QuantumSketch: AI + Manim for STEM Video · Docker for AI Workloads: Isolation & GPU Access.