Python视频制作引擎Manim安装教程2021版
0 写在前面
相信很多同学就算没听过3Blue1Brown,也一定曾看过他们出品的视频,其从独特的视觉角度解说各种数学概念,内容包括线性代数、微积分、神经网络、傅里叶变换以及四元数等晦涩难懂的知识点。例如最火的《线性代数本质》系列视频。
那么这些视频是如何制作的呢?
这里需要引入的是Python的Manim视频支持引擎——专门用于支持数学可视化的媒体引擎,通过Manim并结合Python编程就可以实现3Blue1Brown的视频效果。本文给出Manim最新发行版的安装教程,因为网上的教程基本都过时了,容易踩坑。
1 效果展示
动画1:
动画2:(动图始终超过大小,放不上来)
2 安装教程(Windows)
2.1 安装ffmpeg
进入ffmpeg官网,点击如图所示的按钮
接着下载安装包
下载完后直接解压,并设置环境变量
2.2 安装Latex
进入官网MikTex官网,下载对应操作系统的安装包。
解压后运行安装程序.exe即可(环境变量会自动配置)
2.3 安装dvisvgm
进入官网dvisvgm下载相应操作系统的安装包,解压后运行安装程序即可。
2.4 安装Manim
通过git bash运行下面命令
git clone https://github.com/3b1b/manim.git cd manim # 安装python依赖 pip install -e . python -m pip install -r requirements.txt
2021版重点:错误复现如下
LaTeX Error! Not a worry, it happens to the best of us. Traceback (most recent call last): File "D:\Program Files\Python3\Scripts\manimgl-script.py", line 33, in <module> sys.exit(load_entry_point('manimgl', 'console_scripts', 'manimgl')()) File "d:\public\manim\manimlib\__main__.py", line 17, in main scene.run() File "d:\public\manim\manimlib\scene\scene.py", line 75, in run self.construct() File "example_scenes.py", line 29, in construct IntegerMatrix(matrix, include_background_rectangle=True), File "d:\public\manim\manimlib\mobject\matrix.py", line 81, in __init__ self.add_brackets() File "d:\public\manim\manimlib\mobject\matrix.py", line 111, in add_brackets bracket_pair = Tex("".join([ File "d:\public\manim\manimlib\mobject\svg\tex_mobject.py", line 167, in __init__ super().__init__(full_string, **kwargs) File "d:\public\manim\manimlib\mobject\svg\tex_mobject.py", line 42, in __init__ filename = tex_to_svg_file(full_tex) File "d:\public\manim\manimlib\utils\tex_file_writing.py", line 54, in tex_to_svg_file tex_to_svg(tex_file_content, svg_file) File "d:\public\manim\manimlib\utils\tex_file_writing.py", line 62, in tex_to_svg svg_file = dvi_to_svg(tex_to_dvi(tex_file)) File "d:\public\manim\manimlib\utils\tex_file_writing.py", line 97, in tex_to_dvi with open(log_file, "r") as file: FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\Tex\\cf5d7f9f2e57398a.log'
该问题的最终解决方案是配置manim/manimlib/default_config.yml
的缓存路径,其中"D:\\AIProject\\test\\manim\\tex"
是manim
目录下新建的一个空文件夹,用来存放tex输出文件。
3 测试与开发
进入manim
目录下运行:
manimgl example_scenes.py OpeningManimExample
即可得到动画2的效果。
新建main.py
文件,运行下面代码
from manimlib import * class GraphExample(Scene): def construct(self): axes = Axes((-3, 10), (-1, 8)) axes.add_coordinate_labels() self.play(Write(axes, lag_ratio=0.01, run_time=1)) # Axes.get_graph will return the graph of a function sin_graph = axes.get_graph( lambda x: 2 * math.sin(x), color=BLUE, ) # By default, it draws it so as to somewhat smoothly interpolate # between sampled points (x, f(x)). If the graph is meant to have # a corner, though, you can set use_smoothing to False relu_graph = axes.get_graph( lambda x: max(x, 0), use_smoothing=False, color=YELLOW, ) # For discontinuous functions, you can specify the point of # discontinuity so that it does not try to draw over the gap. step_graph = axes.get_graph( lambda x: 2.0 if x > 3 else 1.0, discontinuities=[3], color=GREEN, ) # Axes.get_graph_label takes in either a string or a mobject. # If it's a string, it treats it as a LaTeX expression. By default # it places the label next to the graph near the right side, and # has it match the color of the graph sin_label = axes.get_graph_label(sin_graph, "\\sin(x)") relu_label = axes.get_graph_label(relu_graph, Text("ReLU")) step_label = axes.get_graph_label(step_graph, Text("Step"), x=4) self.play( ShowCreation(sin_graph), FadeIn(sin_label, RIGHT), ) self.wait(2) self.play( ReplacementTransform(sin_graph, relu_graph), FadeTransform(sin_label, relu_label), ) self.wait() self.play( ReplacementTransform(relu_graph, step_graph), FadeTransform(relu_label, step_label), ) self.wait() parabola = axes.get_graph(lambda x: 0.25 * x**2) parabola.set_stroke(BLUE) self.play( FadeOut(step_graph), FadeOut(step_label), ShowCreation(parabola) ) self.wait() # You can use axes.input_to_graph_point, abbreviated # to axes.i2gp, to find a particular point on a graph dot = Dot(color=RED) dot.move_to(axes.i2gp(2, parabola)) self.play(FadeIn(dot, scale=0.5)) # A value tracker lets us animate a parameter, usually # with the intent of having other mobjects update based # on the parameter x_tracker = ValueTracker(2) f_always( dot.move_to, lambda: axes.i2gp(x_tracker.get_value(), parabola) ) self.play(x_tracker.animate.set_value(4), run_time=3) self.play(x_tracker.animate.set_value(-2), run_time=3) self.wait()
即可得到动画1的效果。