Manim next_to 用法:标签不跟着物体移动?add_updater 和 VGroup 两种改法(0.21.0 实测)

发布时间:2026/10/5 4:12:19

Manim next_to 用法:标签不跟着物体移动?add_updater 和 VGroup 两种改法(0.21.0 实测) next_to是 Manim 里最常用的相对定位方法label.next_to(tri, RIGHT, buff0.3)把标签摆到三角形右边 0.3 的位置。但它是一次性的只在调用的那一行算一次坐标不会建立「一直在右边」的关系。所以之后三角形一动标签就留在原地。要让标签跟着走有两种改法add_updater每帧重新next_to一次或者把两者装进VGroup一起动。本文代码和坐标数字都在 Manim Community 0.21.02026 年的最新版本上实测过。Manim 是 3Blue1Brown 作者开源的数学动画引擎用 Python 描述画面里有什么、怎么动由它逐帧渲染成视频没接触过的可以先看这篇介绍。下面三段完整代码可以直接贴进极坐标⋅XYZ 的工作区点运行里面装的也是 Manim 0.21.0本机不用装 Python 和 LaTeX。先把问题跑出来一个三角形右边用next_to摆一个 △ABC 的标签然后把三角形往左挪 5 个单位from manim import * class LabelLeftBehind(Scene): def construct(self): tri Polygon([-2, -2, 0], [0, 2, 0], [3, 0, 0], colorBLUE) tri.set_fill(BLUE, 0.5).scale(0.5).move_to(RIGHT * 3) label MathTex(r\triangle ABC, colorYELLOW) label.next_to(tri, RIGHT, buff0.3) self.add(tri, label) self.wait(0.5) self.play(tri.animate.shift(LEFT * 5), run_time2) self.wait()三角形走了标签没动。我们把坐标打印出来看过移动前三角形右边缘在 x 4.25标签左边缘在 x 4.55中间正好隔着buff0.3。移动后三角形右边缘到了 x -0.75标签左边缘还是 4.55两者隔了 5.3 个单位。next_to 那一行到底做了什么label.next_to(tri, RIGHT, buff0.3)执行时Manim 做了三件事取tri外接框右边缘的中点取label外接框左边缘的中点然后把label平移让这两个点在水平方向上相距 0.3。算完就是一次普通的平移label身上只留下了新坐标。tri这个参照物没有被存到任何地方Manim 里也没有「约束」这种东西在后台盯着。所以这行代码的效果和你手算出坐标再写label.move_to([5.33, 0, 0])没有区别只是省了你算的那一步。align_to、to_edge、to_corner、move_to(另一个物体)都是同一个脾气摆的是调用那一刻的位置。网上不少教程的示例里物体动了标签也跟着动看起来像是自动的。翻代码会发现那是在物体挪到新位置之后又调了一次next_to或者干脆每帧都在调。改法一挂一个 updater每帧重新贴一次updater 是挂在物体上的一个函数动画播放期间 Manim 每渲染一帧之前都会调它一遍。把next_to放进去标签每一帧都按三角形的最新位置重新摆from manim import * class LabelFollows(Scene): def construct(self): tri Polygon([-2, -2, 0], [0, 2, 0], [3, 0, 0], colorBLUE) tri.set_fill(BLUE, 0.5).scale(0.5).move_to(RIGHT * 3) label MathTex(r\triangle ABC, colorYELLOW) label.next_to(tri, RIGHT, buff0.3) label.add_updater(lambda m: m.next_to(tri, RIGHT, buff0.3)) self.add(tri, label) self.wait(0.5) self.play(tri.animate.shift(LEFT * 5), run_time2) self.play(tri.animate.scale(1.6), run_time1.5) self.play(Rotate(tri, PI / 2), run_time1.5) label.clear_updaters() self.play(tri.animate.shift(UP * 1.5)) self.wait()比上一段只多了add_updater那一行。lambda m: ...里的m就是label自己Manim 调用时会传进来。这段后面故意多做了几个动作。三角形放大 1.6 倍、再转 90°标签始终贴在它右边 0.3 的位置自己的大小没变。因为next_to每帧重新读的是三角形外接框的右边缘三角形变大、变形、转向外接框跟着变标签也就跟着让位。最后label.clear_updaters()把 updater 摘掉之后三角形往上走标签又不跟了。做动画时经常需要这样前半段跟着到某个时刻松手让标签留在原地或者单独飞去别处。前面那行label.next_to(...)不要删。add_updater挂上去的时候默认不会先执行一次而且紧跟着的self.wait(0.5)也不会触发它wait期间只有带dt参数的 updater写成lambda m, dt: ...的那种才会被调用像这里lambda m: ...这样不带dt的Manim 认为画面是静止的直接跳过。我们试过把那行删掉标签在开头的半秒里一直待在画面正中央等三角形开始动才跳到它旁边。不想写两遍的话可以用label.add_updater(..., call_updaterTrue)挂上的同时立刻执行一次。改法二装进 VGroup一起动如果标签和图形从头到尾都是一体的不需要中途分开更省事的办法是打包from manim import * class GroupMove(Scene): def construct(self): tri Polygon([-2, -2, 0], [0, 2, 0], [3, 0, 0], colorBLUE) tri.set_fill(BLUE, 0.5).scale(0.5).move_to(RIGHT * 3) label MathTex(r\triangle ABC, colorYELLOW) label.next_to(tri, RIGHT, buff0.3) group VGroup(tri, label) self.add(group) self.wait(0.5) self.play(group.animate.shift(LEFT * 5), run_time2) self.play(group.animate.scale(1.6), run_time1.5) self.wait()注意动画的对象换成了group。平移时两者一起走间距保持 0.3。放大就能看出它和改法一的差别了。对group放大 1.6 倍标签也跟着大了 1.6 倍间距从 0.3 变成 0.48。整组是当一张图在缩放里面的相对位置等比例变。所以怎么选看你要的是哪种「跟着」updaterVGroup平移跟着走跟着走图形放大标签大小不变间距不变标签一起放大间距一起放大图形旋转标签不转贴在新外接框旁边标签一起转中途分开clear_updaters()改回对单个物体做动画每帧开销多调一次函数没有给动点标字母、给会伸缩的线段标长度一般用 updater。一个带文字的图标、一个整体移动的小组件用VGroup。常见写错的地方在循环里写 lambda所有标签都跟着最后一个点这个我们自己也踩过for dot, label in zip(dots, labels): label.add_updater(lambda m: m.next_to(dot, UP))动画一播三个标签全叠到最后一个点上面。原因在 Python不在 Manimlambda 里的dot是等到被调用时才去取值的那时循环早跑完了dot已经是最后一个。用默认参数把当前这个dot留住就好for dot, label in zip(dots, labels): label.add_updater(lambda m, ddot: m.next_to(d, UP))挂了 updater 之后还想手动挪标签label.shift(UP)或者self.play(label.animate.shift(UP))都留不住下一帧 updater 又把它贴回三角形旁边。要挪就先clear_updaters()或者改 updater 里的方向和buff。只动了一次却挂了 updater如果三角形只在某一步挪一下之后就不动了不必上 updater在同一个play里让标签也走过去就行self.play( tri.animate.shift(LEFT * 5), label.animate.shift(LEFT * 5), )常见追问FAQQalways_redraw和这里的add_updater有什么区别Aalways_redraw每一帧把物体重新造一遍适合形状本身要变的东西比如连接两个动点的线段、会伸缩的花括号。标签的形状没变只是换位置用add_updater加next_to就够了不用每帧重新排一次公式。Qupdater 会拖慢渲染吗A一个next_to的计算量很小几十个标签都感觉不出来。慢的是在 updater 里每帧新建MathTex这类重对象。Qself.add之前挂 updater 和之后挂有区别吗A先后顺序没有影响。但物体必须在场景里updater 才会被调用。只挂了 updater 却没add的物体位置不会变。Q我想让标签一直在点的右上方而且离得稍远一点A把方向换成URbuff调大m.next_to(dot, UR, buff0.2)。方向常量可以随便换UP、DL都行。这个知识点在教程《布局上· 描述关系不算坐标》的最后一节有视频讲解旁边的代码可以边看边改updater 的完整用法在《Updater》那一课。来源极坐标⋅XYZ · jizuobiao.xyz · 更新于 2026-10-03 · 基于 Manim Community 0.21.0
延伸阅读

