Shapes

Everything you can show is an object: make it, then play an animation that brings it in (or add it to show it at once).

The picture's units

  • The picture is 8 units tall and about 14.2 wide (16:9), with (0, 0) in the middle.
  • x goes right, y goes up. A point is written [x, y, 0] (the last number is depth, and is always 0 in 2D).
  • LEFT, RIGHT, UP and DOWN are one unit each way; UL, UR, DL and DR are the diagonals; ORIGIN is the middle. Add and multiply them: UP * 2 + LEFT.

Shapes

ShapeMade withStarts as
CircleCircle(radius=1)red outline
EllipseEllipse(width=2, height=1)red outline
DotDot(point=[1, 2, 0])small solid white dot
SquareSquare(side_length=2)white outline
RectangleRectangle(width=4, height=2)white outline
Rounded rectangleRoundedRectangle(corner_radius=0.5, width=4, height=2)white outline
TriangleTriangle()blue outline, point up
Regular polygonRegularPolygon(n=6)blue outline
Any polygonPolygon([0, 0, 0], [2, 0, 0], [0, 1, 0])blue outline through the corners given
StarStar(n=5, outer_radius=1)blue outline
RingAnnulus(inner_radius=1, outer_radius=2)solid white ring
ArcArc(radius=1, start_angle=0, angle=PI / 2)a quarter circle

Every shape takes color, fill_color, fill_opacity, stroke_width and stroke_color:

from pymations import *

shapes = VGroup(
    Circle(color=BLUE, fill_opacity=0.6),
    Square(color=GREEN, fill_opacity=0.6),
    Triangle(color=YELLOW, fill_opacity=0.6),
    Star(color=ORANGE, fill_opacity=0.6),
).arrange(RIGHT, buff=0.6)

play(LaggedStart(*[DrawBorderThenFill(s) for s in shapes], lag_ratio=0.3))
wait()

Angles are in radians: PI is half a turn, TAU a whole turn, and 45 * DEGREES is 45 degrees.

Lines and arrows

LineMade with
LineLine([-2, 0, 0], [2, 0, 0])
Dashed lineDashedLine(LEFT * 2, RIGHT * 2)
ArrowArrow(LEFT * 2, RIGHT * 2)
Two-headed arrowDoubleArrow(LEFT * 2, RIGHT * 2)
Arrow from the middleVector([1, 2, 0])

The ends can be shapes as well as points: Line(circle.get_center(), square.get_center()). buff=0.2 leaves a gap at each end. An arrow already has a small gap (0.25), so it stops short of what it points at; give buff=0 to make it touch.

GrowArrow(arrow) grows an arrow from its tail.

Marking things

from pymations import *

equation = MathTex("x^2 + 2x + 1", font_size=72)
box = SurroundingRectangle(equation, buff=0.2)
brace = Brace(equation, DOWN)
label = brace.get_tex("(x + 1)^2")

play(Write(equation))
play(Create(box))
play(GrowFromCenter(brace), Write(label))
wait()
ObjectWhat it is
SurroundingRectangle(m, buff=0.1)A yellow box round m (or round several: SurroundingRectangle(VGroup(a, b)))
BackgroundRectangle(m)A dark panel behind m, so text stays readable over a busy picture
Brace(m, DOWN)A curly brace along one side of m
brace.get_tex("x"), brace.get_text("width")A label at the brace's tip
BraceLabel(m, "x")A brace and its maths label in one

Groups

VGroup(a, b, c) holds objects together. Anything you do to the group happens to all of them: move it, colour it, fade it, arrange it. group[0] is the first member, and for shape in group: goes through them. group.add(d) puts another in.

Images

ImageMobject("photo.png") shows a picture, and SVGMobject("logo.svg") a drawing, as objects you can move, scale, fade and animate like any shape. The file is next to your .py file; a web address works too.

from pymations import *

logo = SVGMobject("logo.svg", height=2)
photo = ImageMobject("product.png").scale(0.5).next_to(logo, RIGHT, buff=1)

play(DrawBorderThenFill(logo))
play(FadeIn(photo, shift=UP))

Preparing a picture

A picture can be prepared on the way in: cut out the background, make it smaller, or trace it into outlines. Say so when you make it; this works anywhere, including an ordinary def construct(self):

from pymations import *

shoe = ImageMobject("shoe.jpg", remove_background=True, resize=800, corner_radius=0.2, shadow=True)
logo = SVGMobject("logo.png", trace={"colors": 5, "detail": "medium"}).next_to(shoe, RIGHT)

play(FadeIn(shoe, shift=UP))
play(DrawBorderThenFill(logo))
OptionWhat it does
remove_background=TrueCuts out the main subject (a product, a person). Needs an Apple device: the Mac app, iPhone or iPad, or a Circuit on a Mac
resize=800Makes the picture 800 pixels wide, so a large photo loads quickly; {"width": 800, "height": 600} gives both
ops=[("crop", {"x": 0, "y": 0, "width": 600, "height": 400}), ("flip",)]Runs any picture steps, in order
trace=True (on SVGMobject)Turns the picture into flat-colour shapes, one part per shape, that Create, Write and DrawBorderThenFill can draw. trace={"colors": 5, "detail": "medium"} sets how many colours and how much detail
corner_radius, border_color, border_width, shadow, cropStyle the picture on screen

The background is removed first, then the ops run, then the picture is resized. The steps run once and are remembered, so running the file again, or recording it, is quick.

Step by step, with await. To keep each stage, or to use a picture in Pyctures drawing too, load it with load_image and run each step:

from pymations import *

img = load_image("shoe.jpg")
cut = await img.remove_background()
small = await cut.resize(width=800)

play(FadeIn(ImageMobject(small)))

Each step gives a new picture and keeps the original. In a scene, write async def construct(self): so that await can be used inside it.

Some steps run on every device (resize, crop, rotate, trace…); some need an Apple device (remove_background, enhance…) or the iPhone and iPad app. The list of every method gives each one's options, defaults and devices.

Copies

shape.copy() makes a second, independent shape just like the first. Use it to keep the original while a copy moves away.