坐标系家族¶
坐标系把“数据坐标”翻译成“场景位置”,是函数绘图和数据可视化的舞台。家族成员都围绕 CoordinateSystem 的坐标互转 API 构建,再各自叠加网格、刻度或极坐标线。
CoordinateSystem¶
CoordinateSystem(x_range=None, y_range=None, x_length=None, y_length=None, dimension=2) 官方文档 ↗
CoordinateSystem 是抽象基类,本身不可实例化(get_axis_labels() 直接抛 NotImplementedError)。它的价值在于定义了所有坐标系共享的核心 API:
坐标互转:
coords_to_point(*coords)(别名c2p)与point_to_coords(point)(别名p2c);NumberLine上的number_to_point/point_to_number是一维版本绘图:
plot、plot_parametric_curve、plot_implicit_curve、plot_polar_graph、plot_derivative_graph、plot_antiderivative_graph、plot_surface(详见“函数绘图”一节)辅助线:
get_vertical_line(point)、get_horizontal_line(point)、get_line_from_axis_to_point(index, point)(从坐标轴指向点的虚线)面积与积分:
get_area(graph, ...)、get_riemann_rectangles(...)标签:
get_axis_labels()(子类实现)、get_graph_label(graph, label, x_val=..., dot=...)、get_T_label(...)切线:
slope_of_tangent(x, graph)、angle_of_tangent(...)、get_secant_slope_group(...)
name |
type |
default |
desc |
|---|---|---|---|
|
Sequence[float] | None |
None |
x 轴范围 |
|
Sequence[float] | None |
None |
y 轴范围 |
|
float | None |
None |
x 轴物理长度(场景单位) |
|
float | None |
None |
y 轴物理长度 |
|
int |
2 |
坐标系维数 |
常见错误
旧教程里的 axes.get_graph(lambda x: x**2) 在 v0.21.0 已不存在(Axes 上没有 get_graph 方法),统一改用 axes.plot(...)。同理 get_graph_label 属于坐标系而不是图对象:axes.get_graph_label(graph, "f(x)")。
Axes¶
Axes(x_range=None, y_range=None, x_length=12, y_length=6, axis_config=None, x_axis_config=None, y_axis_config=None, tips=True, **kwargs) 官方文档 ↗
Axes 是标准的直角坐标系:x 轴 + y 轴(两条 NumberLine),默认带箭头、无网格。
name |
type |
default |
desc |
|---|---|---|---|
|
Sequence[float] | None |
(-7.11, 7.11, 1) |
x 轴范围,按 |
|
Sequence[float] | None |
(-4, 4, 1) |
y 轴范围 |
|
float | None |
12 |
x 轴长度 |
|
float | None |
6 |
y 轴长度 |
|
dict | None |
None |
同时作用于两条轴的 |
|
dict | None |
None |
单轴配置,优先级高于 |
|
bool |
True |
是否显示轴末端箭头 |
Axes 的两个子对象可通过 axes.get_x_axis() / axes.get_y_axis() 取回(它们就是 NumberLine);axes.get_origin() 返回原点场景位置。axes.get_axis_labels(x_label="x", y_label="y") 返回默认的 LaTeX 轴标签(也可传入 Text 等 Mobject)。
coords_to_point(2, 1) 把数据坐标翻译成场景坐标;配合 point_to_coords 可以在几何位置与数据坐标之间自由往返。
查看源码 axes_basic.py
"""AxesDemo: Axes 的基本创建、坐标互转与坐标读取线。"""
from manim import *
class AxesDemo(Scene):
def construct(self):
axes = Axes(
x_range=(-3, 3, 1),
y_range=(-2, 2, 1),
x_length=9,
y_length=6,
axis_config={"include_tip": True},
)
labels = axes.get_axis_labels(
x_label=Text("x", font_size=36),
y_label=Text("y", font_size=36),
)
self.play(Create(axes), run_time=1.5)
self.play(FadeIn(labels), run_time=0.5)
# coords_to_point:坐标 -> 场景点;point_to_coords 为其逆运算
dot = Dot(axes.coords_to_point(2, 1), color=RED)
x_line = DashedLine(axes.coords_to_point(2, 0), axes.coords_to_point(2, 1))
y_line = DashedLine(axes.coords_to_point(0, 1), axes.coords_to_point(2, 1))
self.play(Create(x_line), Create(y_line), FadeIn(dot), run_time=1.0)
coord = Text("(2, 1)", font_size=30).next_to(dot, UR, buff=0.1)
self.play(Write(coord), run_time=0.8)
self.wait(0.5)
提示
坐标轴本质上就是 NumberLine,所以数轴的所有配置都能用:给某条轴加数字只需 axes.get_x_axis().add_numbers();对数坐标则用 x_axis_config={"scaling": LogBase(base=10)}。
NumberPlane¶
NumberPlane(x_range=(-7.111111111111111, …, y_range=(-4.0, 4.0, 1), x_length=None, y_length=None, background_line_style=None, faded_line_style=None, faded_line_ratio=1, make_smooth_after_applying_functions=True, **kwargs) 官方文档 ↗
NumberPlane 在 Axes 基础上铺满背景网格线(主实线 + 次淡化线),是默认的“草稿纸”。
name |
type |
default |
desc |
|---|---|---|---|
|
Sequence[float] | None |
(-7.11, 7.11, 1) / (-4, 4, 1) |
网格范围(默认与 16:9 画幅适配) |
|
float | None |
None |
平面尺寸,None 时按画幅自动计算 |
|
dict | None |
None |
主网格线样式( |
|
dict | None |
None |
次网格线样式 |
|
int |
1 |
每个主间隔中淡化线的数量 |
|
bool |
True |
应用函数变换后是否平滑网格 |
默认不显示数字;需要坐标数字时调用 plane.add_coordinates()(走 LaTeX)或自行 add_labels。
faded_line_ratio=2 让每个主间隔出现两条淡化线;淡化线很适合营造“坐标纸”质感而不喧宾夺主。
查看源码 number_plane.py
"""NumberPlaneDemo: NumberPlane 背景网格与淡化线。"""
from manim import *
class NumberPlaneDemo(Scene):
def construct(self):
plane = NumberPlane(
x_range=[-4, 4, 1],
y_range=[-3, 3, 1],
background_line_style={
"stroke_color": BLUE_E,
"stroke_width": 2,
"stroke_opacity": 0.5,
},
faded_line_style={"stroke_opacity": 0.15},
faded_line_ratio=2,
)
self.add(plane)
dot = Dot(plane.coords_to_point(1.5, 1), color=YELLOW)
self.play(FadeIn(dot, scale=2), run_time=0.8)
self.play(dot.animate.move_to(plane.coords_to_point(-2, -1)), run_time=1.2)
self.wait(0.5)
ComplexPlane¶
ComplexPlane(**kwargs) 官方文档 ↗
ComplexPlane 把平面解释为复平面:number_to_point 接受复数(如 2 + 1j),point_to_number 返回复数。构造参数与 NumberPlane 完全一致(__init__(self, **kwargs) 全部转发),只额外提供复数语义的转换方法。
plane.number_to_point(2 + 1j) 一步到位;point_to_number 是它的逆运算,返回 complex。
查看源码 complex_plane.py
"""ComplexPlaneDemo: ComplexPlane 上复数与点的互转。"""
from manim import *
class ComplexPlaneDemo(Scene):
def construct(self):
plane = ComplexPlane(
x_range=[-3, 3, 1],
y_range=[-2, 2, 1],
)
self.add(plane)
# number_to_point 接受复数(或实数),返回场景坐标
z = 2 + 1j
dot = Dot(plane.number_to_point(z), color=RED)
v_line = DashedLine(
plane.number_to_point(2), plane.number_to_point(z), color=RED
)
h_line = DashedLine(
plane.number_to_point(1j), plane.number_to_point(z), color=RED
)
label = Text("2 + i", font_size=30).next_to(dot, UR, buff=0.1)
self.play(FadeIn(h_line), FadeIn(v_line), FadeIn(dot), run_time=1.0)
self.play(Write(label), run_time=0.8)
# point_to_number 返回复数
back = plane.point_to_number(dot.get_center())
self.wait(0.5)
常用搭配:
plane.add_coordinates()—— 同时添加实轴、虚轴数字(LaTeX)plane.get_coordinate_labels(...)—— 更精细的坐标标签控制z_to_point的等价写法:复数可直接传给number_to_point
PolarPlane¶
PolarPlane(radius_max=4.0, size=None, radius_step=1, azimuth_step=None, azimuth_units='PI radians', azimuth_compact_fraction=True, azimuth_offset=0, azimuth_direction='CCW', azimuth_label_buff=0.1, azimuth_label_font_size=24, radius_config=None, background_line_style=None, faded_line_style=None, faded_line_ratio=1, make_smooth_after_applying_functions=True, **kwargs) 官方文档 ↗
PolarPlane 绘制极坐标网格:同心圆(半径)+ 放射线(方位角)。它同样继承 Axes 的 plot 家族,并额外提供 polar_to_point(radius, azimuth) / point_to_polar(point)(别名 pr2pt / pt2pr)。
name |
type |
default |
desc |
|---|---|---|---|
|
float |
4.0 |
最大半径 |
|
float | None |
None |
平面直径;None 时按 |
|
float |
1 |
半径网格间隔 |
|
float | None |
None |
方位角网格间隔(None 自动) |
|
str |
"PI radians" |
方位角标签单位,可选 |
|
bool |
True |
标签用 π 的紧凑分数形式 |
|
float |
0 |
角度标签偏移 |
|
str |
"CCW" |
角度增大方向( |
|
dict | None |
None |
半径轴(NumberLine)配置 |
|
— |
— |
同 |
版本说明
网上旧资料常说 PolarPlane 默认角度单位是度——在 v0.21.0 不正确。默认 azimuth_units="PI radians",角度标签渲染为 PI/4 这样的 LaTeX;要十进制度请显式传 azimuth_units="degrees"。注意 get_coordinate_labels() 生成的标签依赖 LaTeX。
继承自 Axes,所以 plot_polar_graph(r_func, theta_range=...) 可直接使用;r_func 输入弧度制的 θ,输出半径。
查看源码 polar_plane.py
"""PolarPlaneDemo: PolarPlane 极坐标网格与极坐标曲线。"""
from manim import *
class PolarPlaneDemo(Scene):
def construct(self):
# 默认 azimuth_units="PI radians",角度标签以 PI 的倍数表示
plane = PolarPlane(
radius_max=4,
azimuth_units="PI radians",
background_line_style={"stroke_opacity": 0.3},
)
self.add(plane)
# 三瓣玫瑰线 r = 1.5 + cos(3t)
graph = plane.plot_polar_graph(
lambda t: 1.5 + np.cos(3 * t),
theta_range=(0, 2 * PI),
color=YELLOW,
)
self.play(Create(graph), run_time=2.0)
self.wait(0.5)
ThreeDAxes¶
ThreeDAxes(x_range=(-6, 6, 1), y_range=(-5, 5, 1), z_range=(-4, 4, 1), x_length=10.5, y_length=10.5, z_length=6.5, z_axis_config=None, z_normal=array([ 0., -1., 0.]), num_axis_pieces=20, light_source=array([-7., -9., 10.]), depth=None, gloss=0.5, **kwargs) 官方文档 ↗
ThreeDAxes 增加一条 z 轴,组成三维直角坐标系。在普通 Scene 中它以固定的斜投影显示;真正的 3D 交互(旋转视角、设置相机)要配合 ThreeDScene 使用,见“3D 与摄像机”板块。
name |
type |
default |
desc |
|---|---|---|---|
|
Sequence[float] | None |
(-6, 6, 1) / (-5, 5, 1) / (-4, 4, 1) |
三个轴的范围 |
|
float | None |
10.5 / 10.5 / 6.5 |
三个轴的物理长度 |
|
dict | None |
None |
z 轴( |
|
Vector3DLike |
(0, -1, 0) |
z 轴“朝向上方”的方向参考 |
|
int |
20 |
每个轴的分段数 |
coords_to_point 在此接受三个坐标;get_z_axis() 取回 z 轴。
普通 Scene 里 ThreeDAxes 以斜投影静态呈现;给它加 Dot3D 标记空间点,后续移入 ThreeDScene 即可获得完整 3D 体验。
查看源码 three_d_axes.py
"""ThreeDAxesDemo: 在普通 2D Scene 中创建 ThreeDAxes(斜投影)。"""
from manim import *
class ThreeDAxesDemo(Scene):
def construct(self):
axes = ThreeDAxes(
x_range=(-3, 3, 1),
y_range=(-3, 3, 1),
z_range=(-2, 2, 1),
z_axis_config={"stroke_color": BLUE},
)
self.play(Create(axes), run_time=2.0)
# coords_to_point 接受三个坐标(普通 Scene 中为斜投影效果)
dot = Dot3D(axes.coords_to_point(1, 1, 1), color=RED)
self.play(FadeIn(dot), run_time=0.8)
self.wait(0.5)
成员怎么选¶
需求 |
用谁 |
|---|---|
只要两条轴、画函数图像 |
|
需要网格背景 |
|
复数运算可视化 |
|
极坐标方程、角度数据 |
|
空间曲线/曲面 |
|
数据柱状图 |
|
自测¶
✏️ 练习
已知 plane = NumberPlane(x_range=[-4, 4, 1], y_range=[-3, 3, 1], x_length=8, y_length=6),plane.coords_to_point(2, 1) 大约在场景什么位置?(原点即平面中心)
✅ 参考答案
x 方向 unit_size = 8 / 8 = 1,y 方向 unit_size = 6 / 6 = 1,所以结果约为 (2, 1, 0)。一般地:coords_to_point 的结果 = 原点 + (x * x_unit_size, y * y_unit_size),可用 plane.get_x_unit_size() / get_y_unit_size() 查询。
✏️ 练习
旧脚本里有一句 graph = axes.get_graph(np.sin),在 v0.21.0 下如何修改?
✅ 参考答案
改为 graph = axes.plot(np.sin)。get_graph 已在重构中移除;返回值是 ParametricFunction,后续 axes.get_area(graph, ...)、axes.get_graph_label(graph, ...) 的用法不变。
✏️ 练习
想让 PolarPlane 的角度标签显示为十进制度(如 45°),怎么做?
✅ 参考答案
构造时传 azimuth_units="degrees";若还想要 ° 符号或自定义格式,可传 azimuth_units=None 后自行用 add_labels 添加 Text 标签。