news 2026/10/7 21:29:12

Manim 排网格:两层 arrange 嵌套,还是 arrange_in_grid?六个大小不一的方块实测对比

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Manim 排网格:两层 arrange 嵌套,还是 arrange_in_grid?六个大小不一的方块实测对比

利益相关:本文作者与极坐标⋅XYZ(jizuobiao.xyz)团队有关联。下面的数字是我们在 Manim Community 0.21.0(2026 年的最新版本)上跑出来的,代码都贴在文里,结论请自行验证。

成员一样大的时候,两种写法排出来的网格一模一样。差别出在成员大小不一的时候:先把每行各自arrange、再把几行上下叠起来,行与行之间互不知道对方,上下对不成列;arrange_in_grid是按整张表算的,同一列的成员中心在一条竖线上。所以要「表格」那种横竖都对齐的效果,用arrange_in_grid;每行个数不一样、或者每行要各自居中,用两层arrange。

Manim 是用 Python 代码写数学动画的开源引擎,3Blue1Brown 的视频就是它做的。它没有「表格布局」「弹性布局」这类东西,排版靠的是VGroup上的几个方法,每个方法调用一次就摆一次位置。排网格能用的就是上面这两条路。

一段代码把两种写法并排放

六个方块,边长依次是 0.5、2、0.5、1、0.5、1.5,间距都用 0.2。左边蓝色是两层arrange,右边黄色是arrange_in_grid:

from manim import * class GridVsNested(Scene): def construct(self): sides = [0.5, 2, 0.5, 1, 0.5, 1.5] def make(color): return [Square(side_length=s, color=color).set_fill(color, 0.5) for s in sides] # 左边:两行各自 arrange,再把两行上下叠起来 m = make(BLUE) row1 = VGroup(*m[:3]).arrange(RIGHT, buff=0.2) row2 = VGroup(*m[3:]).arrange(RIGHT, buff=0.2) nested = VGroup(row1, row2).arrange(DOWN, buff=0.2).move_to([-3.5, 0, 0]) # 右边:同样六个方块,交给 arrange_in_grid grid = VGroup(*make(YELLOW)).arrange_in_grid(rows=2, cols=3, buff=0.2).move_to([3.5, 0, 0]) self.add(nested, grid) self.wait()

不想在本机装环境的话,把这段贴进极坐标⋅XYZ 的工作区点运行就能看,里面装的也是 Manim 0.21.0。

排出来差在哪

我们把每个方块的中心坐标打印了出来,x 以各自那一组的中心为零点:

两层 arrange(左)arrange_in_grid(右)
第一行三个方块的 x-1.45、0、1.45-1.95、-0.25、1.7
第二行三个方块的 x-1.2、-0.25、0.95-1.95、-0.25、1.7
两行的 y0.85、-1.10.85、-1.1
同一行里相邻两个的间隙都是 0.2第一行 0.45、0.7,第二行 0.95、0.95
整体宽 × 高3.4 × 3.74.9 × 3.7

行的高度两边一样,都是按这一行里最高的那个方块来的。

差别全在横向。左边每一行内部间隙严格是 0.2,排得紧,但六个中心落在六个不同的 x 上。右边两行的 x 完全相同,三列对得很齐,代价是间隙不再是 0.2:buff=0.2在这里是格子与格子之间的距离,小方块待在一个比它宽的格子正中,两边自然空出来一截。整体也因此宽了 1.5。

原因在两个方法的做法上。arrange是让第二个成员next_to到第一个旁边、第三个next_to到第二个旁边,一路接下去,它眼里只有相邻的两个。arrange_in_grid先把成员按行列分好,取每一列里最宽的当列宽、每一行里最高的当行高,画出一张格子,再把成员一个个放进去。

排完之后整组的位置也不一样

这一点和对不对齐没关系,但两条路混着用的时候很容易被它绊一下。

arrange排完会把整组挪到画面正中,arrange_in_grid排完整组留在原来的中心。我们把两种写法都先move_to([3, 2, 0])再排:两层arrange排完中心在 (0, 0),前面的move_to白写了;arrange_in_grid排完中心还是 (3, 2)。

