Manim:用 Python 搭一条数学动画视频生产线
如果你记得“有一个 Python 工具专门做数学动画、数学类视频动画”,大概率说的就是 Manim。它最早因为 3Blue1Brown 的数学解释视频而出圈,现在更推荐使用社区维护的 Manim Community Edition(Manim CE):包名是 manim,源码在 ManimCommunity/manim,定位是“用程序精确生成解释型数学视频的动画引擎”。
这篇文章不只回答“Manim 是什么”,还回答一个更工程化的问题:如果我们要真正做视频,应该怎么把 Manim 放进一条完整的视频生产流?
Manim 的创作入口是 Python:你写 Scene、Mobject 和 self.play();但完整视频生产不是 pure Python-only。它还依赖 Cairo/Pango、FFmpeg/PyAV、LaTeX、dvisvgm 等图形、排版和视频组件。最稳的工程路线是:先写叙事脚本和场景清单,再用 manim -ql 快速迭代,最后用 manim -qh 渲染高清片段,并用 FFmpeg 做拼接、配音和最终交付。
Manim 是哪一个项目
今天说 Manim,先要区分两个常见来源:
| 名称 | 说明 | 适合谁 |
|---|---|---|
| Manim Community Edition / Manim CE | 社区维护版本,PyPI 包名 manim,文档和安装体验更完整 | 大多数新用户、课程视频、工程化使用 |
3b1b/manim | Grant Sanderson / 3Blue1Brown 早期自用和持续维护的分支 | 想研究 3Blue1Brown 内部创作方式的人 |
本文默认讨论 Manim CE。截至本文写作时,PyPI 和 GitHub release 快照显示当前版本是 0.20.1,requires-python 是 >=3.11,许可证是 MIT。
官方入口:
- 项目主页:https://www.manim.community/
- 文档:https://docs.manim.community/
- GitHub:https://github.com/ManimCommunity/manim
- PyPI:https://pypi.org/project/manim/
它解决的不是“剪视频”,而是“精确生成画面”
Manim 最适合的场景不是 vlog 剪辑,也不是把素材拖进时间线。它的核心价值是:用代码精确描述数学对象、图形关系和动画过程。
典型场景包括:
- 公式推导:让每一步变形都有视觉对应;
- 几何直觉:点、线、圆、坐标系、向量、曲线、面积逐步出现;
- 算法可视化:数组、图、树、状态转移、搜索过程;
- 数据故事:坐标轴、曲线、柱状图、计数器和动态标注;
- 技术解释:架构图、流程图、状态机、协议交互。
一个简单的心智模型是:
Scene 是舞台
Mobject 是舞台上的对象
Animation 是对象如何变化
Renderer 把变化逐帧画出来
SceneFileWriter 把帧和片段写成视频
用户主要写的是 Python,但最终产物是图片、GIF 或 MP4。
最小 Manim 脚本长什么样
下面是 Manim README 里 SquareToCircle 思路的最小形态:
from manim import *
class SquareToCircle(Scene):
def construct(self):
circle = Circle()
square = Square()
circle.set_fill(PINK, opacity=0.5)
self.play(Create(square))
self.play(Transform(square, circle))
self.play(FadeOut(square))
保存成 example.py 后运行:
manim -ql example.py SquareToCircle
这里的 -ql 是 low quality,适合草稿预览。正式渲染再换成 -qh 或更高质量。
Manim 的好处是这个例子可以一路扩展:把 Square() 换成 MathTex()、Axes()、NumberPlane()、Graph、VGroup,再用 TransformMatchingTex、ValueTracker、always_redraw 等机制,就能做出真正像数学解释视频的动态画面。
它为什么不是 pure Python-only
Manim 给人的第一印象是“Python 工具”,这没错,但容易误解成“只要 pip install 一个包就万事大吉”。真实情况是:Manim CE 的 Python 包只是一层创作和编排入口,底层还会用到多类外部组件。
| 层 | 组件 | 作用 |
|---|---|---|
| Python 创作层 | manim、numpy、scipy、click 等 | 定义 Scene、对象、动画、CLI |
| 图形渲染层 | Cairo、Pango、pycairo、manimpango | 画矢量图形、文字、路径、形状 |
| 数学公式层 | LaTeX、dvisvgm | 把 MathTex / Tex 变成 SVG,再放回场景 |
| 视频编码层 | FFmpeg / PyAV | 写 partial movie files,合成最终视频 |
| 可选交互层 | OpenGL / moderngl | 交互预览、部分 3D 和 OpenGL renderer |
这也是为什么 Linux 上安装 Manim 时,最容易卡在 pycairo 或 manimpango:它们可能需要系统里的 Cairo/Pango 开发头文件。
在 Ubuntu 22.04 类环境里,一组比较稳的依赖是:
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \
libcairo2-dev libpango1.0-dev pkg-config \
ffmpeg dvisvgm texlive-latex-extra latexmk
如果安装时报:
RequiredDependencyException: pangocairo >= 1.30.0 is required
No package 'pangocairo' found
通常不是 Python 代码写错,而是系统缺 libpango1.0-dev / pkg-config / Cairo-Pango 相关开发包。我们在一台 Ubuntu 22.04 服务器上实测时,也正是在补齐 Cairo/Pango 开发依赖后,uv pip install manim 才顺利完成。
Manim 内部渲染链路
从用户角度看,只是运行一条命令:
manim -ql script.py SceneName
但内部大致会经过这条链路:
关键文件在 Manim CE 源码里也能对应起来:
| 环节 | 典型源码位置 | 说明 |
|---|---|---|
| CLI 入口 | manim/__main__.py、manim/cli/render/commands.py | 解析命令、加载 Python 文件、选择 Scene |
| 用户舞台 | manim/scene/scene.py | Scene.render() 调用 setup()、construct()、tear_down() |
| 默认渲染器 | manim/renderer/cairo_renderer.py | 默认 Cairo 路线,把对象捕获成帧 |
| 文件输出 | manim/scene/scene_file_writer.py | 写 partial movie files、合并视频、保存字幕和片段 |
| TeX 管线 | manim/utils/tex.py、manim/utils/tex_file_writing.py | LaTeX -> dvisvgm -> SVG -> Manim mobject |
所以更准确的说法是:Manim 是一套数学动画的 Python 编排层、对象系统和渲染流程管理器;底层图形、公式和编码由外部工具共同完成。
一条完整的视频生产流
如果只是试 Manim,写一个 example.py 就够了。但如果目标是“做一条可以持续产出数学类视频的流水线”,建议从一开始就按项目组织。
manim-video-project/
plan.md # 叙事目标、受众、场景列表、视觉语言
script.py # 一个 class 对应一个 Scene
assets/ # 图片、音频、字体、外部素材
media/ # Manim 自动生成,不手写
renders/ # 最终收敛出来的可交付版本
concat.txt # FFmpeg 拼接清单
final.mp4 # 最终视频
整体流程可以按这七步走:
Step 1:先写 plan.md
Manim 最大的坑不是语法,而是“直接开写代码”。数学动画首先是解释,不是 API 展示。
一个可用的 plan.md 至少应该包含:
# 视频主题
## 观众是谁
## 这条视频要回答的问题
## 一句话结论
## 场景列表
### Scene 1:提出问题
- 画面:
- 旁白:
- 关键对象:
- 预计时长:
### Scene 2:建立直觉
...
## 视觉规范
- 背景色:
- 主色:
- 强调色:
- 字体:
- 公式大小:
## 最终输出
- 分辨率:
- 是否配音:
- 是否字幕:
写 plan.md 的目的,是在代码前先确定:观众应该先看到什么、什么时候出现公式、哪个时刻是 aha moment、哪些信息必须淡化成背景。
Step 2:写一个可扩展的 script.py
建议一个 Scene 一个 class,并且所有 Scene 都能独立渲染:
from manim import *
BG = "#1C1C1C"
PRIMARY = "#58C4DD"
SECONDARY = "#83C167"
ACCENT = "#FFFF00"
class Scene1Opening(Scene):
def construct(self):
self.camera.background_color = BG
title = Text("为什么公式会动起来?", font_size=44, color=PRIMARY)
subtitle = Text("Manim = Python + 数学对象 + 渲染管线", font_size=28, color=SECONDARY)
group = VGroup(title, subtitle).arrange(DOWN, buff=0.4)
self.play(Write(title), run_time=1.2)
self.play(FadeIn(subtitle, shift=UP), run_time=0.8)
self.wait(1.0)
self.play(FadeOut(group), run_time=0.5)
class Scene2Formula(Scene):
def construct(self):
self.camera.background_color = BG
formula = MathTex(r"e^{i\pi}+1=0", font_size=72, color=ACCENT)
note = Text("公式先由 LaTeX 排版,再进入 Manim 场景", font_size=26, color=SECONDARY)
note.next_to(formula, DOWN, buff=0.5)
self.play(Write(formula), run_time=1.5)
self.wait(0.8)
self.play(FadeIn(note), run_time=0.8)
self.wait(1.2)
self.play(FadeOut(VGroup(formula, note)), run_time=0.5)
注意几个习惯:
MathTex用 raw string:r"...";- 每个关键动画后留
self.wait(),否则视频会像 PPT 自动翻页; - 先用统一颜色常量,不要每个 Scene 随手换颜色;
- 场景结尾清理对象,方便后续拼接;
- 低质量草稿时只渲染当前 Scene,不要每次全量高清。
Step 3:草稿渲染只用 -ql
开发时最常用命令是:
manim -ql script.py Scene1Opening
manim -ql script.py Scene2Formula
也可以一次渲染多个场景:
manim -ql script.py Scene1Opening Scene2Formula
-ql 的意义是“快速暴露问题”:布局是否拥挤、公式是否太小、节奏是否太快、颜色是否刺眼、对象是否重叠。不要一开始就 -qh,高清渲染会把迭代速度拖慢。
Step 4:用 still frame 检查关键画面
对于复杂场景,先导出最后一帧或关键帧比反复看视频更快:
manim -ql -s script.py Scene2Formula
这适合检查:
- 公式有没有溢出画面;
- 中文字体是否可用;
- label 和 arrow 是否遮挡;
- 坐标轴和网格是否太亮;
- 画面中心是否被太多对象占满。
Step 5:高清渲染只在收敛后做
草稿稳定后,再用:
manim -qh script.py Scene1Opening Scene2Formula
一般经验:
| 质量 | 用途 |
|---|---|
-ql | 日常开发、快速预览 |
-qm | 中等质量 review |
-qh | 正式 1080p 输出 |
-qk | 4K 或高质量 archive,成本更高 |
如果视频由多个 Scene 组成,建议每个 Scene 独立可渲染,最后再拼接。这样某个 Scene 改坏了,不会影响整条视频的迭代。
Step 6:用 FFmpeg 做拼接、配音和封装
Manim 会为每个 Scene 输出视频文件。最终交付通常还需要 FFmpeg:
media/videos/script/1080p60/Scene1Opening.mp4
media/videos/script/1080p60/Scene2Formula.mp4
准备 concat.txt:
file 'media/videos/script/1080p60/Scene1Opening.mp4'
file 'media/videos/script/1080p60/Scene2Formula.mp4'
拼接:
ffmpeg -y -f concat -safe 0 -i concat.txt -c copy renders/final-no-audio.mp4
如果有配音:
ffmpeg -y \
-i renders/final-no-audio.mp4 \
-i assets/narration.wav \
-c:v copy -c:a aac -shortest \
renders/final.mp4
如果要做字幕,Manim 自身支持 subcaption;也可以在后处理阶段把 .srt 或 .vtt 作为独立字幕文件交付。工程上建议保留两层:
assets/narration-script.md # 人类可读旁白稿
assets/subtitles.srt # 可机读字幕
renders/final.mp4 # 最终视频
Step 7:最后做人工 review
Manim 视频最容易出现的问题不是“跑不起来”,而是“能跑但不好看”。正式交付前至少检查:
- 第一屏是否 3 秒内说明主题;
- 公式是否先有直觉再出现;
- 关键对象是否有视觉层级,而不是全部满亮;
- 每个动作后是否留了理解时间;
- 字幕、旁白和动画是否同步;
- 最终 MP4 是否能在目标平台正常播放。
一个可复用的最小环境搭建
如果是服务器或 CI 环境,我更推荐显式创建 venv,而不是污染全局 Python。
mkdir manim-video-project
cd manim-video-project
uv venv .venv --python 3.12
source .venv/bin/activate
uv pip install manim
manim --version
如果没有 uv,也可以用标准 venv:
python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install -U pip
python -m pip install manim
python -m manim --version
服务器上最好再做一个 smoke:
from manim import *
class SmokeScene(Scene):
def construct(self):
title = Text("Manim smoke test", font_size=40)
formula = MathTex(r"e^{i\pi}+1=0", font_size=64)
formula.next_to(title, DOWN, buff=0.6)
self.play(Write(title))
self.play(Write(formula))
self.wait(1)
渲染:
manim -ql smoke_scene.py SmokeScene
我们在服务器上用类似 smoke 验证过完整链路:Text、MathTex、shape、Write/Create/Transform/FadeOut 都能渲染,最终生成了 MP4;同时也验证了 LaTeX 中间 SVG 会进入 media/Tex/。
常见坑
1. Python 版本太低
Manim CE 0.20.x 要求 Python >=3.11。如果系统 Python 还是 3.10,直接 pip install manim 会失败或安装不到当前版本。用 uv venv --python 3.12 是比较省事的做法。
2. 缺 Cairo / Pango 开发依赖
报 pangocairo、pycairo、manimpango 相关错误时,先补系统包,不要在 Python 层反复重试。
3. 公式不是普通文本
Text("x^2") 和 MathTex(r"x^2") 是两回事。前者走文字渲染,后者走 LaTeX 数学排版。涉及公式、分式、求和、积分,优先用 MathTex。
4. 中文字体要单独验证
英文和数学公式能渲染,不代表中文字体一定好看。中文视频建议单独测试字体、字号、行距和系统 fontconfig,不要等整条视频写完才发现中文乱码或 fallback 很丑。
5. 不要把 media/ 当源码
media/ 是 Manim 自动产物,可以缓存和回看,但不应该把它当作主要源文件维护。真正该维护的是:plan.md、script.py、旁白稿、素材和最终 renders/。
6. 先节奏,再高清
很多 Manim 视频看起来“不高级”,不是因为分辨率低,而是因为画面节奏和信息层级有问题。先在 -ql 下把节奏、停顿、布局改好,再考虑高清。
什么时候 Manim 不是最佳选择
Manim 很强,但不是所有视频都适合它。
| 场景 | 更合适的工具 |
|---|---|
| 真人口播、素材剪辑、B-roll | DaVinci Resolve、Premiere、Final Cut |
| 浏览器交互录屏 | 浏览器自动化 + 录屏工具 |
| 快速 UI 动效原型 | HTML/CSS/JS、p5.js、After Effects |
| 复杂 3D 场景和真实光照 | Blender |
| 大量模板化字幕短视频 | FFmpeg + 模板引擎 |
Manim 最值得用在“需要精确控制图形、公式、对象关系和动画时序”的解释型内容。它不是剪辑软件,而是把数学和图形解释变成代码的 production engine。
对 ChatArch 的建议
如果后续要把 Manim 纳入 ChatArch 的内容生产,可以先做一个轻量模板仓库或项目模板,而不是马上追求全自动生成视频。
推荐最小闭环:
1. 人类或 Agent 写 plan.md
2. Agent 生成 script.py 初稿
3. Manim -ql 渲染草稿片段
4. 人类 review 画面和节奏
5. Agent 修改场景代码
6. Manim -qh 渲染高清片段
7. FFmpeg 拼接、配音、字幕
8. 最终 MP4 进入 ChatBlog / 视频平台 / 文档页
这个闭环里,Agent 最适合承担:场景脚本初稿、公式排版、代码重构、批量渲染命令、FFmpeg 后处理和产物检查。人类最好保留:选题、叙事判断、审美取舍和最终发布确认。
小结
Manim 的价值不在于“可以用 Python 画一个圆”,而在于它把数学解释视频拆成了可编程、可复现、可迭代的场景代码。
正确理解它,需要同时看到两面:
- 对创作者来说,它是 Python:
Scene、Mobject、Animation、self.play(); - 对工程实践来说,它是一条视频流水线:Python 场景、图形渲染、LaTeX 公式、FFmpeg 输出、配音字幕和人工 review。
如果只是想试试,写一个 SquareToCircle 就够了;如果要持续做数学类视频,就应该从第一天开始维护 plan.md、script.py、assets/、renders/ 和可复用的 render helper。这样 Manim 才不只是一个好玩的 Python 库,而会变成一条真正能交付解释型视频的生产线。
资料来源
- Manim Community Edition 官网:https://www.manim.community/
- Manim CE 文档:https://docs.manim.community/
- Manim CE GitHub:https://github.com/ManimCommunity/manim
- Manim CE PyPI:https://pypi.org/project/manim/
- Manim CE README 与 example scenes:
ManimCommunity/manim仓库。 - 本文服务器 smoke 结果来自 ChatArch 内部 Manim 探索任务:在 Ubuntu 22.04 环境中安装 Manim CE
0.20.1,并完成MathTex到 MP4 的最小渲染验证。