向量空间场景¶
manim.scene.vector_space_scene 提供两个教学向的场景基类:VectorScene 在网格背景上画向量、标注坐标,LinearTransformationScene 把整张网格当作向量空间,以动画演示矩阵乘法(3Blue1Brown 线性代数系列的核心场景)。
VectorScene¶
VectorScene(basis_vector_stroke_width=6.0, **kwargs) 官方文档 ↗
VectorScene 继承普通 Scene,额外提供网格背景与一整套向量操作:加向量、贴标签、写坐标、坐标与向量的双向演示。
name |
type |
default |
desc |
|---|---|---|---|
|
float |
6.0 |
基向量(i / j 帽)的线宽 |
场景辅助(默认背景没有网格,需要时自行添加):
self.add_plane(animate=False, **kwargs)—— 添加NumberPlane背景self.add_axes(animate=False, color=WHITE)—— 只添加Axesself.lock_in_faded_grid(dimness=0.7, axes_dimness=0.5)—— 常用开场:淡化网格 + 坐标轴锁定在底层
向量操作:
self.add_vector(vector, color=YELLOW, animate=True, **kwargs)—— 画向量并播放GrowArrow,返回Arrow;vector可传坐标序列self.label_vector(vector, label, animate=True, **kwargs)—— 给向量贴标签(Text/MathTex均可),返回标签self.get_vector(numerical_vector, **kwargs)—— 只创建不播放,返回Arrowself.write_vector_coordinates(vector, **kwargs)—— 写出向量的坐标矩阵Matrixself.vector_to_coords(vector, integer_labels=True, clean_up=True)—— 演示“向量 → 坐标”:返回(坐标矩阵, x 虚线, y 虚线),clean_up=False保留辅助线self.coords_to_vector(coords, coords_start=(2, 2, 0), clean_up=True)—— 反向演示“坐标 → 向量”
add_vector 默认播放生长动画并返回 Arrow,返回值要接住才能继续 label_vector;标签用 Text 渲染即可,不依赖 LaTeX。
查看源码 vector_scene.py
"""VectorSceneDemo: VectorScene 的加向量与向量标注。"""
from manim import *
class VectorSceneDemo(VectorScene):
def construct(self):
# add_vector 默认播放动画并返回 Arrow
v = self.add_vector([2, 1], color=YELLOW)
self.label_vector(v, Text("v", font_size=36))
self.wait(0.5)
w = self.add_vector([-1, 1.5], color=BLUE)
self.label_vector(w, Text("w", font_size=36))
self.wait(0.5)
提示
VectorScene 的网格不会自动出现——add_plane() / lock_in_faded_grid() 二选一。只做向量加减讲解时 lock_in_faded_grid() 的淡化网格最省心;需要读坐标时再用 add_plane() 配合 show_coordinates 风格的显式网格。
LinearTransformationScene¶
LinearTransformationScene(include_background_plane=True, include_foreground_plane=True, background_plane_kwargs=None, foreground_plane_kwargs=None, show_coordinates=False, show_basis_vectors=True, basis_vector_stroke_width=6, i_hat_color=ManimColor('#83C167'), j_hat_color=ManimColor('#FC6255'), leave_ghost_vectors=False, **kwargs) 官方文档 ↗
LinearTransformationScene 继承 VectorScene,专为线性变换动画设计:场景自带背景网格与前景网格,以及 i 帽 / j 帽两个基向量;apply_matrix(...) 会把整个空间(网格、基向量、所有“可变换对象”)按矩阵逐一变换。
name |
type |
default |
desc |
|---|---|---|---|
|
bool |
True |
底层淡化网格 |
|
bool |
True |
顶层“会变形的”网格 |
|
dict | None |
None |
两层 |
|
bool |
False |
是否显示网格坐标数字 |
|
bool |
True |
是否显示 i 帽 / j 帽 |
|
float |
6 |
基向量线宽 |
|
ParsableManimColor |
'#83C167' |
i 帽颜色(绿) |
|
ParsableManimColor |
'#FC6255' |
j 帽颜色(红) |
|
bool |
False |
变换时是否留下基向量的“残影”轨迹 |
变换方法:
self.apply_matrix(matrix, **kwargs)—— 播放线性变换动画;matrix为 2×2(列是 i 帽 / j 帽的新位置)self.apply_inverse(matrix, **kwargs)/apply_transposed_matrix(...)/apply_inverse_transpose(...)—— 逆 / 转置 / 逆转置self.apply_nonlinear_transformation(function, **kwargs)—— 任意R² → R²函数变换(如lambda p: p + np.array([np.sin(p[1]), 0, 0]))self.add_unit_square(animate=False, **kwargs)—— 添加单位正方形(默认不播动画)self.add_transformable_mobject(*mobjects)—— 注册自定义对象,变换时随网格一起变形self.add_transformable_label(vector, label, transformation_name="L", new_label=None, **kwargs)—— 给基向量添加会跟随变换的标注(MathTex)self.add_title(title, scale_factor=1.5, animate=False)—— 场景标题
[[1, 1], [0, 1]] 是切变矩阵:第一列 (1, 0) 是 i 帽的新位置,第二列 (1, 1) 是 j 帽的新位置。单位正方形随网格一起被“推斜”。
查看源码 linear_transformation.py
"""LinearTransformationDemo: 切变矩阵的线性变换动画。"""
from manim import *
class LinearTransformationDemo(LinearTransformationScene):
def construct(self):
# 默认已包含背景/前景 NumberPlane 与 i_hat、j_hat 基向量
self.add_unit_square()
self.wait(0.3)
# 切变:x 轴不变,j_hat 移到 (1, 1)
self.apply_matrix([[1, 1], [0, 1]], run_time=2.0)
self.wait(0.5)
常见错误
apply_matrix 的参数是列主序的数学矩阵:每一列是一个基向量变换后的像(第一列 = i 帽新位置,第二列 = j 帽新位置)。想实现“x 轴不变、y 按 x 剪切”(x' = x + y, y' = y)应传 [[1, 1], [0, 1]];而它的转置 [[1, 0], [1, 1]] 是“y 轴不变、x 按 y 剪切”——两者效果完全不同,对称矩阵看不出来时最容易写错。不确定就观察 i 帽 / j 帽的实际走向。
提示
leave_ghost_vectors=True 会在每次变换时留下基向量的半透明残影,多步变换的轨迹一目了然;show_coordinates=True 适合演示“网格线即坐标”的概念,但数字较密,正式讲解常用 show_coordinates=False 的干净网格。
自测¶
✏️ 练习
self.add_vector([2, 1]) 之后想给这个向量贴上标签 v,完整写法是什么?
✅ 参考答案
接住返回值再标注:
v = self.add_vector([2, 1], color=YELLOW)
self.label_vector(v, Text("v", font_size=36))
add_vector 默认播放 GrowArrow 动画;不想播动画可传 animate=False。
✏️ 练习
在 LinearTransformationScene 中演示“先逆时针旋转 90°,再沿 x 轴剪切”的两步变换,第二步应该怎么写矩阵?(旋转矩阵 R = [[0, -1], [1, 0]],剪切 S = [[1, 1], [0, 1]])
✅ 参考答案
第二步直接 self.apply_matrix([[1, 1], [0, 1]]) 即可。LinearTransformationScene 的每一步 apply_matrix 都作用在当前空间状态上:先 self.apply_matrix([[0, -1], [1, 0]]) 旋转,再 self.apply_matrix([[1, 1], [0, 1]]) 剪切,总效果即复合变换 S @ R。想一次到位也可合成矩阵 self.apply_matrix(np.array([[1, 1], [0, 1]]) @ np.array([[0, -1], [1, 0]]))。
✏️ 练习
只想保留会变形的“前景网格”,去掉底层淡化网格,怎么构造?
✅ 参考答案
class MyScene(LinearTransformationScene): def __init__(self, **kw): super().__init__(include_background_plane=False, **kw)——或直接在构造时传参。前景网格是变换的“主角”,背景网格只作参照;两层都关掉(include_foreground_plane=False)则只剩基向量和注册对象在动。
下一步¶
坐标系与数据可视化板块到此结束:数轴、刻度、坐标系家族、函数绘图、概率图表、矩阵、表格与向量空间场景都已就位。下一板块进入动画进阶,从 Animation 的内部机制讲起。