所以上面那段代码里,两边的move_to都放在了排列的后面。用arrange的时候这个顺序是必须的,用arrange_in_grid时放前放后都行,统一放后面最省心。

arrange_in_grid 的格子还能怎么调

格子里靠哪边

默认是放在格子正中。cell_alignment=DOWN让每个成员贴着格子底边,我们试了上面那六个方块,同一行的底边 y 变得一样了(第一行 -0.15,第二行 -1.85),像东西摆在架子上。col_alignments="lcr"可以一列一列地指定左、中、右,做左列是名称、右列是数字的小表格时用得上。

格子固定大小

不想让列宽随内容变,可以直接给:col_widths=[2] * 3, row_heights=[2] * 2。这样排完,三列的中心相距都是 2.2(列宽 2 加间隙 0.2),和里面装的方块多大没关系。列表长度要和列数对上,我们试过给三列只传两个宽度,报的是ValueError: col_widths has a mismatching size.

横竖间隙分开设

buff=(0.2, 1.0),第一个数是横向间隙,第二个是纵向间隙。这是量出来的结果;0.21.0 的文档字符串里写的是(row, col),容易理解反。

行列数只写一个

七个成员写cols=3会排成 3、3、1,写rows=2是 4、3。两个都写但装不下(比如七个成员rows=2, cols=3)会报ValueError。

什么时候反而该用两层 arrange

arrange_in_grid有一件事做不到:每行各自居中。

七个边长 1 的方块arrange_in_grid(cols=3, buff=0.2),前两行的 x 是 -1.2、0、1.2,第三行只有一个,它在 x = -1.2,靠最左。网格是按格子填的,不满的那一行从第一格开始放。

换成两层arrange,每行是一个独立的小组,最外层arrange(DOWN)时默认中心对中心,第三行那一个就在 x = 0,居中了。

同样的道理,每行个数本来就不一样的排法只能用两层arrange。比如 1、2、3 的三角堆:

sq = [Square(side_length=1) for _ in range(6)] rows = VGroup(VGroup(sq[0]), VGroup(*sq[1:3]), VGroup(*sq[3:])) for r in rows: r.arrange(RIGHT, buff=0.2) rows.arrange(DOWN, buff=0.2)

排出来第一行在 x = 0,第二行在 ±0.6,第三行在 -1.2、0、1.2,每行都以中线对称。

小结

两层 arrangearrange_in_grid
成员一样大结果相同结果相同
成员大小不一行内间隙相等,上下不成列行列都对齐,间隙随格子变
每行个数不同、每行各自居中能不能,不满的行靠左
排完整组的位置回到原点留在原来的中心
格内对齐、固定格子大小没有cell_alignment、col_alignments、col_widths
代码量每行一个小组,外面再套一层一行

arrange的buff、aligned_edge、center=False这些基础用法,以及往VGroup里放图片报错怎么办,在极坐标⋅XYZ 的这篇文章里写得更细;配套视频在教程《布局(下)· 尺寸 / 包围 / 编组 / 深度 + 实战》的第三节。

实测环境:Manim Community 0.21.0 · 2026 年 10 月

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

知识点16:案例实战:LangChain + MCP 打造任务分解Agent

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

作者头像 李华
网站建设 2026/10/7 21:19:51

云端服务启动后浏览器访问失败:先查端口链路还是重装应用?

云端服务启动后浏览器访问失败:先查端口链路还是重装应用? 云端 Web 服务排查里,最常见的误判之一就是: 看到服务已经启动,就默认浏览器应该可以访问。 这两个状态其实不是一回事。 “服务启动”说明服务进程或服务本身…

作者头像 李华
网站建设 2026/10/7 21:11:17

GHelper:3 个前置确认,10 分钟替代奥创中心

GHelper:3 个前置确认,10 分钟替代奥创中心 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivobook, Zenbook, E…

作者头像 李华