MathViz Tutorials
Learn from Zero to Hero -- 15 hands-on lessons
Learn MathViz Step by Step
Follow these 15 tutorials from Hello Circle to advanced 3D animations.
Each lesson shows the .mviz source alongside the compiled Python output, plus a rendered video preview.
Save any example to a .mviz file and run: mathviz compile example.mviz
Step 0 / 15
Beginner
Fundamentals
Master the basics: shapes, text, animations, and positioning.
1
Hello Circle
What you will learn
- The
scenekeyword defines a Manim Scene class fn construct(self)is the entry point for every animationCreate()draws a shape,FadeOut()removes it.animateenables smooth property transitions
// Tutorial 01: Hello Circle
// Your very first MathViz animation
scene HelloCircle {
fn construct(self) {
let circle = Circle()
circle.set_color(BLUE)
circle.set_fill(BLUE, opacity: 0.5)
self.play(Create(circle))
self.wait(1)
// Animate the circle changing color
self.play(circle.animate.set_color(YELLOW))
self.wait(0.5)
// Scale it up
self.play(circle.animate.scale(2))
self.wait(0.5)
// Fade it out
self.play(FadeOut(circle))
}
}
from manim import *
class HelloCircle(Scene):
def construct(self):
circle = Circle()
circle.set_color(BLUE)
circle.set_fill(BLUE, opacity=0.5)
self.play(Create(circle))
self.wait(1)
self.play(circle.animate.set_color(YELLOW))
self.wait(0.5)
self.play(circle.animate.scale(2))
self.wait(0.5)
self.play(FadeOut(circle))
2
Basic Shapes
What you will learn
Circle,Square, andTrianglecreate geometric shapes- Named parameters use colon syntax:
radius: 0.8 shift()moves objects by a direction vector- Multiple animations can be played simultaneously
// Tutorial 02: Basic Shapes
// Create circles, squares, triangles, and stars
scene BasicShapes {
fn construct(self) {
let circle = Circle(radius: 0.8, color: BLUE)
let square = Square(side_length: 1.5, color: RED)
let triangle = Triangle(color: GREEN)
triangle.scale(1.2)
circle.shift(LEFT * 3)
triangle.shift(RIGHT * 3)
self.play(Create(circle))
self.play(Create(square))
self.play(Create(triangle))
self.wait(0.5)
let l1 = Text("Circle", color: BLUE)
l1.scale(0.5)
l1.next_to(circle, DOWN)
let l2 = Text("Square", color: RED)
l2.scale(0.5)
l2.next_to(square, DOWN)
let l3 = Text("Triangle", color: GREEN)
l3.scale(0.5)
l3.next_to(triangle, DOWN)
self.play(Write(l1), Write(l2), Write(l3))
self.wait(1)
self.play(FadeOut(circle), FadeOut(square), FadeOut(triangle))
self.play(FadeOut(l1), FadeOut(l2), FadeOut(l3))
}
}
from manim import *
class BasicShapes(Scene):
def construct(self):
circle = Circle(radius=0.8, color=BLUE)
square = Square(side_length=1.5, color=RED)
triangle = Triangle(color=GREEN)
triangle.scale(1.2)
circle.shift((LEFT * 3))
triangle.shift((RIGHT * 3))
self.play(Create(circle))
self.play(Create(square))
self.play(Create(triangle))
self.wait(0.5)
l1 = Text('Circle', color=BLUE)
l1.scale(0.5)
l1.next_to(circle, DOWN)
l2 = Text('Square', color=RED)
l2.scale(0.5)
l2.next_to(square, DOWN)
l3 = Text('Triangle', color=GREEN)
l3.scale(0.5)
l3.next_to(triangle, DOWN)
self.play(Write(l1), Write(l2), Write(l3))
self.wait(1)
self.play(FadeOut(circle), FadeOut(square), FadeOut(triangle))
self.play(FadeOut(l1), FadeOut(l2), FadeOut(l3))
3
Fade Animations
What you will learn
FadeInandFadeOutfor smooth appearance/disappearance- Directional fades with
shift:parameter FadeTransformmorphs one object into another with a fade effect- Combining fill color and opacity
// Tutorial 03: Fade Animations
// FadeIn, FadeOut, and various fade effects
scene FadeAnimations {
fn construct(self) {
let title = Text("Fade Animations", color: BLUE)
title.to_edge(UP)
self.play(Write(title))
// FadeIn - object appears gradually
let circle = Circle(radius: 1.0, color: RED)
circle.set_fill(RED, opacity: 0.5)
circle.shift(LEFT * 2)
self.play(FadeIn(circle))
self.wait(0.5)
// FadeOut - object disappears gradually
self.play(FadeOut(circle))
self.wait(0.5)
// FadeIn with shift direction
let square = Square(side_length: 1.5, color: GREEN)
square.set_fill(GREEN, opacity: 0.5)
self.play(FadeIn(square, shift: UP))
self.wait(0.5)
self.play(FadeOut(square, shift: DOWN))
self.wait(0.5)
// FadeTransform morphs one into another
let obj1 = Circle(radius: 1.0, color: BLUE)
obj1.set_fill(BLUE, opacity: 0.5)
self.play(FadeIn(obj1))
let obj2 = Square(side_length: 2.0, color: YELLOW)
obj2.set_fill(YELLOW, opacity: 0.5)
self.play(FadeTransform(obj1, obj2))
self.wait(1)
self.play(FadeOut(obj2), FadeOut(title))
}
}
from manim import *
class FadeAnimations(Scene):
def construct(self):
title = Text('Fade Animations', color=BLUE)
title.to_edge(UP)
self.play(Write(title))
circle = Circle(radius=1.0, color=RED)
circle.set_fill(RED, opacity=0.5)
circle.shift((LEFT * 2))
self.play(FadeIn(circle))
self.wait(0.5)
self.play(FadeOut(circle))
self.wait(0.5)
square = Square(side_length=1.5, color=GREEN)
square.set_fill(GREEN, opacity=0.5)
self.play(FadeIn(square, shift=UP))
self.wait(0.5)
self.play(FadeOut(square, shift=DOWN))
self.wait(0.5)
obj1 = Circle(radius=1.0, color=BLUE)
obj1.set_fill(BLUE, opacity=0.5)
self.play(FadeIn(obj1))
self.wait(0.3)
obj2 = Square(side_length=2.0, color=YELLOW)
obj2.set_fill(YELLOW, opacity=0.5)
self.play(FadeTransform(obj1, obj2))
self.wait(1)
self.play(FadeOut(obj2), FadeOut(title))
4
Text Basics
What you will learn
Text()creates text objects with optional colorWrite()animates text being written on screen.animate.set_color()smoothly transitions colorsto_edge()positions objects at screen boundaries
// Tutorial 04: Text Basics
// Create text, colored text, and positioned text
scene TextBasics {
fn construct(self) {
let hello = Text("Hello, MathViz!")
hello.scale(1.5)
self.play(Write(hello))
self.wait(0.5)
self.play(FadeOut(hello))
// Colored text
let colored = Text("Colors are fun!", color: YELLOW)
colored.scale(1.2)
self.play(Write(colored))
self.wait(0.3)
self.play(colored.animate.set_color(RED))
self.wait(0.3)
self.play(colored.animate.set_color(GREEN))
self.wait(0.3)
self.play(FadeOut(colored))
// Positioned text at all edges
let t1 = Text("Top", color: BLUE)
t1.to_edge(UP)
let t2 = Text("Bottom", color: RED)
t2.to_edge(DOWN)
let t3 = Text("Left", color: GREEN)
t3.to_edge(LEFT)
let t4 = Text("Right", color: YELLOW)
t4.to_edge(RIGHT)
let center = Text("Center", color: WHITE)
self.play(Write(center))
self.play(Write(t1), Write(t2), Write(t3), Write(t4))
self.wait(1)
self.play(FadeOut(t1), FadeOut(t2), FadeOut(t3), FadeOut(t4), FadeOut(center))
}
}
from manim import *
class TextBasics(Scene):
def construct(self):
hello = Text('Hello, MathViz!')
hello.scale(1.5)
self.play(Write(hello))
self.wait(0.5)
self.play(FadeOut(hello))
colored = Text('Colors are fun!', color=YELLOW)
colored.scale(1.2)
self.play(Write(colored))
self.wait(0.3)
self.play(colored.animate.set_color(RED))
self.wait(0.3)
self.play(colored.animate.set_color(GREEN))
self.wait(0.3)
self.play(FadeOut(colored))
t1 = Text('Top', color=BLUE)
t1.to_edge(UP)
t2 = Text('Bottom', color=RED)
t2.to_edge(DOWN)
t3 = Text('Left', color=GREEN)
t3.to_edge(LEFT)
t4 = Text('Right', color=YELLOW)
t4.to_edge(RIGHT)
center = Text('Center', color=WHITE)
self.play(Write(center))
self.play(Write(t1), Write(t2), Write(t3), Write(t4))
self.wait(1)
self.play(FadeOut(t1), FadeOut(t2), FadeOut(t3), FadeOut(t4), FadeOut(center))
5
LaTeX Mathematics
What you will learn
MathTex()renders LaTeX mathematical formulas- Standard LaTeX notation:
\\int,\\frac,^{},_{} - Scaling and coloring math expressions
- Famous equations: Einstein, Pythagoras, Euler
// Tutorial 05: LaTeX Mathematics
// Display beautiful mathematical formulas
scene LatexMath {
fn construct(self) {
let title = Text("Mathematical Formulas", color: BLUE)
title.scale(0.8)
title.to_edge(UP)
self.play(Write(title))
// Einstein's equation
let eq1 = MathTex("E = mc^2")
eq1.scale(1.5)
self.play(Write(eq1))
self.wait(1)
self.play(FadeOut(eq1))
// Pythagorean theorem
let eq2 = MathTex("a^2 + b^2 = c^2")
eq2.scale(1.5)
self.play(Write(eq2))
self.wait(1)
self.play(FadeOut(eq2))
// Gaussian integral
let eq3 = MathTex("\\int_0^\\infty e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2}")
eq3.scale(1.2)
self.play(Write(eq3))
self.wait(1)
self.play(FadeOut(eq3))
// Euler's identity
let eq4 = MathTex("e^{i\\pi} + 1 = 0")
eq4.scale(2.0)
eq4.set_color(YELLOW)
self.play(Write(eq4))
self.wait(1.5)
self.play(FadeOut(eq4), FadeOut(title))
}
}
from manim import *
class LatexMath(Scene):
def construct(self):
title = Text('Mathematical Formulas', color=BLUE)
title.scale(0.8)
title.to_edge(UP)
self.play(Write(title))
eq1 = MathTex('E = mc^2')
eq1.scale(1.5)
self.play(Write(eq1))
self.wait(1)
self.play(FadeOut(eq1))
eq2 = MathTex('a^2 + b^2 = c^2')
eq2.scale(1.5)
self.play(Write(eq2))
self.wait(1)
self.play(FadeOut(eq2))
eq3 = MathTex('\\int_0^\\infty e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2}')
eq3.scale(1.2)
self.play(Write(eq3))
self.wait(1)
self.play(FadeOut(eq3))
eq4 = MathTex('e^{i\\pi} + 1 = 0')
eq4.scale(2.0)
eq4.set_color(YELLOW)
self.play(Write(eq4))
self.wait(1.5)
self.play(FadeOut(eq4), FadeOut(title))
6
Positioning
What you will learn
next_to()places an object relative to anothershift()moves by a direction vector (e.g.LEFT * 3)to_edge()andto_corner()for screen placementbuff:controls spacing between objects
// Tutorial 06: Positioning
// next_to, shift, to_edge, to_corner
scene Positioning {
fn construct(self) {
let center_sq = Square(side_length: 1.0, color: RED)
center_sq.set_fill(RED, opacity: 0.3)
self.play(Create(center_sq))
// next_to places adjacent
let right_circ = Circle(radius: 0.4, color: BLUE)
right_circ.next_to(center_sq, RIGHT, buff: 0.3)
self.play(Create(right_circ))
let top_circ = Circle(radius: 0.4, color: GREEN)
top_circ.next_to(center_sq, UP, buff: 0.3)
self.play(Create(top_circ))
self.wait(0.5)
// shift moves by a vector
let shifted = Square(side_length: 0.6, color: YELLOW)
shifted.shift(LEFT * 3 + UP * 2)
self.play(Create(shifted))
// to_edge places at boundary
let edge_text = Text("Edge", color: PURPLE)
edge_text.scale(0.5)
edge_text.to_edge(DOWN)
self.play(Write(edge_text))
// to_corner for corners
let corner_text = Text("Corner", color: TEAL)
corner_text.scale(0.5)
corner_text.to_corner(UL)
self.play(Write(corner_text))
self.wait(1)
self.play(
FadeOut(center_sq), FadeOut(right_circ), FadeOut(top_circ),
FadeOut(shifted), FadeOut(edge_text), FadeOut(corner_text)
)
}
}
from manim import *
class Positioning(Scene):
def construct(self):
center_sq = Square(side_length=1.0, color=RED)
center_sq.set_fill(RED, opacity=0.3)
self.play(Create(center_sq))
right_circ = Circle(radius=0.4, color=BLUE)
right_circ.next_to(center_sq, RIGHT, buff=0.3)
self.play(Create(right_circ))
top_circ = Circle(radius=0.4, color=GREEN)
top_circ.next_to(center_sq, UP, buff=0.3)
self.play(Create(top_circ))
self.wait(0.5)
shifted = Square(side_length=0.6, color=YELLOW)
shifted.shift(((LEFT * 3) + (UP * 2)))
self.play(Create(shifted))
edge_text = Text('Edge', color=PURPLE)
edge_text.scale(0.5)
edge_text.to_edge(DOWN)
self.play(Write(edge_text))
corner_text = Text('Corner', color=TEAL)
corner_text.scale(0.5)
corner_text.to_corner(UL)
self.play(Write(corner_text))
self.wait(1)
self.play(FadeOut(center_sq), FadeOut(right_circ), FadeOut(top_circ),
FadeOut(shifted), FadeOut(edge_text), FadeOut(corner_text))
Intermediate
Building Skills
Styling, transforms, graphs, groups, and dynamic updates.
7
Colors & Styling
What you will learn
set_color()changes the stroke/border colorset_fill(color, opacity:)fills the interiorset_stroke(color, width:)controls the border- Animate style changes with
.animate
// Tutorial 07: Colors and Styling
// set_color, set_fill, set_stroke, opacity
scene ColorsStyling {
fn construct(self) {
let title = Text("Colors & Styling", color: BLUE)
title.scale(0.7)
title.to_edge(UP)
self.play(Write(title))
let c1 = Circle(radius: 0.8)
c1.set_color(BLUE)
c1.shift(LEFT * 3)
let c2 = Circle(radius: 0.8)
c2.set_fill(RED, opacity: 0.5)
c2.set_stroke(WHITE, width: 2)
let c3 = Circle(radius: 0.8)
c3.set_fill(GREEN, opacity: 0.7)
c3.set_stroke(YELLOW, width: 4)
c3.shift(RIGHT * 3)
self.play(Create(c1), Create(c2), Create(c3))
self.wait(0.5)
self.play(c1.animate.set_color(YELLOW))
self.play(c2.animate.set_fill(BLUE, opacity: 0.8))
self.wait(1)
self.play(FadeOut(c1), FadeOut(c2), FadeOut(c3), FadeOut(title))
}
}
from manim import *
class ColorsStyling(Scene):
def construct(self):
title = Text('Colors & Styling', color=BLUE)
title.scale(0.7)
title.to_edge(UP)
self.play(Write(title))
c1 = Circle(radius=0.8)
c1.set_color(BLUE)
c1.shift((LEFT * 3))
c2 = Circle(radius=0.8)
c2.set_fill(RED, opacity=0.5)
c2.set_stroke(WHITE, width=2)
c3 = Circle(radius=0.8)
c3.set_fill(GREEN, opacity=0.7)
c3.set_stroke(YELLOW, width=4)
c3.shift((RIGHT * 3))
self.play(Create(c1), Create(c2), Create(c3))
self.wait(0.5)
self.play(c1.animate.set_color(YELLOW))
self.play(c2.animate.set_fill(BLUE, opacity=0.8))
self.wait(1)
self.play(FadeOut(c1), FadeOut(c2), FadeOut(c3), FadeOut(title))
8
Transforms
What you will learn
Transform(a, b)morphs objectainto the shape ofbReplacementTransform(a, b)replaces the reference entirely- Chaining with
.animate.scale().shift() .animate.rotate(PI / 4)for rotations
// Tutorial 08: Transforms
// Transform, ReplacementTransform, chaining
scene Transforms {
fn construct(self) {
let title = Text("Transforms", color: BLUE)
title.scale(0.7)
title.to_edge(UP)
self.play(Write(title))
let square = Square(side_length: 2.0, color: BLUE)
square.set_fill(BLUE, opacity: 0.3)
self.play(Create(square))
let circle = Circle(radius: 1.0, color: RED)
circle.set_fill(RED, opacity: 0.3)
self.play(Transform(square, circle))
self.wait(0.5)
self.play(FadeOut(square))
// ReplacementTransform
let sq2 = Square(side_length: 1.5, color: GREEN)
sq2.set_fill(GREEN, opacity: 0.3)
self.play(Create(sq2))
let tri = Triangle(color: YELLOW)
tri.scale(1.5)
tri.set_fill(YELLOW, opacity: 0.3)
self.play(ReplacementTransform(sq2, tri))
self.wait(0.5)
// Chained animate
self.play(tri.animate.scale(0.5).shift(UP))
self.play(tri.animate.rotate(PI / 4))
self.wait(0.5)
self.play(FadeOut(tri), FadeOut(title))
}
}
from manim import *
class Transforms(Scene):
def construct(self):
title = Text('Transforms', color=BLUE)
title.scale(0.7)
title.to_edge(UP)
self.play(Write(title))
square = Square(side_length=2.0, color=BLUE)
square.set_fill(BLUE, opacity=0.3)
self.play(Create(square))
circle = Circle(radius=1.0, color=RED)
circle.set_fill(RED, opacity=0.3)
self.play(Transform(square, circle))
self.wait(0.5)
self.play(FadeOut(square))
sq2 = Square(side_length=1.5, color=GREEN)
sq2.set_fill(GREEN, opacity=0.3)
self.play(Create(sq2))
tri = Triangle(color=YELLOW)
tri.scale(1.5)
tri.set_fill(YELLOW, opacity=0.3)
self.play(ReplacementTransform(sq2, tri))
self.wait(0.5)
self.play(tri.animate.scale(0.5).shift(UP))
self.play(tri.animate.rotate((PI / 4)))
self.wait(0.5)
self.play(FadeOut(tri), FadeOut(title))
9
Axes & Graphs
What you will learn
Axes()creates a coordinate system with configurable rangesaxes.plot(|x| sin(x))uses pipe-lambda syntax for functions- Axis labels with
get_x_axis_label() - Plotting multiple functions on the same axes
// Tutorial 09: Axes and Graphs
// Coordinate axes and function plotting
scene AxesGraphs {
fn construct(self) {
let axes = Axes(
x_range: [-3, 3, 1],
y_range: [-2, 2, 1],
axis_config: {"color": BLUE}
)
let x_label = axes.get_x_axis_label("x")
let y_label = axes.get_y_axis_label("y")
self.play(Create(axes), Write(x_label), Write(y_label))
self.wait(0.5)
// Plot sine with pipe-lambda syntax
let sin_graph = axes.plot(|x| sin(x), color: YELLOW)
let sin_label = MathTex("\\sin(x)", color: YELLOW)
sin_label.scale(0.7)
sin_label.to_corner(UR)
self.play(Create(sin_graph), Write(sin_label))
self.wait(0.5)
// Plot cosine
let cos_graph = axes.plot(|x| cos(x), color: GREEN)
let cos_label = MathTex("\\cos(x)", color: GREEN)
cos_label.scale(0.7)
cos_label.next_to(sin_label, DOWN)
self.play(Create(cos_graph), Write(cos_label))
self.wait(1)
self.play(
FadeOut(axes), FadeOut(sin_graph), FadeOut(cos_graph),
FadeOut(x_label), FadeOut(y_label),
FadeOut(sin_label), FadeOut(cos_label)
)
}
}
from manim import *
class AxesGraphs(Scene):
def construct(self):
axes = Axes(x_range=[(-3), 3, 1], y_range=[(-2), 2, 1],
axis_config={'color': BLUE})
x_label = axes.get_x_axis_label('x')
y_label = axes.get_y_axis_label('y')
self.play(Create(axes), Write(x_label), Write(y_label))
self.wait(0.5)
sin_graph = axes.plot(lambda x: np.sin(x), color=YELLOW)
sin_label = MathTex('\\sin(x)', color=YELLOW)
sin_label.scale(0.7)
sin_label.to_corner(UR)
self.play(Create(sin_graph), Write(sin_label))
self.wait(0.5)
cos_graph = axes.plot(lambda x: np.cos(x), color=GREEN)
cos_label = MathTex('\\cos(x)', color=GREEN)
cos_label.scale(0.7)
cos_label.next_to(sin_label, DOWN)
self.play(Create(cos_graph), Write(cos_label))
self.wait(1)
self.play(FadeOut(axes), FadeOut(sin_graph), FadeOut(cos_graph),
FadeOut(x_label), FadeOut(y_label),
FadeOut(sin_label), FadeOut(cos_label))
10
Number Plane
What you will learn
NumberPlane()creates a full-screen coordinate grid- Plotting curves with
plane.plot() Dot()creates point markersMoveAlongPath()animates along a curve
// Tutorial 10: Number Plane
// NumberPlane and parametric curves
scene NumberPlaneDemo {
fn construct(self) {
let plane = NumberPlane(
x_range: [-4, 4, 1],
y_range: [-3, 3, 1],
background_line_style: {"stroke_opacity": 0.4}
)
self.play(Create(plane), run_time: 2)
self.wait(0.5)
// Plot a parabola
let parabola = plane.plot(|x| x * x / 3, color: YELLOW)
let label = MathTex("f(x) = \\frac{x^2}{3}", color: YELLOW)
label.scale(0.8)
label.to_corner(UR)
self.play(Create(parabola), Write(label))
self.wait(0.5)
// Animate a dot along the curve
let dot = Dot(color: RED)
dot.move_to(plane.c2p(-3, 3))
self.play(Create(dot))
self.play(MoveAlongPath(dot, parabola), run_time: 3)
self.wait(1)
self.play(FadeOut(plane), FadeOut(parabola), FadeOut(label), FadeOut(dot))
}
}
from manim import *
class NumberPlaneDemo(Scene):
def construct(self):
plane = NumberPlane(x_range=[(-4), 4, 1], y_range=[(-3), 3, 1],
background_line_style={'stroke_opacity': 0.4})
self.play(Create(plane), run_time=2)
self.wait(0.5)
parabola = plane.plot(lambda x: ((x * x) / 3), color=YELLOW)
label = MathTex('f(x) = \\frac{x^2}{3}', color=YELLOW)
label.scale(0.8)
label.to_corner(UR)
self.play(Create(parabola), Write(label))
self.wait(0.5)
dot = Dot(color=RED)
dot.move_to(plane.c2p((-3), 3))
self.play(Create(dot))
self.play(MoveAlongPath(dot, parabola), run_time=3)
self.wait(1)
self.play(FadeOut(plane), FadeOut(parabola), FadeOut(label), FadeOut(dot))
11
Groups
What you will learn
VGroup()groups multiple objects together.arrange(RIGHT, buff: 0.5)lays out objects in a row- Animating the entire group at once with
group.animate - Individual elements remain accessible within the group
// Tutorial 11: Groups
// VGroup, arrange, and batch animations
scene Groups {
fn construct(self) {
let title = Text("VGroup & Arrange", color: BLUE)
title.scale(0.7)
title.to_edge(UP)
self.play(Write(title))
let c1 = Circle(radius: 0.4, color: RED)
c1.set_fill(RED, opacity: 0.5)
let c2 = Circle(radius: 0.4, color: GREEN)
c2.set_fill(GREEN, opacity: 0.5)
let c3 = Circle(radius: 0.4, color: BLUE)
c3.set_fill(BLUE, opacity: 0.5)
let c4 = Circle(radius: 0.4, color: YELLOW)
c4.set_fill(YELLOW, opacity: 0.5)
let row = VGroup(c1, c2, c3, c4)
row.arrange(RIGHT, buff: 0.5)
self.play(Create(row))
self.play(row.animate.scale(1.5))
self.play(row.animate.shift(DOWN))
let s1 = Square(side_length: 0.6, color: PURPLE)
s1.set_fill(PURPLE, opacity: 0.5)
let s2 = Square(side_length: 0.6, color: TEAL)
s2.set_fill(TEAL, opacity: 0.5)
let s3 = Square(side_length: 0.6, color: ORANGE)
s3.set_fill(ORANGE, opacity: 0.5)
let row2 = VGroup(s1, s2, s3)
row2.arrange(RIGHT, buff: 0.5)
row2.next_to(row, UP, buff: 0.8)
self.play(Create(row2))
self.wait(1)
self.play(FadeOut(row), FadeOut(row2), FadeOut(title))
}
}
from manim import *
class Groups(Scene):
def construct(self):
title = Text('VGroup & Arrange', color=BLUE)
title.scale(0.7)
title.to_edge(UP)
self.play(Write(title))
c1 = Circle(radius=0.4, color=RED)
c1.set_fill(RED, opacity=0.5)
c2 = Circle(radius=0.4, color=GREEN)
c2.set_fill(GREEN, opacity=0.5)
c3 = Circle(radius=0.4, color=BLUE)
c3.set_fill(BLUE, opacity=0.5)
c4 = Circle(radius=0.4, color=YELLOW)
c4.set_fill(YELLOW, opacity=0.5)
row = VGroup(c1, c2, c3, c4)
row.arrange(RIGHT, buff=0.5)
self.play(Create(row))
self.play(row.animate.scale(1.5))
self.play(row.animate.shift(DOWN))
s1 = Square(side_length=0.6, color=PURPLE)
s1.set_fill(PURPLE, opacity=0.5)
s2 = Square(side_length=0.6, color=TEAL)
s2.set_fill(TEAL, opacity=0.5)
s3 = Square(side_length=0.6, color=ORANGE)
s3.set_fill(ORANGE, opacity=0.5)
row2 = VGroup(s1, s2, s3)
row2.arrange(RIGHT, buff=0.5)
row2.next_to(row, UP, buff=0.8)
self.play(Create(row2))
self.wait(1)
self.play(FadeOut(row), FadeOut(row2), FadeOut(title))
12
Updaters
What you will learn
ValueTracker()creates an animatable numeric valuealways_redraw()rebuilds an object every frame- Pipe-lambda
||creates zero-argument closures - Tracking a dot along a plotted curve dynamically
// Tutorial 12: Updaters
// always_redraw and ValueTracker
scene Updaters {
fn construct(self) {
let title = Text("Updaters", color: BLUE)
title.scale(0.7)
title.to_edge(UP)
self.play(Write(title))
// ValueTracker animates a value smoothly
let tracker = ValueTracker(0)
// always_redraw rebuilds each frame
let number = always_redraw(
|| DecimalNumber(tracker.get_value()).scale(1.5).set_color(YELLOW)
)
self.play(Create(number))
self.play(tracker.animate.set_value(10), run_time: 3)
self.play(FadeOut(number))
// Dynamic dot tracking along sine
let t = ValueTracker(-3)
let axes = Axes(x_range: [-3, 3, 1], y_range: [-2, 2, 1])
let graph = axes.plot(|x| sin(x), color: YELLOW)
self.play(Create(axes), Create(graph))
let dot = always_redraw(
|| Dot(axes.c2p(t.get_value(), sin(t.get_value())), color: RED)
)
self.play(Create(dot))
self.play(t.animate.set_value(3), run_time: 4)
self.wait(1)
self.play(FadeOut(axes), FadeOut(graph), FadeOut(dot), FadeOut(title))
}
}
from manim import *
class Updaters(Scene):
def construct(self):
title = Text('Updaters', color=BLUE)
title.scale(0.7)
title.to_edge(UP)
self.play(Write(title))
tracker = ValueTracker(0)
number = always_redraw(
lambda: DecimalNumber(tracker.get_value()).scale(1.5).set_color(YELLOW))
self.play(Create(number))
self.play(tracker.animate.set_value(10), run_time=3)
self.play(FadeOut(number))
t = ValueTracker((-3))
axes = Axes(x_range=[(-3), 3, 1], y_range=[(-2), 2, 1])
graph = axes.plot(lambda x: np.sin(x), color=YELLOW)
self.play(Create(axes), Create(graph))
dot = always_redraw(
lambda: Dot(axes.c2p(t.get_value(), np.sin(t.get_value())), color=RED))
self.play(Create(dot))
self.play(t.animate.set_value(3), run_time=4)
self.wait(1)
self.play(FadeOut(axes), FadeOut(graph), FadeOut(dot), FadeOut(title))
Advanced
Mastery
3D scenes, theorem visualization, and complex animation orchestration.
13
3D Scenes
What you will learn
ThreeDAxes()creates 3D coordinate axesSurface()constructs parametric 3D surfacesset_camera_orientation()for viewing anglesbegin_ambient_camera_rotation()for orbiting views
// Tutorial 13: 3D Scenes
// ThreeDScene, 3D objects, camera rotation
scene ThreeDDemo {
fn construct(self) {
let axes = ThreeDAxes()
self.play(Create(axes))
// Create a sphere surface
let sphere = Surface(
|u, v| axes.c2p(
cos(u) * cos(v),
cos(u) * sin(v),
sin(u)
),
u_range: [-PI / 2, PI / 2],
v_range: [0, TAU],
resolution: (16, 32)
)
sphere.set_color(BLUE)
sphere.set_opacity(0.5)
self.set_camera_orientation(phi: 70 * DEGREES, theta: -45 * DEGREES)
self.play(Create(sphere), run_time: 2)
// Orbit the camera
self.begin_ambient_camera_rotation(rate: 0.3)
self.wait(4)
self.stop_ambient_camera_rotation()
self.wait(1)
self.play(FadeOut(axes), FadeOut(sphere))
}
}
from manim import *
class ThreeDDemo(ThreeDScene):
def construct(self):
axes = ThreeDAxes()
self.play(Create(axes))
sphere = Surface(
lambda u, v: axes.c2p(
np.cos(u) * np.cos(v),
np.cos(u) * np.sin(v),
np.sin(u)),
u_range=[(-PI / 2), (PI / 2)],
v_range=[0, TAU],
resolution=(16, 32))
sphere.set_color(BLUE)
sphere.set_opacity(0.5)
self.set_camera_orientation(phi=(70 * DEGREES), theta=((-45) * DEGREES))
self.play(Create(sphere), run_time=2)
self.begin_ambient_camera_rotation(rate=0.3)
self.wait(4)
self.stop_ambient_camera_rotation()
self.wait(1)
self.play(FadeOut(axes), FadeOut(sphere))
14
Complex Math Visualization
What you will learn
- Visualizing the Fundamental Theorem of Calculus
axes.get_area()shades the region under a curve- Combining formulas, graphs, and annotations
- Labeling specific points on axes with
axes.c2p()
// Tutorial 14: Complex Math Visualization
// Theorem visualization with formulas and graphs
scene ComplexMath {
fn construct(self) {
let title = Text("The Fundamental Theorem of Calculus", color: BLUE)
title.scale(0.6)
title.to_edge(UP)
self.play(Write(title))
let theorem = MathTex("\\int_a^b f(x)\\,dx = F(b) - F(a)")
theorem.scale(1.3)
self.play(Write(theorem))
self.wait(1)
self.play(theorem.animate.shift(UP * 0.5).scale(0.7))
// Visualize with a shaded area
let axes = Axes(x_range: [0, 5, 1], y_range: [0, 4, 1])
axes.scale(0.6)
axes.shift(DOWN * 1.5)
let graph = axes.plot(|x| 0.1 * x * x + 0.5, color: YELLOW)
let area = axes.get_area(graph, x_range: [1, 4], color: BLUE, opacity: 0.3)
self.play(Create(axes))
self.play(Create(graph))
self.play(FadeIn(area))
let a_label = MathTex("a", color: RED)
a_label.scale(0.6)
a_label.next_to(axes.c2p(1, 0), DOWN)
let b_label = MathTex("b", color: RED)
b_label.scale(0.6)
b_label.next_to(axes.c2p(4, 0), DOWN)
self.play(Write(a_label), Write(b_label))
self.wait(1.5)
self.play(
FadeOut(title), FadeOut(theorem), FadeOut(axes),
FadeOut(graph), FadeOut(area), FadeOut(a_label), FadeOut(b_label)
)
}
}
from manim import *
class ComplexMath(Scene):
def construct(self):
title = Text('The Fundamental Theorem of Calculus', color=BLUE)
title.scale(0.6)
title.to_edge(UP)
self.play(Write(title))
theorem = MathTex('\\int_a^b f(x)\\,dx = F(b) - F(a)')
theorem.scale(1.3)
self.play(Write(theorem))
self.wait(1)
self.play(theorem.animate.shift((UP * 0.5)).scale(0.7))
axes = Axes(x_range=[0, 5, 1], y_range=[0, 4, 1])
axes.scale(0.6)
axes.shift((DOWN * 1.5))
graph = axes.plot(lambda x: ((0.1 * x * x) + 0.5), color=YELLOW)
area = axes.get_area(graph, x_range=[1, 4], color=BLUE, opacity=0.3)
self.play(Create(axes))
self.play(Create(graph))
self.play(FadeIn(area))
a_label = MathTex('a', color=RED)
a_label.scale(0.6)
a_label.next_to(axes.c2p(1, 0), DOWN)
b_label = MathTex('b', color=RED)
b_label.scale(0.6)
b_label.next_to(axes.c2p(4, 0), DOWN)
self.play(Write(a_label), Write(b_label))
self.wait(1.5)
self.play(FadeOut(title), FadeOut(theorem), FadeOut(axes),
FadeOut(graph), FadeOut(area), FadeOut(a_label), FadeOut(b_label))
15
Advanced Animation Orchestration
What you will learn
LaggedStart()creates cascading staggered animationsAnimationGroup()runs multiple animations simultaneouslySuccession()chains animations sequentiallylag_ratio:controls the stagger timing
// Tutorial 15: Advanced Animations
// AnimationGroup, LaggedStart, Succession
scene AdvancedAnimation {
fn construct(self) {
let title = Text("Advanced Animations", color: BLUE)
title.scale(0.7)
title.to_edge(UP)
self.play(Write(title))
// Build 6 colored circles
let c0 = Circle(radius: 0.3, color: RED)
c0.set_fill(RED, opacity: 0.5)
let c1 = Circle(radius: 0.3, color: ORANGE)
c1.set_fill(ORANGE, opacity: 0.5)
let c2 = Circle(radius: 0.3, color: YELLOW)
c2.set_fill(YELLOW, opacity: 0.5)
let c3 = Circle(radius: 0.3, color: GREEN)
c3.set_fill(GREEN, opacity: 0.5)
let c4 = Circle(radius: 0.3, color: BLUE)
c4.set_fill(BLUE, opacity: 0.5)
let c5 = Circle(radius: 0.3, color: PURPLE)
c5.set_fill(PURPLE, opacity: 0.5)
let group = VGroup(c0, c1, c2, c3, c4, c5)
group.arrange(RIGHT, buff: 0.4)
// LaggedStart - cascading creation
self.play(LaggedStart(
Create(c0), Create(c1), Create(c2),
Create(c3), Create(c4), Create(c5),
lag_ratio: 0.2
))
// AnimationGroup - all at once
self.play(AnimationGroup(
c0.animate.shift(UP),
c1.animate.shift(UP * 0.5),
c2.animate.shift(DOWN * 0.5),
c3.animate.shift(DOWN),
c4.animate.shift(UP * 0.5),
c5.animate.shift(UP)
))
// Succession - one after another
self.play(Succession(
c0.animate.set_color(WHITE),
c1.animate.set_color(WHITE),
c2.animate.set_color(WHITE),
c3.animate.set_color(WHITE),
c4.animate.set_color(WHITE),
c5.animate.set_color(WHITE)
))
self.wait(1)
self.play(FadeOut(group), FadeOut(title))
}
}
from manim import *
class AdvancedAnimation(Scene):
def construct(self):
title = Text('Advanced Animations', color=BLUE)
title.scale(0.7)
title.to_edge(UP)
self.play(Write(title))
c0 = Circle(radius=0.3, color=RED)
c0.set_fill(RED, opacity=0.5)
c1 = Circle(radius=0.3, color=ORANGE)
c1.set_fill(ORANGE, opacity=0.5)
c2 = Circle(radius=0.3, color=YELLOW)
c2.set_fill(YELLOW, opacity=0.5)
c3 = Circle(radius=0.3, color=GREEN)
c3.set_fill(GREEN, opacity=0.5)
c4 = Circle(radius=0.3, color=BLUE)
c4.set_fill(BLUE, opacity=0.5)
c5 = Circle(radius=0.3, color=PURPLE)
c5.set_fill(PURPLE, opacity=0.5)
group = VGroup(c0, c1, c2, c3, c4, c5)
group.arrange(RIGHT, buff=0.4)
self.play(LaggedStart(Create(c0), Create(c1), Create(c2),
Create(c3), Create(c4), Create(c5), lag_ratio=0.2))
self.play(AnimationGroup(c0.animate.shift(UP),
c1.animate.shift((UP * 0.5)), c2.animate.shift((DOWN * 0.5)),
c3.animate.shift(DOWN), c4.animate.shift((UP * 0.5)),
c5.animate.shift(UP)))
self.play(Succession(c0.animate.set_color(WHITE),
c1.animate.set_color(WHITE), c2.animate.set_color(WHITE),
c3.animate.set_color(WHITE), c4.animate.set_color(WHITE),
c5.animate.set_color(WHITE)))
self.wait(1)
self.play(FadeOut(group), FadeOut(title))
Congratulations!
You have completed all 15 MathViz tutorials. You now know how to:
- Create and animate shapes, text, and LaTeX formulas
- Position, style, and transform objects
- Plot mathematical functions on axes and number planes
- Use groups, updaters, and value trackers for dynamic scenes
- Build 3D scenes with camera control
- Orchestrate complex animations with LaggedStart, AnimationGroup, and Succession