Placing Things

You rarely need coordinates: say where things go, and Pymations works out the numbers.

Every change below happens at once. Put .animate in front to play it as a movement: play(label.animate.next_to(dot, UP)).

Next to something

from pymations import *

circle = Circle(color=BLUE)
above = Text("above").next_to(circle, UP)
right = Text("right").next_to(circle, RIGHT, buff=0.5)

play(Create(circle), Write(above), Write(right))

a.next_to(b, direction) puts a beside b, touching edge to edge, with a small gap (buff, 0.25 unless you give one). b can be a point, such as axes.c2p(1, 2). Diagonals (UR, DL...) put it at a corner.

aligned_edge=LEFT lines up the left edges as well: b.next_to(a, DOWN, aligned_edge=LEFT) makes a neat list.

In rows and grids

from pymations import *

row = VGroup(*[Square(side_length=1) for _ in range(5)]).arrange(RIGHT, buff=0.3)
grid = VGroup(*[Dot() for _ in range(12)]).arrange_in_grid(rows=3, buff=0.5).next_to(row, DOWN, buff=1)

play(Create(row), FadeIn(grid))
  • group.arrange(RIGHT) puts the members in a row, left to right; arrange(DOWN) in a column. The group stays centred where it was.
  • group.arrange_in_grid(rows=3) (or cols=) fills a grid, row by row.

At the edges

ChangeWhere it goes
m.to_edge(UP)Against the top of the picture (also DOWN, LEFT, RIGHT)
m.to_corner(UL)Into a corner (UL, UR, DL, DR)
m.center()The middle of the picture

They leave a margin of half a unit; buff= changes it.

Moving

ChangeWhat it does
m.shift(RIGHT * 2)Moves by an amount
m.move_to([1, 2, 0])Moves its middle to a point, or onto another object: m.move_to(other)
m.align_to(other, LEFT)Lines up one edge with other's, moving only that way
m.set_x(3), m.set_y(-1)Sets one coordinate of its middle

Size and turning

ChangeWhat it does
m.scale(2)Twice as big (about its middle). Line widths stay the same
m.scale_to_fit_width(4), m.scale_to_fit_height(2)Scales until it is that wide or tall
m.set(width=4)The same as scale_to_fit_width(4)
m.match_width(other)As wide as other
m.stretch(2, 0)Stretches along x (0) or y (1) only
m.rotate(PI / 4)Turns it (an eighth of a turn) about its middle
m.flip()Mirrors it left to right

In front and behind

Things added later are drawn on top. m.set_z_index(1) keeps m above everything with a lower number, whatever order they came in.

Where things are

m.get_center(), m.get_top(), m.get_bottom(), m.get_left(), m.get_right(), m.get_corner(UR), and for a line get_start() and get_end(), are points you can use straight away, and do sums with:

from pymations import *

box = Square()
dot = Dot(box.get_corner(UR) + UP * 0.5, color=YELLOW)
arrow = Arrow(dot.get_center(), box.get_top())

play(Create(box), FadeIn(dot), GrowArrow(arrow))

Reading a position back

Positions are worked out in the preview, so Python does not have their numbers until it asks. Most of the time you never need them. If you do (to print one, or to use it in an if), put await in front:

from pymations import *

box = Square().shift(RIGHT * 2)
x, y, z = await box.get_center()
print("The box is at", x, y)

In a scene, write async def construct(self): so that await can be used inside it. Widths and heights read back the same way: w = await box.width.