Scenes and groups
Scene semantics of clear / remove, VGroup indexing and nesting, loop-built groups, and what an upright 3D camera looks like.
This page lists 6 examples. The code is imported from corpus/examples/scene/; the screenshots are end states rendered on real machines.
Redraw after clear
clear empties the frame; the mobjects drawn afterwards appear on their own.

"""clear 后重新画
@expect clear 后画面清空,随后新画的物体单独出现。"""
from manim import *
class ClearScene(Scene):
def construct(self):
self.add(Circle(radius=1.5))
self.wait(0.2)
self.clear()
self.add(Square(side_length=2))
self.wait(0.2)remove takes a mobject out
The removed mobject disappears while the others stay as they were: the scene holds three mobjects and only one is removed (the red circle, labelled remove); in the final frame the blue square and the yellow triangle remain and the red circle does not — evidence that exactly one was removed.

"""remove 摘掉物体
@expect 被 remove 的物体消失,其余物体原样保留:场景放三个物体,
只 remove 其中一个(红圆,标注「remove」),终帧蓝方块与黄三角
仍在、红圆不在——「只删一个」自证。
"""
from manim import *
class RemoveScene(Scene):
def construct(self):
square = Square(side_length=1.6, color=BLUE)
square.move_to([-3.5, 0, 0])
circle = Circle(radius=0.9, color=RED)
circle.move_to([0, 0, 0])
triangle = Triangle(color=YELLOW)
triangle.move_to([3.5, 0, 0])
self.play(Create(square), Create(circle), Create(triangle))
gone = Text("remove", font_size=24, color=RED)
gone.move_to([0, 1.6, 0])
stay = Text("保留", font_size=24, color=GREY_A)
stay.move_to([-3.5, 1.6, 0])
stay2 = Text("保留", font_size=24, color=GREY_A)
stay2.move_to([3.5, 1.6, 0])
self.play(FadeIn(gone), FadeIn(stay), FadeIn(stay2))
# 只摘红圆一个,其余原样保留
self.remove(circle)
self.wait(0.3)VGroup plus index access
An indexed child is manipulated on its own; an out-of-range index raises IndexError (the print assertion is authoritative).

"""VGroup + 下标取子物体
@expect 下标取出的子物体单独被操作,越界下标抛 IndexError(print 断言为准)。"""
from manim import *
class VgroupIndexScene(Scene):
def construct(self):
dots = VGroup(*[Dot(point=[i - 2, 0, 0]) for i in range(5)])
self.play(FadeIn(dots))
self.play(dots[0].animate.set_color(RED))
self.wait(0.3)VGroup inside VGroup
The outer group moves as a whole and the inner group moves on its own; the two layers do not leak into each other. Self-evidence: after the outer group moves up the red dot follows, then the inner group turns yellow on its own while the red dot's colour stays.

"""VGroup 套 VGroup
@expect 嵌套组整体动、子组也单独动,两层互不串。
自证:外层整体上移后红点跟着走,内层再单独变黄、红点颜色不变。"""
from manim import *
class VgroupNestedScene(Scene):
def construct(self):
inner = VGroup(Circle(radius=0.4), Square(side_length=0.6))
inner.arrange(RIGHT, buff=0.3)
outer = VGroup(inner, Dot(point=[0, -1.5, 0], color=RED))
self.play(FadeIn(outer))
# 第一步:外层整体上移——圆、方、红点一起动
self.play(outer.animate.shift(UP * 0.8))
# 第二步:内层单独变色——只有圆和方变黄,红点不动也不变色
self.play(inner.animate.set_color(YELLOW))
note = Text("外层整体上移,内层单独变色", font_size=24).move_to([0, -3.2, 0])
self.play(FadeIn(note))
self.wait(0.3)Building a row of squares in a loop
A row (column) of squares built in a loop; the count matches the iteration count.

"""循环搭一组方块
@expect 循环搭出的一排(一列)方块,数量与循环次数一致。
@note VGroup() 无参构造 + add 累积,是很常见的搭法
"""
from manim import *
class LoopBuildScene(Scene):
def construct(self):
squares = VGroup()
for i in range(4):
sq = Square(side_length=0.8, color=BLUE)
sq.shift(RIGHT * (i * 1.2 - 1.8))
squares.add(sq)
self.play(Create(squares))
self.wait(0.3)The upright 3D camera: the x axis must be horizontal on screen
Five cubes form a true cross: red (x=-4) on the left and blue (x=+4) on the right at exactly the same height; yellow (y=+3) above and orange (y=-3) below at exactly the same horizontal position as the green centre cube. Each cube shows its top and front face (lit, with depth).

"""3D 相机的「正」:x 轴该在屏幕上水平
@expect 五个立方体排成一个**正十字**:红(x=-4)在左、蓝(x=+4)在右,两者的高低完全一样;
黄(y=+3)在上、橙(y=-3)在下,两者与中间绿块的横向位置完全一样。
立方体各自露出顶面与正面(有光、有深度)。
@note 这条是「相机没被滚转」的哨兵,因为滚转是**看不出来的错**:相机位置、角度全都对,
`getOrbitAngles()` 读回来分毫不差,只有画面歪——任何几何断言都抓不到它。
2026-10-11 实测:manim-web 0.3.24 的 `Camera3D.orbit` 用 `this._up || (…)` 把「相机朝上」
锁在**第一次**调用上,于是建场景时那组默认角度(phi=70°/theta=-135°)会一直残留——
这里渲出来就是 x 轴的三个立方体**斜着往上**(歪 15°)。修法与出处见
`src/engine/manim-patch.ts`。
"""
from manim import *
class ThreeDUprightScene(ThreeDScene):
def construct(self):
self.set_camera_orientation(phi=50 * DEGREES, theta=-90 * DEGREES) # 正面俯视:x 轴该水平
self.add(
Cube(color=RED).shift([-4, 0, 0]),
Cube(color=GREEN).shift([0, 0, 0]),
Cube(color=BLUE).shift([4, 0, 0]),
Cube(color=YELLOW).shift([0, 3, 0]),
Cube(color=ORANGE).shift([0, -3, 0]),
)