Examples

Runnable examples for the currently supported feature set. Previews are lazy and only compile when you click Render preview, so opening this page does not trigger a flood of compile requests.

Core Objects

  • - Circle, Square, Rectangle, Line, Arrow, Dot, Polygon, RegularPolygon
  • - Text, Tex, MathTex
  • - ImageMobject, SVGMobject
  • - Group and VGroup

Animation Primitives

  • - Create, FadeIn, FadeOut, Write, Unwrite, GrowFromCenter, GrowFromPoint, ShrinkToCenter, Uncreate
  • - Rotate, Shift, MoveTo, Scale, ScaleInPlace
  • - Transform, ReplacementTransform, TransformFromCopy, ClockwiseTransform, CounterclockwiseTransform
  • - MoveToTarget, ApplyMethod, MoveAlongPath, ApplyPointwiseFunction
  • - AnimationGroup, LaggedStart, LaggedStartMap

Scene Features

  • - Camera frame animate, move_camera, zoom_camera
  • - add_fixed_in_frame_mobjects for HUD/static overlays
  • - Updaters via add_updater / clear_updaters
  • - Voiceovers, captions, background audio, image assets
  • - Compilation diagnostics with line and column mapping

Runnable Example Library

Browse examples by topic, search through supported patterns, and render any scene directly in the browser.

Timing

1
Timing

run_time on play

Slow down an animation with run_time.

scene = Scene(fps=30, width=640, height=360)square = Square()scene.add(square)scene.play(square.animate.shift(UP), run_time=3)scene.wait(1)
run_time on play preview

Styling

2
Styling

set_stroke / set_fill

Change stroke and fill on multiple shapes.

scene = Scene(fps=30, width=640, height=360)circle = Circle().shift(LEFT)square = Square().shift(UP)triangle = Triangle().shift(RIGHT)circle.set_stroke(color=GREEN, width=20)square.set_fill(YELLOW, opacity=1.0)triangle.set_fill(PINK, opacity=0.5)scene.add(circle, square, triangle)scene.wait(1)
set_stroke / set_fill preview
Styling

Z-order via add order

Order of add() controls stacking.

scene = Scene(fps=30, width=640, height=360)circle = Circle().shift(LEFT).set_stroke(color=GREEN, width=20)square = Square().shift(UP).set_fill(YELLOW, opacity=1.0)triangle = Triangle().shift(RIGHT).set_fill(PINK, opacity=0.5)scene.add(triangle, square, circle)scene.wait(1.5)
Z-order via add order preview

Transforms

5
Transforms

Transform between shapes

Square to Rectangle with rotation.

scene = Scene(fps=30, width=640, height=360, backgroundColor=WHITE)m1 = Square().set_color(RED)m2 = Rectangle(width=3, height=2).set_color(RED).rotate(0.2)scene.add(m1, m2)scene.play(Transform(m1, m2), run_time=1.5)scene.wait(1)
Transform between shapes preview
Transforms

Squares to circles side-by-side

Pair of squares morphing into circles simultaneously.

scene = Scene(fps=60, width=960, height=540, backgroundColor=WHITE)m1a = Square().set_color(RED).shift(LEFT)m1b = Circle().set_color(RED).shift(LEFT)m2a = Square().set_color(BLUE).shift(RIGHT)m2b = Circle().set_color(BLUE).shift(RIGHT)scene.play(Transform(m1a, m1b), Transform(m2a, m2b), run_time=1.2)scene.wait(0.8)
Squares to circles side-by-side preview
Transforms

Square to circle with rolled points

Compares normal and rolled point-order transforms in parallel.

class ExampleRotation(Scene):    def construct(self):        self.camera.background_color = WHITE        m1a = Square().set_color(RED).shift(LEFT)        m1b = Circle().set_color(RED).shift(LEFT)        m2a = Square().set_color(BLUE).shift(RIGHT)        m2b = Circle().set_color(BLUE).shift(RIGHT)         points = m2a.points        points = np.roll(points, int(len(points) / 4), axis=0)        m2a.points = points         self.play(Transform(m1a, m1b), Transform(m2a, m2b), run_time=1) scene = ExampleRotation()scene.construct()
Square to circle with rolled points preview
Transforms

Triangle to Square

Morph an equilateral triangle into a square.

scene = Scene(fps=60, width=960, height=540, backgroundColor=WHITE)tri = Triangle().set_color(ORANGE).shift(LEFT*1.5)sqr = Square().set_color(ORANGE).shift(LEFT*1.5)scene.add(tri)scene.play(Transform(tri, sqr), run_time=1.2)scene.wait(0.8)
Triangle to Square preview
Transforms

