news 2026/9/10 2:37:21

ManimCE 函数绘制与数据可视化实战:从坐标轴到参数曲线的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ManimCE 函数绘制与数据可视化实战:从坐标轴到参数曲线的完整指南

ManimCE 函数绘制与数据可视化实战:从坐标轴到参数曲线的完整指南

【免费下载链接】OpenMontageWorld's first open-source, agentic video production system. 12 production pipelines, 100+ tools, 700+ agent skill and production-knowledge files. Turn your AI coding assistant into a full video production studio.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMontage

在 OpenMontage 视频生产系统中,Manim Community Edition(ManimCE)承担着数学动画与科普类视频的生成任务,其核心能力之一就是函数绘图与数据可视化——将数学表达式、数据点和几何曲线转换为可直接渲染的动画场景。本文以仓库内.claude/skills/manimce-best-practices/rules/graphing.md为基础,结合配套的完整示例 graph_plotting.py 与 math_animate 工具 的源码实现,系统讲解坐标轴配置、函数绘制、参数曲线、面积可视化、动态动画与 3D 曲面等实战技术。读完本文,你将能够独立编写从简单抛物线到复杂参数曲线、再到 3D 曲面的完整 Manim 绘图场景,并理解其在 OpenMontage 视频生产管线中的实际落地方案。

前置准备:坐标轴(Axes)是绘图的地基

在 ManimCE 中,所有函数绘图都建立在坐标轴(Axes)之上。Axes本质上是两条数轴(NumberLine)的组合,它将数学坐标空间映射到屏幕像素空间。

from manim import * class BasicPlot(Scene): def construct(self): axes = Axes(x_range=[-3, 3], y_range=[-2, 8]) # Plot a function graph = axes.plot(lambda x: x**2, color=BLUE) self.add(axes, graph)

x_rangey_range接受[min, max, step]三元组,第三个元素控制刻度步长;x_lengthy_length控制坐标轴在屏幕上的物理长度。来自 axes.md 的完整配置示例展示了更精细的控制:

class CustomAxes(Scene): def construct(self): axes = Axes( x_range=[-5, 5, 1], # [min, max, step] y_range=[-3, 3, 1], x_length=10, # Physical length on screen y_length=6, axis_config={ "color": BLUE, "include_tip": True, "include_numbers": True, }, x_axis_config={ "numbers_to_include": [-4, -2, 0, 2, 4], }, y_axis_config={ "numbers_to_include": [-2, 0, 2], }, ) self.add(axes)

坐标转换三件套:c2p、p2c 与 i2gp

Axes提供了两个方向的坐标转换方法,以及一个专门服务于函数图形的查询方法,这在后续绘制切点、标注数据点时至关重要:

# c2p = coords_to_point:数学坐标 -> 屏幕位置 point = axes.c2p(2, 1) # p2c = point_to_coords:屏幕位置 -> 数学坐标 coords = axes.p2c(point) # i2gp = input_to_graph_point:给定 x,求 graph 上对应点的屏幕位置 dot = Dot(axes.i2gp(1.5, graph))

plot() 参数详解:控制定义域、颜色与线宽

axes.plot()接受一个Callable[[float], float]形式的函数对象(lambda 或具名函数均可),并通过参数控制其绘制细节。原文档的PlotParameters场景展示了三个最常用参数:

class PlotParameters(Scene): def construct(self): axes = Axes(x_range=[-5, 5], y_range=[-2, 2]) graph = axes.plot( lambda x: np.sin(x), x_range=[-PI, PI], # Limit domain color=YELLOW, stroke_width=4, ) self.add(axes, graph)

各参数的作用与取值建议:

参数作用说明
x_range限定绘制定义域用于避免函数在无定义区间(如对数、开根号、分式的奇点)被错误连线
color曲线颜色使用 ManimCE 预置颜色常量,如BLUEYELLOWGREEN
stroke_width曲线线宽默认约为 4,放大强调时可以提高
discontinuities标记不连续点配合dt参数跳过断点处连线

需要说明的是,axes.plot()传入的可以是任意单参数函数——np.sinnp.cos这类 numpy 函数也可以直接传入而无需 lambda 包装,仓库示例 graph_plotting.py 中正是这样使用:axes.plot(np.sin, color=BLUE, x_range=[-2*PI, 2*PI])

多函数叠加:在同一坐标轴上对比曲线

将多个函数绘制在同一个Axes上,是数学可视化中最常见的对比手法。原文档的MultiplePlots场景直接给出了正弦、余弦、二次函数三线同框的写法:

class MultiplePlots(Scene): def construct(self): axes = Axes(x_range=[-3, 3], y_range=[-2, 10]) sin_graph = axes.plot(lambda x: np.sin(x), color=BLUE) cos_graph = axes.plot(lambda x: np.cos(x), color=RED) quad_graph = axes.plot(lambda x: x**2, color=GREEN) self.add(axes, sin_graph, cos_graph, quad_graph)

配套示例 graph_plotting.py 进一步演示了“多曲线 + 分步动画 + 图例标签”的完整模式:先Create(axes),再依次Create(sine)Create(cosine),同时用MathTex配合to_corner(UR)next_to(..., DOWN)摆放图例,实现 3Blue1Brown 风格的渐进式揭示。

为图形添加标签:get_graph_label

get_graph_labelAxes提供的高层 API,它会在曲线指定位置自动摆放标签,并处理好偏移方向:

class GraphLabels(Scene): def construct(self): axes = Axes(x_range=[-3, 3], y_range=[-2, 10]) graph = axes.plot(lambda x: x**2, color=BLUE) # Add label to graph label = axes.get_graph_label( graph, label=MathTex("y = x^2"), x_val=2, direction=UR ) self.add(axes, graph, label)

参数含义:label为标签内容(MathTex或普通字符串);x_val指定标签锚定在曲线上的横坐标位置;direction控制标签相对该点的偏移方向(URULDRDL等)。这与 graph_plotting.py 中手动MathTex(...).next_to(parabola, UR)的方式殊途同归——前者锚定更精确,后者布局更灵活。

参数曲线:plot_parametric_curve 与 ParametricFunction

基于坐标轴绘制

参数曲线通过plot_parametric_curve绘制,其函数返回三维数组[x(t), y(t), z(t)]t_range控制参数t的扫描范围。原文档用圆形给出了最小示例:

class ParametricExample(Scene): def construct(self): axes = Axes(x_range=[-3, 3], y_range=[-3, 3]) # Circle: x = cos(t), y = sin(t) curve = axes.plot_parametric_curve( lambda t: np.array([np.cos(t), np.sin(t), 0]), t_range=[0, 2 * PI], color=YELLOW ) self.add(axes, curve)

经典参数曲线三例

原文档附带了三组可直接复用的经典参数曲线,分别对应利萨茹曲线、螺旋线与心形线:

# Lissajous curve curve = axes.plot_parametric_curve( lambda t: np.array([np.sin(3*t), np.sin(2*t), 0]), t_range=[0, 2*PI], ) # Spiral curve = axes.plot_parametric_curve( lambda t: np.array([t*np.cos(t), t*np.sin(t), 0]), t_range=[0, 4*PI], ) # Heart curve curve = axes.plot_parametric_curve( lambda t: np.array([ 16 * np.sin(t)**3, 13*np.cos(t) - 5*np.cos(2*t) - 2*np.cos(3*t) - np.cos(4*t), 0 ]) / 10, t_range=[0, 2*PI], )

配套示例 graph_plotting.py 还展示了参数曲线的进阶玩法:在同一坐标轴上先绘制圆形,再绘制利萨茹曲线,最后用self.play(Transform(circle, lissajous))实现曲线之间的平滑形变——这是 Manim 视觉叙事中“同源概念相互转化”的标准手法。此外,隐函数(如x^2 + y^2 = 4)在 Manim 中没有直接的隐式绘图 API,标准做法正是将其参数化为圆/椭圆后绘制,见示例中的ImplicitFunction场景。

脱离坐标轴的独立绘制

当只需要一条曲线而不需要坐标网格时,可以直接使用独立的ParametricFunctionmobject:

class StandaloneParametric(Scene): def construct(self): curve = ParametricFunction( lambda t: np.array([np.cos(t), np.sin(t), 0]), t_range=[0, 2*PI], color=BLUE ) self.add(curve)

面积与黎曼矩形:可视化积分概念

曲线下方面积(get_area)

get_area用于在曲线与 x 轴之间填充半透明色块,是讲解定积分几何意义的标配工具:

class AreaUnderCurve(Scene): def construct(self): axes = Axes(x_range=[-1, 5], y_range=[-1, 10]) graph = axes.plot(lambda x: x**2, x_range=[0, 3], color=BLUE) # Shade area under curve area = axes.get_area( graph, x_range=[0, 2], color=BLUE, opacity=0.5 ) self.add(axes, graph, area)

配套示例 graph_plotting.py 将其扩展为完整的“微积分叙事”:绘制0.5x²的曲线后填充[1, 3]区间面积,并在右上角用MathTex(r"\int_1^3 \frac{x^2}{2} \, dx")写出积分式,先Create(func)、再FadeIn(area)、最后Write(integral),实现“图形 -> 面积 -> 符号”的三级递进。

黎曼矩形(get_riemann_rectangles)

get_riemann_rectangles将曲线下方的区域离散化为矩形,dx控制矩形宽度,宽度越小越逼近真实面积:

class RiemannRectangles(Scene): def construct(self): axes = Axes(x_range=[-1, 5], y_range=[-1, 10]) graph = axes.plot(lambda x: x**2, color=BLUE) rects = axes.get_riemann_rectangles( graph, x_range=[0, 3], dx=0.5, color=YELLOW, stroke_width=1 ) self.add(axes, graph, rects)

graph_plotting.py 中的RiemannSum场景给出了动画版:遍历dx_values = [1, 0.5, 0.25],矩形逐次加密,直观演示黎曼和收敛于定积分的过程,是数学课堂视频的经典桥段。

动态绘图:动画图形与沿曲线运动的点

用 Create 动画绘制曲线

静态图形远不如动态绘制有表现力。Create(graph)会沿曲线路径逐段描画,run_time控制时长:

class AnimatedGraph(Scene): def construct(self): axes = Axes(x_range=[-3, 3], y_range=[-2, 2]) self.add(axes) graph = axes.plot(lambda x: np.sin(x), color=BLUE) # Animate the graph being drawn self.play(Create(graph), run_time=3)

沿曲线移动的点:ValueTracker + always_redraw + i2gp

原文档的MovingPointOnGraph场景是“函数图像上运动质点”的标准模板:用ValueTracker保存当前横坐标,always_redraw保证每一帧重新计算点的位置,i2gp负责把横坐标映射为曲线上的屏幕坐标:

class MovingPointOnGraph(Scene): def construct(self): axes = Axes(x_range=[-3, 3], y_range=[-2, 2]) graph = axes.plot(lambda x: np.sin(x), color=BLUE) # Point that follows graph x_tracker = ValueTracker(-3) dot = always_redraw(lambda: Dot( axes.i2gp(x_tracker.get_value(), graph), color=YELLOW )) self.add(axes, graph, dot) self.play(x_tracker.animate.set_value(3), run_time=4)

配套示例 graph_plotting.py 展示了更强的动态模式——参数化图形本身:用ValueTracker保存振幅,always_redraw内重新调用axes.plot(lambda x: amplitude.get_value() * np.sin(x)),随后依次play(amplitude.animate.set_value(2))等,让整条正弦曲线的振幅连续变化,同时右上角实时显示A = 2.0。这也印证了 updaters.md 中的核心思想:ValueTracker+always_redraw是构建动态数学可视化的通用组合。

3D 曲面绘制:ThreeDAxes 与 plot_surface

当需要表达z = f(x, y)的空间曲面时,使用ThreeDSceneplot_surface。曲面函数接收二维参数(u, v)并返回标量zcolorscale可以传入颜色列表生成渐变着色:

class SurfacePlot(ThreeDScene): def construct(self): axes = ThreeDAxes() surface = axes.plot_surface( lambda u, v: np.sin(u) * np.cos(v), u_range=[-PI, PI], v_range=[-PI, PI], colorscale=[BLUE, GREEN, YELLOW], ) self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES) self.add(axes, surface)

注意三个要点:场景类必须继承ThreeDSceneset_camera_orientation通过phi/theta(极角与方位角)控制相机视角;3D 场景默认使用 Cairo 渲染器。仓库技能 manim-usage.md 明确建议默认使用 2D,仅当“空间关系本身就是概念”时才使用 3D——3D 渲染速度明显慢于 2D,且曲面类场景应配合相机轨道运动来揭示隐藏结构。详细的 3D 相机控制可参考 3d.md。

进阶实战:来自仓库示例的完整模式

切线可视化

graph_plotting.py 的TangentLine场景是“导数可视化”的经典实现:对y = x²x = 2处取切点,用点斜式4*(x-2)+4绘制切线,并用MathTex(r"m = 2x = 4")标出斜率:

# Point of tangency at x = 2 point = Dot(axes.c2p(x_val, x_val ** 2), color=RED) # Tangent line: derivative of x^2 is 2x, at x=2 slope is 4 tangent = axes.plot( lambda x: 4 * (x - 2) + 4, # Point-slope form color=YELLOW, x_range=[0.5, 3.5] )

数据点标注

CoordinateLabeling场景演示了数据点标注的标准流程:用c2p定位点,用DashedLine向坐标轴引辅助虚线,用next_to摆放横纵坐标标签。NumberPlaneExample场景则演示了在NumberPlane网格上从原点向目标点画Arrow向量,配合GrowArrow动画实现向量可视化。

极坐标绘图

PolarPlot场景使用PolarPlaneplot_polar_graph绘制极坐标曲线:心形线r = 1 + sin(θ)与玫瑰线r = 2·cos(3θ),两者之间同样可以用Transform动画切换:

polar_plane = PolarPlane(radius_max=3, size=6) cardioid = polar_plane.plot_polar_graph( lambda theta: 1 + np.sin(theta), theta_range=[0, 2 * PI], color=BLUE )

在 OpenMontage 中的落地:math_animate 工具

上述绘图模式在 OpenMontage 中通过 math_animate 工具 统一封装。该工具基于 ManimCE 本地运行,无需 API Key,成本为零,其input_schema接受scene_code(定义Scene类的 Python 代码)、qualitylow/medium/high/4k/preview预设)、formatmp4/gif/png/webm)、background_color等参数,其中质量预设直接映射到 Manim CLI 的质量旗标(见 QUALITY_PRESETS)。

