_SH Log's
Back to Root
EST: 5 min read

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#python#education#quantumsketch

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 ThreeDScene without 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.