Rounded rectangle to circle

Wide rectangle easing into a circle.

scene = Scene(fps=60, width=960, height=540, backgroundColor=WHITE)rect = Rectangle(width=4, height=2).set_color(TEAL).shift(RIGHT*1.5)circ = Circle().set_color(TEAL).shift(RIGHT*1.5)scene.add(rect)scene.play(Transform(rect, circ), run_time=1.2)scene.wait(0.8)
Rounded rectangle to circle preview

Camera

2
Camera

Simple camera move

Pan and zoom the frame.

scene = Scene(fps=30, width=640, height=360, backgroundColor=BLACK)grid = NumberPlane()scene.add(grid)scene.move_camera(position=LEFT * 2, zoom=1.3, run_time=1.5, rate_func=smooth)scene.wait(0.5)scene.move_camera(position=RIGHT * 2, zoom=0.9, run_time=1.5, rate_func=smooth)scene.wait(0.5)
Simple camera move preview
Camera

Camera frame animate

Use the 2D camera frame animate proxy to pan and zoom around a layout.

scene = Scene(fps=30, width=960, height=540, backgroundColor="#020617") plane = NumberPlane().set_stroke(color=GREY_D, width=1)left = Circle(color=BLUE).scale(1.2).shift(LEFT * 3)right = Square(color=YELLOW).scale(1.1).shift(RIGHT * 3)label = Text("Frame animate", font_size=36, color=WHITE).to_edge(UP) scene.add(plane, left, right, label)scene.play(scene.camera.frame.animate.move_to(LEFT * 3).set(zoom=1.5), run_time=1.4)scene.play(scene.camera.frame.animate.move_to(RIGHT * 3).set(zoom=1.3), run_time=1.4)scene.play(scene.camera.frame.animate.move_to(ORIGIN).set(zoom=1.0), run_time=1.2)scene.wait(0.4)
Camera frame animate preview

Animations

4
Animations

animate method chaining

Animate property setters and transforms.

scene = Scene(fps=30, width=640, height=360)square = Square().set_fill(RED, opacity=1.0)scene.add(square)scene.play(square.animate.set_fill(WHITE), run_time=1)scene.play(square.animate.shift(UP).rotate(PI / 3), run_time=1.5)scene.wait(1)
animate method chaining preview
Animations

FadeIn / Rotate / FadeOut

Core Animation examples.

scene = Scene(fps=30, width=640, height=360)square = Square()scene.play(FadeIn(square))scene.play(Rotate(square, PI / 4))scene.play(FadeOut(square))scene.wait(1)
FadeIn / Rotate / FadeOut preview
Animations

LaggedStart bounce

Three shapes move with a small lag.

scene = Scene(fps=30, width=640, height=360)circle = Circle().shift(LEFT * 2)square = Square().shift(ORIGIN)triangle = Triangle().shift(RIGHT * 2)scene.add(circle, square, triangle)scene.play(    LaggedStart(        circle.animate.shift(UP * 1.5),        square.animate.shift(DOWN * 1.0),        triangle.animate.shift(UP * 1.5),        lag_ratio=0.2    ),    run_time=2,    rate_func=there_and_back)scene.wait(0.5)
LaggedStart bounce preview
Animations

AnimationGroup move_to

Two objects move at the same time with lag_ratio=0.

scene = Scene(fps=30, width=640, height=360)car = Dot(point=LEFT * 4 + UP * 1, color=RED)bus = Dot(point=LEFT * 4 + DOWN * 1, color=BLUE)scene.add(car, bus) car_end_pos = RIGHT * 4 + UP * 1gpu_end_pos_latency = LEFT * 0.5 + DOWN * 1bus_latency_time = 3 scene.play(    AnimationGroup(        car.animate.move_to(car_end_pos),        bus.animate.move_to(gpu_end_pos_latency),        lag_ratio=0    ),    run_time=bus_latency_time,    rate_func=linear)scene.wait(0.5)
No preview image yet

Graphs

1
Graphs

Axes with function graph

Plot a sine wave on axes.

scene = Scene(fps=30, width=640, height=360)axes = Axes(x_range=(-3, 3, 1), y_range=(-1.5, 1.5, 0.5))graph = FunctionGraph(lambda x: sin(x), color=BLUE)scene.add(axes)scene.play(Create(graph), run_time=2)scene.wait(1)
Axes with function graph preview