更多相关文章

2026/10/5 4:07:19

大视野视觉引导机械手带角度抓取:旋转中心标定与节拍优化实战

前阵子调试一条四工位转盘线,托盘上的工件每次摆放方向都不一样,机械手要从托盘里把单个工件抓起来放到下一工位。最让人头疼的是视野做得比较大,一个相机要覆盖整个托盘,像素当量已经到0.14毫米左右,而工件定位销孔的…

2026/10/5 4:07:19

python -m 与 python xxx.py 的区别:相对导入与 ImportError 排查

在Python里,python xxx.py和python -m package.module的差别,是很多人在import报错之后才开始认真琢磨的事。我见过不少项目里,明明代码在别人机器上是好的,自己一跑就弹ImportError,排查半天发现只是启动命令不同。尤…

2026/10/5 5:12:21

多模型AI网关实战:统一接入、智能路由与成本治理

多模型时代,应用和模型之间隔着一层"翻译官",这事儿现在越来越绕不过去了。我自己在团队里管过好几个接大模型API的项目,最深的感受就是:模型厂商越来越多,接入方式五花八门,每个API的鉴权、定价…

2026/10/5 5:12:21

LabVIEW多通道DAQ采集:NTC温度与TTL转速同步测量实战

去年做发动机台架测试时,甲方要求同时采集冷却水温度、机油温度、进气温度这几路NTC热敏电阻信号,顺便把曲轴位置传感器输出的TTL方波也收进来,用于实时计算发动机转速。这套需求在LabVIEW里看着简单,实际上手就会发现&#xff1a…

2026/10/5 5:12:21

QuickBlue AI应用底座:企业大模型落地与知识问答实践

1. 先搞清楚“AI 应用底座”到底是个什么东西先别急着聊 QuickBlue,我把话放前面:过去两年我见过太多想上 AI 却上不去的企业。有的是老板拍板买了几万块的大模型 API 额度,结果技术团队折腾一个月,连个能用的内部问答机器人都没跑…

2026/10/5 5:12:21

扫地机器人双脑架构:实时安全控制与Linux功能解耦设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 5:07:21

一维序列转二维图像:GAF、MTF、递归图与STFT方法详解

一维序列转二维图像,这几年在工业界和学术界都快被聊烂了。很多人第一次听到这个操作,会觉得莫名其妙:好好的振动信号、股价曲线、脑电波形,为什么非要折腾成一张图片?真做进去之后才发现,图像化不是花架子…

2026/10/4 0:01:02

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/4 0:01:02

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/4 1:01:05

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