Mastering Manim: Create Stunning Math Animations with Python
This guide walks you through installing Manim, setting up a Python project, using the Manim Sideview preview plugin, and running a series of example scripts—including circles, squares‑to‑circles, vectors, and Boolean operations—while also covering common installation issues and integration with Cursor.
Introduction
Hello everyone, I’m Xiao Xi. If you love teaching demos but struggle with technical limits, the Manim library—designed for high‑quality math‑science videos—will become your go‑to tool.
About Manim
What is Manim?
Manim is a Python library for creating mathematical animations. Developed by 3Blue1Brown, it visualizes concepts such as vector transformations and limits in an engaging, dynamic way, filling the gap left by static textbook images.
Official Resources
Website: https://www.manim.community
Documentation: https://docs.manim.community/en/stable/
Online demo: https://hub.2i2c.mybinder.org/…/First%20Steps%20with%20Manim.ipynb
Preparation
Creating a Python Project
Use the uv tool to initialise a project and create a virtual environment:
# 初始化项目
$ uv init manim-examples
# 进入项目目录
$ cd manim-examples
# 创建并激活虚拟环境
$ uv venv && source .venv/bin/activateInstall Manim:
# 安装
$ uv add manimCreate a src folder to hold your scripts (see the image below for the resulting structure).
Adding Manim Documentation to Cursor
After adding the Manim docs URL, wait until the status turns green to confirm successful parsing.
Installing the Manim Sideview Plugin
Manim Sideview provides an in‑IDE preview, eliminating the need to run commands manually.
Official Examples
Below are several basic Manim scripts that demonstrate core functionality.
Circle Animation
from manim import *
class CreateCircle(Scene):
def construct(self):
circle = Circle()
circle.set_fill(PINK, opacity=0.5)
self.play(Create(circle))Run the script: $ manim -pql create_circle.py CreateCircle Command‑line flags:
-p Play the scene after rendering.
-ql Low quality (854×480 15 FPS).
-qm Medium quality (1280×720 30 FPS).
-qh High quality (1920×1080 60 FPS).
-qp 2K quality (2560×1440 60 FPS).
-qk 4K quality (3840×2160 60 FPS).
The output file is .mp4 by default; add --format gif to produce a GIF.
$ manim -pql create_circle.py CreateCircle --format gifSquare to Circle Transformation
from manim import *
class SquareToCircle(Scene):
def construct(self):
square = Square()
square.rotate(PI/4)
circle = Circle()
circle.set_fill(PINK, opacity=0.5)
self.play(Create(square))
self.play(Transform(square, circle))
self.play(FadeOut(circle))Alternative .animate syntax is also shown in the source.
Vector Coordinates
from manim import *
class VectorArrow(Scene):
def construct(self):
dot = Dot(ORIGIN)
arrow = Arrow(ORIGIN, [2, 2, 0], buff=0)
number_plane = NumberPlane()
origin_label = Text("(O,0)").next_to(dot, DOWN)
arrow_label = Text("(2,2)").next_to(arrow.get_end(), RIGHT)
self.add(number_plane, dot, arrow, origin_label, arrow_label)Boolean Operations
from manim import *
class BooleanOperations(Scene):
def construct(self):
ellipse1 = Ellipse(width=4.0, height=5.0, fill_opacity=0.5, color=BLUE, stroke_width=10).move_to(LEFT)
ellipse2 = ellipse1.copy().set_color(RED).move_to(RIGHT)
bool_ops_text = MarkupText("<u>Boolean Operation</u>").next_to(ellipse1, UP*3)
ellipse_group = Group(bool_ops_text, ellipse1, ellipse2).move_to(LEFT*3)
self.play(FadeIn(ellipse_group))
i = Intersection(ellipse1, ellipse2, color=GREEN, fill_opacity=0.5)
self.play(i.animate.scale(0.25).move_to(RIGHT*5 + UP*2.5))
intersection_text = Text("Intersection", font_size=23).next_to(i, UP)
self.play(FadeIn(intersection_text))
u = Union(ellipse1, ellipse2, color=ORANGE, fill_opacity=0.5)
union_text = Text("Union", font_size=23)
self.play(u.animate.scale(0.3).next_to(i, DOWN, buff=union_text.height*3))
union_text.next_to(u, UP)
self.play(FadeIn(union_text))
e = Exclusion(ellipse1, ellipse2, color=YELLOW, fill_opacity=0.5)
exclusion_text = Text("Exclusion", font_size=23)
self.play(e.animate.scale(0.3).next_to(u, DOWN, buff=exclusion_text.height*3.5))
exclusion_text.next_to(e, UP)
self.play(FadeIn(exclusion_text))
d = Difference(ellipse1, ellipse2, color=PINK, fill_opacity=0.5)
difference_text = Text("Difference", font_size=23)
self.play(d.animate.scale(0.3).next_to(u, LEFT, buff=difference_text.height*3.5))
difference_text.next_to(d, UP)
self.play(FadeIn(difference_text))Using Manim in Cursor
Lever Principle Demo
Prompt Cursor with a request to generate a lever‑principle animation, then adjust layout and text size when overlapping occurs.
Mathematical Formula Derivation
Prompt Cursor to animate the expansion of (a+b)², iterate through feedback cycles, and obtain basic, enhanced, and interactive versions.
Project Repository
The full example repository is available at https://github.com/MisterZhouZhou/manim-examples .
Common Issues
No package Cairo found
Install Cairo and pkg‑config via Homebrew:
brew install cairo pkg-configNo such file or directory: latex
Manim requires a LaTeX distribution. On macOS you can install a minimal TeX Live with:
sudo tlmgr install amsmath babel-english cbfonts-fd cm-super count1to ctex doublestroke dvisvgm everyhook fontspec frcursive fundus-calligra gnu-freefont jknapltx latex-bin mathastex microtype multitoc physics preview prelim2e ragged2e relsize rsfs setspace standalone tipa wasy wasysym xcolor xetex xkeyvalSigned-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