Basics

2
Basics

Shapes placement

Circle, Square, Triangle shifted in different directions.

scene = Scene(fps=30, width=640, height=360)circle = Circle().shift(LEFT)square = Square().shift(UP)triangle = Triangle().shift(RIGHT)scene.add(circle, square, triangle)scene.wait(1)
Shapes placement preview
Basics

CreatingMobjects

Add and remove a circle with waits.

scene = Scene(fps=30, width=640, height=360)circle = Circle()scene.add(circle)scene.wait(1)scene.remove(circle)scene.wait(1)
CreatingMobjects preview

Text

2
Text

Code and table layout

Render `Code` and `Table` side by side to probe text fitting and layout stability.

scene = Scene(fps=30, width=960, height=540, backgroundColor="#0f172a") code = Code("total = 0\nfor value in range(4):\n    total += value")table = Table([    ["Metric", "Value"],    ["Frames", "120"],    ["FPS", "30"],    ["Status", "Ready"],]) code.to_edge(LEFT, buff=0.8)table.to_edge(RIGHT, buff=0.8)title = Text("Text-backed layout objects", font_size=34, color=WHITE).to_edge(UP) scene.play(FadeIn(title), FadeIn(code), FadeIn(table), run_time=1.2)scene.wait(0.8)
Code and table layout preview
Text

Write text

Demonstrate Write animation on Text.

scene = Scene(fps=30, width=640, height=360)hello = Text("Hello, Manim!", font_size=48)scene.play(Write(hello), run_time=2)scene.wait(1)
Write text preview

General

1
General

Sine-Wave Glide

A blue circle animates from the left edge to the right edge over 5 seconds, tracing a smooth full-cycle sine wave at half the scene’s height while maintaining its stroke width.

scene = Scene(fps=60) dot = Circle(radius=1, color=BLUE, strokeWidth=8)scene.add(dot) start_x = -scene.frame_width / 2end_x = scene.frame_width / 2travel_time = scene.durationvx = (end_x - start_x) / travel_timeamplitude = scene.frame_height / 4  # half the scene height def drift(mob, dt):    # accumulate elapsed time on the mob    t = getattr(mob, "_t", 0) + dt    mob._t = t    x = start_x + vx * t    y = amplitude * sin((t / travel_time) * TAU)  # full sine wave over the run    mob.position = (x, y, 0) dot.add_updater(drift)scene.wait(travel_time)dot.remove_updater(drift)
Sine-Wave Glide preview

Updaters

4
Updaters

ValueTracker with DecimalNumber

Animate a number changing smoothly.

scene = Scene(fps=30, width=640, height=360)tracker = ValueTracker(0)number = DecimalNumber(tracker.get_value()).scale(3)number.add_updater(lambda m, dt: m.set_value(tracker.get_value()).move_to(ORIGIN))scene.add(number)scene.play(tracker.animate.set_value(100), run_time=3)scene.wait(0.5)
ValueTracker with DecimalNumber preview
Updaters

ValueTracker driving a moving dot

A ValueTracker updates both a dot position and a label via updaters.

scene = Scene(fps=30, width=640, height=360) tracker = ValueTracker(0)dot = Circle(radius=0.3, color=BLUE)label = DecimalNumber(tracker.get_value()).scale(1.6) def update_dot(mob, dt):    x = -3 + (tracker.get_value() / 100) * 6  # map 0→100 to -3→+3    mob.move_to((x, 0, 0)) def update_label(mob, dt):    mob.set_value(tracker.get_value())    mob.next_to(dot, UP, buff=0.3) dot.add_updater(update_dot)label.add_updater(update_label) scene.add(dot, label)scene.play(tracker.animate.set_value(100), run_time=3)scene.wait(0.5)
ValueTracker driving a moving dot preview
Updaters

Tracker-driven plot

ValueTracker animates a line and moving dot on Axes via always_redraw.

scene = Scene(fps=60, width=800, height=450) axes = Axes(    x_range=[0, 4, 1],    y_range=[0, 3, 1],    x_length=7,    y_length=4,).to_edge(DOWN, buff=0.6) def func(x):    return 0.5 + 0.5 * x + 0.6 * sin(x * PI / 2) tracker = ValueTracker(0) line = always_redraw(lambda: axes.plot(func, x_range=[0, tracker.get_value()], color=BLUE, stroke_width=5))dot = always_redraw(lambda: Dot(axes.c2p(tracker.get_value(), func(tracker.get_value())), color=YELLOW).scale(1.1)) scene.add(axes, line, dot)scene.play(tracker.animate.set_value(4), run_time=3, rate_func=linear)scene.wait(0.5)
Tracker-driven plot preview
Updaters