值得特别说明的是其安全边界:scene_code会在宿主机上被 Manim 实际执行,因此工具内置静态扫描,拦截ossubprocesssocketrequestsevalopen等危险导入与危险标识符,并默认拒绝所有双下划线属性访问,仅放行__init____name__(见 math_animate.py)。只有当allow_unsafe_code=True时才绕过该扫描。对应的安全契约由 test_math_animate_safety.py 全量覆盖验证。

在 OpenMontage 生产实践中(见 manim-usage.md),绘图场景还需遵循以下约定:

  • 一个场景一个概念:复杂证明拆分为多个 Manim 场景,每次画面揭示不超过 3~4 个新视觉元素;
  • 配色语义化:未知量用YELLOW、已知常量用BLUE_C、矩阵/算子用RED、标注用GREEN、弱化元素用GREY+opacity=0.5
  • 时序规范:方程书写Write用 1.5~2.0s,图形Create用 0.8~1.2s,重大揭示后至少self.wait(1.5)
  • 背景统一:始终使用深色背景(BLACK#1a1a2e),视频输出为 1080p。

渲染与发布:CLI 命令速查

绘图场景编写完成后,通过 Manim CLI 渲染。来自 cli.md 的完整命令体系如下:

# 开发迭代:低质量 + 预览(快) manim -pql scene.py MyScene # 草稿审查:中等质量 manim -pqm scene.py MyScene # 成片输出:1080p60(OpenMontage 的 YouTube 横屏标准) manim -qh scene.py MyScene # 分享用 GIF manim --format gif -qm scene.py MyScene # 只存最后一帧(缩略图) manim -s scene.py MyScene # 渲染文件中所有场景 manim -a scene.py # 自定义分辨率与帧率 manim -r 1920,1080 --fps 30 scene.py MyScene

质量旗标对照:-ql(854x480/15fps,测试用)、-qm(1280x720/30fps)、-qh(1920x1080/60fps)、-qp(2560x1440/60fps)、-qk(3840x2160/60fps)。若直接使用math_animate工具,则无需手写 CLI,只需在scene_code中定义好Scene子类并指定quality参数即可。

最佳实践总结

结合原文档的规则清单与仓库中的实际示例,函数绘图场景应遵循以下五条准则:

  1. 为不连续函数显式设置x_range:避免在无定义区域(对数、开方、分式奇点)被自动连线产生误导;
  2. 善用get_graph_label:函数曲线务必配标签,x_val锚定位置、direction控制方向,保证可读性;
  3. 让颜色匹配概念:同一视频内保持一致的语义化配色(如未知量一律黄色),避免颜色歧义;
  4. 绘制曲线上的点一律使用i2gp:由 Manim 自动处理坐标转换,杜绝手工换算导致的像素级偏差;
  5. 用动画代替静态展示Create描画曲线、ValueTracker + always_redraw驱动动态参数,让数学“活”起来。

完整的可运行参考实现位于 graph_plotting.py(含 12 个场景:坐标轴、函数绘制、多函数、面积、NumberPlane、参数曲线、切线、动态振幅、黎曼和、隐函数、坐标标注、极坐标),可直接以manim -pql graph_plotting.py SceneName运行验证。配套的坐标系统基础可参考 axes.md,场景规划方法论可参考 manim-composer 技能,渲染参数与 CLI 细节见 cli.md。

【免费下载链接】OpenMontageWorld's first open-source, agentic video production system. 12 production pipelines, 100+ tools, 700+ agent skill and production-knowledge files. Turn your AI coding assistant into a full video production studio.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMontage

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 2:36:15

SpringBoot+Vue健康饮食系统调试实战指南

简介:这是一套面向计算机专业本科生的Java全栈毕设实战项目,聚焦智能健康饮食场景,专为毕业设计、课程设计及期末大作业打造,兼顾SpringBoot后端开发与Vue前端工程化实践能力训练。资源包共353个文件,涵盖88个核心Java…

作者头像 李华
网站建设 2026/9/10 2:34:12

智慧工地安全帽反光衣检测:VOC与YOLO标注转换及YOLOv8训练实战

简介:这份智慧工地检测数据集来自真实工地监控摄像头,共3065张图像,覆盖多视角多场景抓拍,面向反光衣穿戴检测、安全帽佩戴检测与人员入侵告警等任务。压缩包共2000个文件,以XML(VOC格式)标注、…

作者头像 李华
网站建设 2026/9/10 2:31:37

Prophet时序预测实战:数据预处理、参数调优与结果解读

简介:本资源是一份面向Python初学者与数据分析从业者的Prophet时间序列预测入门实践脚本,聚焦业务场景下的快速建模与结果解读。资源核心为一个精简实用的prophet.py脚本,完整封装了数据加载、模型初始化、趋势与季节性拟合、未来365天预测及…

作者头像 李华