Mini Great Plateau

A tracker sweeps a timeline while always_redraw grows a plot and tip dot.

scene = Scene(fps=30, width=640, height=360) axes = Axes(    x_range=[1970, 2030, 10],    y_range=[0, 9, 1],    x_length=9,    y_length=5,    axis_config={"include_tip": False, "stroke_width": 2, "color": GREY_C},    x_axis_config={"numbers_to_include": [1970, 1990, 2010, 2030]},).move_to(ORIGIN) START_VISIBLE_YEAR = 1971.2year_tracker = ValueTracker(1970) # --- Data series ---def get_transistor_y(year):    return 0.5 + (year - 1970) * (8.0 / 55.0) def get_clock_y(year):    if year <= 2005:        return 0.3 + (year - 1970) * (3.9 / 35.0)    else:        return 4.2 + (year - 2005) * (0.3 / 20.0) def get_cores_y(year):    if year <= 2005:        return 0    else:        return (year - 2005) * (5.0 / 20.0) # --- Helpers ---def get_line_graph(func, color, stroke=3):    return always_redraw(        lambda: VGroup() if year_tracker.get_value() < START_VISIBLE_YEAR else axes.plot(            func,            x_range=[1970, year_tracker.get_value()],            color=color,            stroke_width=stroke        )    ) def get_tip_dot(func, color):    return always_redraw(        lambda: VGroup() if year_tracker.get_value() < START_VISIBLE_YEAR else Dot(            point=axes.c2p(                year_tracker.get_value(),                func(year_tracker.get_value())            ),            color=color        ).scale(0.8)    ) # --- Series visuals ---line_trans = get_line_graph(get_transistor_y, TEAL, stroke=5)line_clock = get_line_graph(get_clock_y, MAROON, stroke=5)line_cores = get_line_graph(get_cores_y, GOLD, stroke=4) dot_trans = get_tip_dot(get_transistor_y, TEAL)dot_clock = get_tip_dot(get_clock_y, MAROON)dot_cores = get_tip_dot(get_cores_y, GOLD) x_label = Tex("Year", font_size=22, color=GREY_B).next_to(axes.x_axis, DOWN, buff=0.25)y_label = Tex("Performance (arb.)", font_size=22, color=GREY_B).rotate(-90 * DEGREES).next_to(axes.y_axis, LEFT, buff=0.3) scene.add(axes, line_trans, line_clock, line_cores, dot_trans, dot_clock, dot_cores, x_label, y_label)scene.play(year_tracker.animate.set_value(START_VISIBLE_YEAR), run_time=0.5, rate_func=linear)scene.play(year_tracker.animate.set_value(2005), run_time=2, rate_func=linear)scene.play(year_tracker.animate.set_value(2025), run_time=1.5, rate_func=linear)scene.wait(0.5)
Mini Great Plateau preview

Positioning

1
Positioning

move_to / next_to / align_to

Relative and absolute placement helpers.

scene = Scene(fps=30, width=640, height=360)circle = Circle()square = Square()triangle = Triangle()circle.move_to(LEFT * 2)square.next_to(circle, LEFT)triangle.align_to(circle, LEFT)scene.add(circle, square, triangle)scene.wait(1)
move_to / next_to / align_to preview

Geometry

1
Geometry

Line points / start / end / center

Build a polyline via append_points and inspect sampled anchor points.

class MobjectExample(Scene):    def construct(self):        p1 = [-1,-1, 0]        p2 = [ 1,-1, 0]        p3 = [ 1, 1, 0]        p4 = [-1, 1, 0]        a  = Line(p1,p2).append_points(Line(p2,p3).points).append_points(Line(p3,p4).points)        point_start  = a.get_start()        point_end    = a.get_end()        point_center = a.get_center()        self.add(Text(f"a.get_start() = {np.round(point_start,2).tolist()}", font_size=24).to_edge(UR).set_color(YELLOW))        self.add(Text(f"a.get_end() = {np.round(point_end,2).tolist()}", font_size=24).next_to(self.mobjects[-1],DOWN).set_color(RED))        self.add(Text(f"a.get_center() = {np.round(point_center,2).tolist()}", font_size=24).next_to(self.mobjects[-1],DOWN).set_color(BLUE))         self.add(Dot(a.get_start()).set_color(YELLOW).scale(2))        self.add(Dot(a.get_end()).set_color(RED).scale(2))        self.add(Dot(a.get_top()).set_color(GREEN_A).scale(2))        self.add(Dot(a.get_bottom()).set_color(GREEN_D).scale(2))        self.add(Dot(a.get_center()).set_color(BLUE).scale(2))        self.add(Dot(a.point_from_proportion(0.5)).set_color(ORANGE).scale(2))        self.add(*[Dot(x) for x in a.points])        self.add(a) scene = MobjectExample()scene.construct()
Line points / start / end / center preview

Movement

2
Movement

MoveAlongPath on a circle

Animate a dot around a circular guide path while leaving the guide visible.

scene = Scene(fps=30, width=960, height=540, backgroundColor="#020617") orbit = Circle(radius=2.2, color=GREY_C)planet = Dot(color=YELLOW).move_to(orbit.point_from_proportion(0))sun = Dot(color=ORANGE).scale(1.8)title = Text("MoveAlongPath", font_size=34, color=WHITE).to_edge(UP) scene.add(orbit, sun, planet, title)scene.play(MoveAlongPath(planet, orbit), run_time=3.2, rate_func=linear)scene.wait(0.4)
MoveAlongPath on a circle preview
Movement

Rate function comparison

Three dots traverse the same distance with linear, smooth, and there_and_back timing.

scene = Scene(fps=30, width=960, height=540, backgroundColor="#020617") base = Line(LEFT * 4, RIGHT * 4, color=GREY_D)labels = VGroup(    Text("linear", font_size=22, color=BLUE),    Text("smooth", font_size=22, color=GREEN),    Text("there_and_back", font_size=22, color=YELLOW),).arrange(DOWN, aligned_edge=LEFT, buff=0.9).move_to(LEFT * 4.8) dots = VGroup(    Dot(color=BLUE).move_to(LEFT * 4 + UP * 1.2),    Dot(color=GREEN).move_to(LEFT * 4),    Dot(color=YELLOW).move_to(LEFT * 4 + DOWN * 1.2),) scene.add(    base.copy().shift(UP * 1.2),    base,    base.copy().shift(DOWN * 1.2),    labels,    dots,)scene.play(dots[0].animate.move_to(RIGHT * 4 + UP * 1.2), run_time=2.4, rate_func=linear)scene.play(dots[1].animate.move_to(RIGHT * 4), run_time=2.4, rate_func=smooth)scene.play(dots[2].animate.move_to(RIGHT * 4 + DOWN * 1.2), run_time=2.4, rate_func=there_and_back)scene.wait(0.4)
Rate function comparison preview

Audio & Voiceover

1
Audio & Voiceover

Narrated 3D scene

Use VoiceoverThreeDScene to keep captions and a 3D camera move aligned on the same timeline.

from manim import * class NarratedOrbitScene(VoiceoverThreeDScene):    def construct(self):        self.add_voiceover(            "intro",            "The camera reveals a cube while the caption timeline stays aligned.",            1.8,        )        self.set_camera_orientation(phi=70 * DEGREES, theta=-40 * DEGREES, distance=7.5)         header = self.create_header(            "VoiceoverThreeDScene",            "Reusable narration on top of ThreeDScene",        )        self.add_fixed_in_frame_mobjects(header)         axes = ThreeDAxes()        cube = Cube().set_color(BLUE)        cube.rotate(18 * DEGREES, axis=RIGHT)        cube.rotate(24 * DEGREES, axis=UP)         self.add(axes)        with self.play_voiceover_block("intro"):            self.play(FadeIn(cube), run_time=0.6)            self.move_camera(                phi=62 * DEGREES,                theta=-18 * DEGREES,                distance=6.9,                run_time=1.2,            )        self.wait(0.3) scene = NarratedOrbitScene()scene.construct()
Narrated 3D scene preview

Camera & 3D

2
Camera & 3D

3D cube camera move

Set an initial 3D camera orientation, reveal a cube, and animate the camera to a new view.

from manim import * class SimpleCubeScene(ThreeDScene):    def construct(self):        self.set_camera_orientation(            phi=72 * DEGREES,            theta=-42 * DEGREES,            distance=7.5,        )         cube = Cube()         self.add(cube)        self.play(FadeIn(cube, scale=0.92), run_time=0.8)        self.move_camera(            phi=64 * DEGREES,            theta=-28 * DEGREES,            distance=7.1,            run_time=1.6,        )        self.wait(1.2) scene = SimpleCubeScene()scene.construct()
3D cube camera move preview
Camera & 3D

3D scene with fixed overlay

Combine a 3D object with a title that stays fixed in screen space.

from manim import * class FixedOverlayScene(ThreeDScene):    def construct(self):        self.set_camera_orientation(phi=68 * DEGREES, theta=-35 * DEGREES, distance=7.2)         title = Text("Fixed overlay", font_size=34, color=YELLOW).to_edge(UP)        subtitle = Text("HUD stays flat while the 3D camera moves", font_size=20, color=WHITE).next_to(title, DOWN, buff=0.12)        self.add_fixed_in_frame_mobjects(title, subtitle)        self.add(title, subtitle)         axes = ThreeDAxes()        cube = Cube().set_color(BLUE)        cube.rotate(20 * DEGREES, axis=RIGHT)        cube.rotate(25 * DEGREES, axis=UP)         self.add(axes, cube)        self.begin_ambient_camera_rotation(rate=0.18)        self.wait(2.5)        self.stop_ambient_camera_rotation()        self.wait(0.3) scene = FixedOverlayScene()scene.construct()
3D scene with fixed overlay preview

3D

3
3D

3D primitives gallery

Stage several 3D primitives on axes and orbit the camera around them.

from manim import * class ThreeDGalleryScene(ThreeDScene):    def construct(self):        self.set_camera_orientation(phi=70 * DEGREES, theta=-40 * DEGREES, distance=10)         axes = ThreeDAxes(x_length=6, y_length=4, z_length=4)        cube = Cube().set_color(BLUE).shift(LEFT * 2)        sphere = Sphere(radius=0.8).set_color(GREEN)        cylinder = Cylinder(radius=0.45, height=1.8).set_color(YELLOW).shift(RIGHT * 2)         label = Text("Cube   Sphere   Cylinder", font_size=22, color=WHITE).to_edge(DOWN)        self.add_fixed_in_frame_mobjects(label)         self.add(axes, cube, sphere, cylinder, label)        self.play(FadeIn(cube), FadeIn(sphere), FadeIn(cylinder), run_time=1.0)        self.begin_ambient_camera_rotation(rate=0.12)        self.wait(2.4)        self.stop_ambient_camera_rotation()        self.wait(0.4) scene = ThreeDGalleryScene()scene.construct()
3D primitives gallery preview
3D

3D surface wave

Plot a parametric surface and rotate the camera to read its shape.

from manim import *import numpy as np class SurfaceWaveScene(ThreeDScene):    def construct(self):        self.set_camera_orientation(phi=72 * DEGREES, theta=-35 * DEGREES, distance=8.5)         axes = ThreeDAxes(x_length=5, y_length=5, z_length=3)        surface = Surface(            lambda u, v: [u, v, 0.35 * np.sin(2 * u) * np.cos(2 * v)],            u_range=[-1.8, 1.8],            v_range=[-1.8, 1.8],            resolution=(16, 16),            color=BLUE,        )        mesh = SurfaceMesh(surface, color=WHITE, stroke_width=1)         self.add(axes, surface, mesh)        self.move_camera(phi=62 * DEGREES, theta=-15 * DEGREES, distance=7.8, run_time=1.8)        self.wait(1.0) scene = SurfaceWaveScene()scene.construct()
3D surface wave preview
3D

Checkerboard surface fill

Alternate face colors across a sampled surface with set_fill_by_checkerboard.

from manim import *import numpy as np class CheckerboardSurfaceScene(ThreeDScene):    def construct(self):        self.set_camera_orientation(phi=72 * DEGREES, theta=-35 * DEGREES, distance=8.0)         axes = ThreeDAxes(x_length=5, y_length=5, z_length=3)        surface = Surface(            lambda u, v: [u, v, 0.35 * np.sin(2 * u) * np.cos(2 * v)],            u_range=[-1.8, 1.8],            v_range=[-1.8, 1.8],            resolution=(10, 10),        )        surface.set_fill_by_checkerboard(BLUE_D, BLUE_E, opacity=0.95)         self.add(axes, surface)        self.move_camera(phi=60 * DEGREES, theta=-18 * DEGREES, distance=7.4, run_time=1.8)        self.wait(0.6) scene = CheckerboardSurfaceScene()scene.construct()
Checkerboard surface fill preview