Mobject Basics#

After reading this chapter, you will be able to build up Mobjects on scenes, no animations included yet. There will be lots of minimal examples and only very brief explanations.

[1]:
from manim import *
config.media_embed = True
Manim Community v0.17.3

[2]:
#ignore this cell, only for setup
param = "-v WARNING -r 500,100 -s  --disable_caching Example"
parambigger = "-v WARNING -r 500,120 -s  --disable_caching Example"

Positioning#

First we want to position mobjects. There are tons of options, and not everything will be covered here.

set positions#

Some important methods to set positions are:
shift move_to align_to , next_to ,to_corner , to_edge , arrange , arrange_in_grid
[3]:
dORIGIN= Dot(color= BLUE,radius=0.5)
[4]:
%%manim $param
class Example(Scene):
    def construct(self):
        d= Dot(color= YELLOW, radius=0.5)
        d.shift(2*RIGHT)
        self.add(dORIGIN, d)
_images/ch3_5_0.png
[5]:
%%manim $param
class Example(Scene):
    def construct(self):
        d= Dot(color= YELLOW, radius=0.5)
        d.shift(3*RIGHT+0.8*UP)
        self.add(dORIGIN, d)
_images/ch3_6_0.png
[6]:
%%manim $param
class Example(Scene):
    def construct(self):
        d= Dot(color= ORANGE, radius=0.5)
        d.next_to(dORIGIN, LEFT)
        self.add(dORIGIN, d)
_images/ch3_7_0.png
[7]:
%%manim $param
class Example(Scene):
    def construct(self):
        d= Dot(color= ORANGE, radius=0.5)
        d.next_to(dORIGIN, LEFT, buff=0)
        self.add(dORIGIN, d)
_images/ch3_8_0.png
[8]:
%%manim $param
class Example(Scene):
    def construct(self):
        d= Dot(color= ORANGE, radius=0.5)
        d.next_to(dORIGIN, LEFT, buff=4)
        self.add(dORIGIN, d)
_images/ch3_9_0.png
[9]:
%%manim $param
class Example(Scene):
    def construct(self):
        d= Dot(color= ORANGE, radius=0.5)
        d.next_to(dORIGIN, UL,buff=-0.5) # UL is UPLEFT
        self.add(dORIGIN, d)
_images/ch3_10_0.png
[10]:
%%manim $param
class Example(Scene):
    def construct(self):
        d= Dot(color= ORANGE, radius=0.5)
        d.to_edge(LEFT)
        self.add(dORIGIN, d)
_images/ch3_11_0.png
[11]:
%%manim $param
class Example(Scene):
    def construct(self):
        s= Star(stroke_width=10)
        d=Dot(color= ORANGE, radius=0.5)
        d.align_to(s,DOWN)
        self.add(s,d)
_images/ch3_12_0.png
[12]:
%%manim $param
class Example(Scene):
    def construct(self):
        s= Star(stroke_width=10)
        d=Dot(color= ORANGE, radius=0.5)
        d.next_to(s,RIGHT, aligned_edge=UP) #next to and align combined
        self.add(s,d)

_images/ch3_13_0.png
[13]:
%%manim $param
class Example(Scene):
    def construct(self):
        for i in range(0,10):
            self.add(Dot(color= ORANGE, radius=0.5))
        VGroup(*self.mobjects).arrange()
_images/ch3_14_0.png
[14]:
%%manim $param
class Example(Scene):
    def construct(self):
        for i in range(0,24):
            self.add(Dot(color= ORANGE, radius=0.2))
        VGroup(*self.mobjects).arrange_in_grid(cols=6)
_images/ch3_15_0.png

get positions#

The most important methods to get positions:
get_center , get_top , get_right , get_start
[15]:
s= Star(stroke_width=10)
d=Dot(color= YELLOW, radius=0.2)
[16]:
%%manim $param
class Example(Scene):
    def construct(self):
        pos= s.get_center()
        self.add(s, d.move_to(pos))
_images/ch3_18_0.png
[17]:
%%manim $param
class Example(Scene):
    def construct(self):
        pos= s.get_center_of_mass()
        self.add(s, d.move_to(pos))
_images/ch3_19_0.png
[18]:
%%manim $param
class Example(Scene):
    def construct(self):
        pos= s.get_top()
        self.add(s, d.move_to(pos))
_images/ch3_20_0.png
[19]:
%%manim $param
class Example(Scene):
    def construct(self):
        pos= s.get_right()
        self.add(s, d.move_to(pos))
_images/ch3_21_0.png
[20]:
%%manim $param
class Example(Scene):
    def construct(self):
        pos= s.get_bottom()
        self.add(s, d.move_to(pos))
_images/ch3_22_0.png
[21]:
%%manim $param
class Example(Scene):
    def construct(self):
        pos= s.get_left()
        self.add(s, d.move_to(pos))
_images/ch3_23_0.png
[22]:
%%manim $param
class Example(Scene):
    def construct(self):
        pos= s.get_corner(UL)
        self.add(s, d.move_to(pos))
_images/ch3_24_0.png
[23]:
%%manim $param
class Example(Scene):
    def construct(self):
        pos= s.get_corner(DR)
        self.add(s, d.move_to(pos))
_images/ch3_25_0.png
[24]:
arc= Arc(radius=1.0, start_angle=-PI/16, angle=PI, stroke_width=10)
[25]:
%%manim $param
class Example(Scene):
    def construct(self):
        pos= arc.get_start()
        self.add(arc, d.move_to(pos))
_images/ch3_27_0.png
[26]:
%%manim $param
class Example(Scene):
    def construct(self):
        pos= arc.get_end()
        self.add(arc, d.move_to(pos))
_images/ch3_28_0.png
[27]:
%%manim $param
class Example(Scene):
    def construct(self):
        pos= arc.get_midpoint()
        self.add(arc, d.move_to(pos))
_images/ch3_29_0.png
[28]:
%%manim $param
class Example(Scene):
    def construct(self):
        pos= arc.point_from_proportion(0.2)
        self.add(arc, d.move_to(pos))
_images/ch3_30_0.png
[29]:
%%manim $param
class Example(Scene):
    def construct(self):
        pos= arc.get_center()
        self.add(arc, d.move_to(pos))
_images/ch3_31_0.png
[30]:
%%manim $param
class Example(Scene):
    def construct(self):
        pos= arc.get_center_of_mass()
        self.add(arc, d.move_to(pos))
_images/ch3_32_0.png
[31]:
%%manim $param
class Example(Scene):
    def construct(self):
        pos= arc.get_arc_center()
        self.add(arc, d.move_to(pos))
_images/ch3_33_0.png
[32]:
%%manim $param
class Example(Scene): #Example for `get_x` , `get_y`, `set_x` and `set_y`
    def construct(self):
        d = Dot(point=[3,1,0],radius=0.2,color= BLUE)
        triangle= Triangle(color=YELLOW, stroke_width=10).scale(0.5)
        x_pos=d.get_x()
        print(x_pos)
        triangle.set_x(x_pos)
        self.add(d, triangle)
3.0
_images/ch3_34_1.png
[33]:
%%manim $param
class Example(Scene): #Example for `get_x` , `get_y`, `set_x` and `set_y`
    def construct(self):
        d = Dot(point=[3,1,0],radius=0.2,color= BLUE)
        triangle= Triangle(color=YELLOW, stroke_width=10).scale(0.5)
        y_pos=d.get_y()
        print(y_pos)
        triangle.set_y(y_pos)
        self.add(d, triangle)
1.0
_images/ch3_35_1.png

Scaling and Stretching#

[34]:
%%manim $param
class Example(Scene):
    def construct(self):
        d= Dot(color= YELLOW)
        d.scale(10)
        self.add(d)
_images/ch3_37_0.png
[35]:
%%manim $param
class Example(Scene):
    def construct(self):
        d= Dot(color= YELLOW)
        d.scale(10)
        d.stretch(4, dim = 0) # dim = 0 means vertical
        self.add(d)
_images/ch3_38_0.png
[36]:
%%manim $parambigger
class Example(Scene):
    def construct(self):
        d= Dot(color= YELLOW)
        d.scale(10)
        d.stretch(2, dim = 1) # dim = 1 means horizontal
        self.add(d)
_images/ch3_39_0.png
[37]:
%%manim $param
class Example(Scene):
    def construct(self):
        d= Dot(color= YELLOW)
        d.scale(10)
        d.apply_matrix([[0.5, 0.5, 0], # shear matrix
                        [ 0 ,  1 , 0],
                        [ 0 ,  0 , 1]])
        self.add(d)
_images/ch3_40_0.png

Rotating#

[38]:
%%manim $parambigger
class Example(Scene):
    def construct(self):
        m= ManimBanner().scale(0.5)
        m.rotate(PI/8)
        self.add(m)
_images/ch3_42_0.png
[39]:
%%manim $parambigger
class Example(Scene):
    def construct(self):
        m= ManimBanner().scale(0.5)
        m.rotate(-20*DEGREES)
        self.add(m)
_images/ch3_43_0.png
[40]:
%%manim $parambigger
class Example(Scene):
    def construct(self):
        m= ManimBanner().scale(0.5)
        self.add(m.copy())
        m.rotate(about_point=2*LEFT, angle=180*DEGREES)
        self.add(m, Dot(2*LEFT,radius=0.1))
_images/ch3_44_0.png
[41]:
%%manim $parambigger
class Example(Scene):
    def construct(self):
        m= ManimBanner().scale(0.5)
        m.rotate(axis=UP,angle=60*DEGREES)
        self.add(m)
_images/ch3_45_0.png

Note

Python is very fertile tool, there multiple ways to accomplish a certain task, but some options are not “best practice”. For the methods in the next chapters, I want to show the best practice (labeled with BEST and the green check with the star), other possible options (labeled with YES and the green check), and options that do not work (labeled with NO and the red cross)

[42]:
# ignore this cell, only for setup
YES = SVGMobject("good.svg").to_edge(LEFT, buff=1)
BEST = YES.copy()
BEST.add(Star(color= YELLOW, fill_opacity=1).scale(0.5).move_to(BEST).shift(0.5*DOWN+0.5*RIGHT))
NO  = Cross(Square(), stroke_color = RED_D, stroke_width = 38).scale(0.9).move_to(YES)

Colors and Opacity#

  • Color parameters for Mobjects are stroke_color, fill_color and color. The parameter color automatically sets both stroke_color and fill_color.
    The recommended ways to set colors are via c = Circle(fill_color= BLUE, fill_opacity= 1 ) , c.set_fill(color=RED) or c.set_style(fill_color=GREEN)
    Not possible are c.fill_color=YELLOW , c.set(fill_color=YELLOW) and c.set_fill_color(YELLOW)
  • Opacity parameters for Mobjects are fill_opacity and stroke_opacity (there is not opacity here).
    The recommended ways to set opacity are via c = Circle(fill_color= BLUE, fill_opacity= 0.5 ) , c.set_fill(color=RED) or c.set_style(fill_color=GREEN)
    Analog to colors, c.fill_opacity=1, c.set(fill_opacity=1) and c.set_fill_opacity(1) are not possible. (to keep things short, these examples are not shown).

Colors#

[43]:
%%manim $param
class Example(Scene):
    def construct(self):
        c = Square(fill_color= BLUE, fill_opacity= 1 )
        self.add(BEST,c)
_images/ch3_51_0.png
[44]:
%%manim $param
class Example(Scene):
    def construct(self):
        c = Square(fill_color= BLUE, fill_opacity= 1)
        c.set_fill(color=RED)
        self.add(BEST,c)
_images/ch3_52_0.png
[45]:
%%manim $param
class Example(Scene):
    def construct(self):
        c = Square(fill_color= BLUE, fill_opacity= 1)
        c.set_style(fill_color=GREEN)
        self.add(BEST,c)
_images/ch3_53_0.png
[46]:
%%manim $param
class Example(Scene):
    def construct(self):
        c = Square(fill_opacity= 1)
        c.fill_color=YELLOW
        self.add(NO,c)
_images/ch3_54_0.png
[47]:
%%manim $param
class Example(Scene):
    def construct(self):
        c = Square(fill_opacity= 1)
        c.set(fill_color=YELLOW)
        self.add(NO,c)
_images/ch3_55_0.png
[48]:
%%manim $param
class Example(Scene):
    def construct(self):
        c = Square(fill_opacity= 1)
        c.set_fill_color(YELLOW)
        self.add(NO,c)
<string>:4: DeprecationWarning: This method is not guaranteed to stay around. Please prefer setting the attribute normally or with Mobject.set().
_images/ch3_56_1.png
[49]:
%%manim $param
class Example(Scene):
    def construct(self):
        self.camera.background_color = PURPLE
        self.add(BEST)
_images/ch3_57_0.png

Opacitiy#

[50]:
%%manim $param
class Example(Scene):
    def construct(self):
        c = Ellipse(color= YELLOW, fill_opacity=0.3).scale(2)
        self.add(BEST,c)
_images/ch3_59_0.png
[51]:
%%manim  $param
class Example(Scene):
    def construct(self):
        c = Ellipse(color= YELLOW).scale(2)
        c.set_fill(opacity=0.5) # be careful: here, it must be `opacity` and not `fill_opacity` !
        self.add(BEST,c)
_images/ch3_60_0.png
[52]:
%%manim  $param
class Example(Scene):
    def construct(self):
        c = Ellipse(color= YELLOW).scale(2)
        c.set_style(fill_opacity=0.7) # and here, it must be `fill_opacity` and not `opacity` !
        self.add(BEST,c)
_images/ch3_61_0.png

Stroke width#

Strokes can be set in multiple ways:
The recommended ways are via Circle(stroke_width=30) , c.set_stroke(width = 30) or c.set_style(stroke_width= 30)
Also possible, but not the best solution is c.stroke_width = 30 and c.set(stroke_width = 30)
Also possible, but not recommended because deprecated is c.set_stroke_width(30)
[53]:
%%manim $param
class Example(Scene):
    def construct(self):
        c = Circle(stroke_width=30)
        self.add(BEST,c)
_images/ch3_63_0.png
[54]:
%%manim $param
class Example(Scene):
    def construct(self):
        c = Circle()
        c.set_stroke(width = 30)
        self.add(BEST,c)
_images/ch3_64_0.png
[55]:
%%manim $param
class Example(Scene):
    def construct(self):
        c = Circle()
        c.set_style(stroke_width= 30)
        self.add(BEST,c)
_images/ch3_65_0.png
[56]:
%%manim $param
class Example(Scene):
    def construct(self):
        c = Circle()
        c.stroke_width = 30
        self.add(YES,c)
_images/ch3_66_0.png
[57]:
%%manim $param
class Example(Scene):
    def construct(self):
        c = Circle()
        c.set(stroke_width = 30)
        self.add(YES,c)
_images/ch3_67_0.png
[58]:
%%manim $param
class Example(Scene):
    def construct(self):
        c = Circle()
        c.set_stroke_width(30)
        self.add(NO,c)
<string>:4: DeprecationWarning: This method is not guaranteed to stay around. Please prefer setting the attribute normally or with Mobject.set().
_images/ch3_68_1.png

Layers#

There are two main ways to change the layers of Mobjects:

  1. Reordering the list of submobjects that where added

  2. Using the z_index

submobjects#

A scene stores displayed mobjects in a list. They are displayed in the order that they are added to the scene with the syntax self.add(circleLeft,circleRight) First, we have a look on positioning mobjects with self.add and the methods self.bring_to_back and self.bring_to_front. In most cases, this is completely enough. Later, we will come to the z_index, that is seen by manim by one priority higher: Even when a mobject is added first to the mobject list, it will be displayed on top of the others, if it has a higher z_index. An example about this will be seen later.

[59]:
circleLeft = Circle(color=BLUE, fill_opacity=1)
circleRight = Circle(color=ORANGE,fill_opacity=1).shift(RIGHT)
line = Line(2*LEFT,3*RIGHT,color=YELLOW, stroke_width=20)
[60]:
%%manim  $parambigger
class Example(Scene):
    def construct(self):
        self.add(circleLeft,circleRight)
        self.add(BEST)
_images/ch3_71_0.png
[61]:
%%manim  $parambigger
class Example(Scene):
    def construct(self):
        self.add(circleRight,circleLeft)
        self.add(BEST)
_images/ch3_72_0.png
[62]:
%%manim  $parambigger
class Example(Scene):
    def construct(self):
        self.add(circleLeft,circleRight, line)
        self.add(BEST)
_images/ch3_73_0.png
[63]:
%%manim  $parambigger
class Example(Scene):
    def construct(self):
        self.add(circleLeft,circleRight, line)
        print(self.mobjects)
        self.bring_to_back(line)
        print(self.mobjects)
        self.add(BEST)
[Circle, Circle, Line]
[Line, Circle, Circle]
_images/ch3_74_1.png
[64]:
%%manim  $parambigger
class Example(Scene):
    def construct(self):
        self.add(circleLeft,circleRight, line)
        print(self.mobjects)
        self.bring_to_front(circleLeft)
        print(self.mobjects)
        self.add(BEST)
[Circle, Circle, Line]
[Circle, Line, Circle]
_images/ch3_75_1.png

z_index#

The default z_index is 0. Now we will see what happens, when we increase the value of the z_index.
The z_index can be changed by triangle = Triangle(z_index=1),triangle.z_index=1 , triangle.set(z_index=1) and triangle.set_z_index(1)
It can not be changed using triangle.set_style(z_index=1)
[65]:
#initilizing line,circle,square and triangle
BUFF= 0.5*DOWN
line = Line(3*LEFT,3*RIGHT,color=YELLOW, stroke_width=20)
circle = Circle(color=GREEN_D, fill_opacity=1).shift(LEFT+BUFF)
square = Square(color=BLUE_D, fill_opacity=1).shift(UP+BUFF)
triangle = Triangle(color=RED_D, fill_opacity=1).shift(RIGHT+BUFF)
[66]:
%%manim  $parambigger
class Example(Scene):
    def construct(self):
        self.add(line,triangle, square, circle)  # order matters
        print(self.mobjects)
        print(f"{triangle.z_index=} , {square.z_index=} , {circle.z_index=} , {line.z_index=}")
        self.add(BEST)
[Line, Triangle, Square, Circle]
triangle.z_index=0 , square.z_index=0 , circle.z_index=0 , line.z_index=0
_images/ch3_78_1.png
[67]:
%%manim  $parambigger
class Example(Scene):
    def construct(self):
        triangle.z_index=1
        self.add(triangle, square, circle,line)  # order matters
        print(self.mobjects)
        print(f"{triangle.z_index=} , {square.z_index=} , {circle.z_index=} , {line.z_index=}")
        self.add(BEST)
[Triangle, Square, Circle, Line]
triangle.z_index=1 , square.z_index=0 , circle.z_index=0 , line.z_index=0
_images/ch3_79_1.png
[68]:
%%manim  $parambigger
class Example(Scene):
    def construct(self):
        triangle.z_index = 1
        square.z_index   = 2
        circle.z_index   = 3
        self.add(triangle, square, circle,line)  # order matters
        self.add(BEST)
        print(f"{line.z_index=}")
line.z_index=0
_images/ch3_80_1.png
[69]:
%%manim  $parambigger
class Example(Scene):
    def construct(self):
        triangle.z_index = 3
        square.z_index   = 2
        circle.z_index   = 1
        self.add(triangle, square, circle,line)  # order matters
        self.add(BEST)
        print(f"{line.z_index=}")
line.z_index=0
_images/ch3_81_1.png
[70]:
%%manim  $parambigger
triangle.z_index = 0
square.z_index   = 0
circle.z_index   = 0
class Example(Scene):
    def construct(self):
        triangle.set(z_index=1)
        self.add(triangle, square, circle,line)  # order matters
        print(self.mobjects)
        print(f"{triangle.z_index=} , {square.z_index=} , {circle.z_index=} , {line.z_index=}")
        self.add(BEST)
[Triangle, Square, Circle, Line]
triangle.z_index=1 , square.z_index=0 , circle.z_index=0 , line.z_index=0
_images/ch3_82_1.png
[71]:
%%manim  $parambigger
triangle.z_index = 0
square.z_index   = 0
circle.z_index   = 0
class Example(Scene):
    def construct(self):
        try:
            triangle.set_style(z_index=1)  # here we expect an error! Only for didactic purpose, it is put into this `try` blog, so that no long error message is shown.
        except TypeError:
            print("TypeError, set_style() got an unexpected keyword argument 'z_index'. ")
            self.add(NO)
        self.add(triangle, square, circle,line)  # order matters
        print(f"{triangle.z_index=} , {square.z_index=} , {circle.z_index=} , {line.z_index=}")

TypeError, set_style() got an unexpected keyword argument 'z_index'.
triangle.z_index=0 , square.z_index=0 , circle.z_index=0 , line.z_index=0
_images/ch3_83_1.png

VGroup and Group#

VGroup#

It is a Group of VMobjects (“V” stands for Vector)

[72]:
#only for setup
def create_dots():
    blue1_ref= Dot(color= BLUE,       point=[-.3,-.5,0], radius=0.5)
    blue2_ref= Dot(color= BLUE_A,     point=[ .3,-.5,0], radius=0.5)
    yellow1_ref= Dot(color= YELLOW,   point=[-.3, .5,0], radius=0.5)
    yellow2_ref= Dot(color= YELLOW_A, point=[ .3, .5,0], radius=0.5)
    return blue1_ref, blue2_ref,yellow1_ref,yellow2_ref
[73]:
%%manim $param
blue1,blue2, yellow1,yellow2 = create_dots()
class Example(Scene):
    def construct(self):
        self.add(blue1,blue2, yellow1,yellow2)
_images/ch3_86_0.png
[74]:
%%manim $param
blue1,blue2, yellow1,yellow2 = create_dots()
class Example(Scene):
    def construct(self):
        VGroup(yellow1,yellow2).shift(RIGHT)
        self.add(blue1,blue2, yellow1,yellow2)
_images/ch3_87_0.png
[75]:
%%manim $param
blue1,blue2, yellow1,yellow2 = create_dots()
class Example(Scene):
    def construct(self):
        g1=VGroup(yellow1,yellow2).shift(2*RIGHT)
        self.add(blue1,blue2, g1)
_images/ch3_88_0.png
[76]:
%%manim $param
blue1,blue2, yellow1,yellow2 = create_dots()
class Example(Scene):
    def construct(self):
        g1=VGroup(yellow1,yellow2).set_color(RED)
        self.add(blue1,blue2, g1)
_images/ch3_89_0.png
[77]:
%%manim $param
blue1,blue2, yellow1,yellow2 = create_dots()
class Example(Scene):
    def construct(self):
        g1=VGroup(yellow1,yellow2).shift(0.5*DOWN)
        g2=VGroup(blue1,blue2)
        self.add(g1, g2)
_images/ch3_90_0.png
[78]:
%%manim $param
blue1,blue2, yellow1,yellow2 = create_dots()
class Example(Scene):
    def construct(self):
        g1=VGroup(yellow1,yellow2).shift(0.5*DOWN)
        g2=VGroup(blue1,blue2)
        self.add(g2,g1)
_images/ch3_91_0.png
[79]:
%%manim $param
blue1,blue2, yellow1,yellow2 = create_dots()
class Example(Scene): # Groups of Groups
    def construct(self):
        g1=VGroup(yellow1,yellow2).shift(0.5*DOWN)
        g2=VGroup(blue1,blue2)
        gAll = VGroup(g1, g2)
        self.add(gAll)
        print(gAll.submobjects)
        print(gAll.submobjects[0].submobjects)
        print(gAll.submobjects[1].submobjects)
[VGroup(Dot, Dot), VGroup(Dot, Dot)]
[Dot, Dot]
[Dot, Dot]
_images/ch3_92_1.png
[80]:
%%manim $param
blue1,blue2, yellow1,yellow2 = create_dots()
class Example(Scene): #setting VMobject attibutes
    def construct(self):
        g=VGroup(yellow1,yellow2,blue1,blue2)
        g.set_stroke(color=PURPLE_D, width=20) # <--
        self.add(g)
_images/ch3_93_0.png
[81]:
%%manim $param
blue1,blue2, yellow1,yellow2 = create_dots()
class Example(Scene): # add syntax
    def construct(self):
        g=VGroup(yellow1,yellow2,blue1)
        g.add(blue2) # <--
        g.set_stroke(color=GREEN, width=20)
        self.add(g)
_images/ch3_94_0.png
[82]:
%%manim $param
blue1,blue2, yellow1,yellow2 = create_dots()
class Example(Scene): # += Syntax
    def construct(self):
        g=VGroup(yellow1,yellow2,blue1)
        g += blue2 # <--
        g.set_stroke(color=ORANGE, width=20)
        self.add(g)
_images/ch3_95_0.png
[83]:
%%manim $param
blue1,blue2, yellow1,yellow2 = create_dots()
class Example(Scene): # empty initilizing
    def construct(self):
        g=VGroup()
        for _ in range(0,10):
            g += yellow1.copy()
        g.set_stroke(color=WHITE, width=20)
        g.arrange_in_grid(rows=2) # <-- Groups and VGroups can be arranged in grids
        g.move_to(ORIGIN)
        self.add(g)
_images/ch3_96_0.png

Note:

VMobject().add(…) is functionally equivalent to VGroup(…), but it is recommended to use VGroup, as

  • It is better readable

  • supports the += syntax

[84]:
%%manim $param
blue1,blue2, yellow1,yellow2 = create_dots()
class Example(Scene):  # using VMobject instead
    def construct(self):
        g= VMobject()
        g.add(yellow1,yellow2,blue1,blue2)
        g.set_stroke(color=PURPLE_D, width=20)
        self.add(g)
_images/ch3_98_0.png
[85]:
%%manim $param
blue1,blue2, yellow1,yellow2 = create_dots()
class Example(Scene):  # other Mobjects can be added to any Mobjects
    def construct(self):
        d= Dot(color= YELLOW, radius=0.7)
        d.add(Line(0.2*UP, 0.8*UP, color=RED,stroke_width=40))
        self.add(d)
_images/ch3_99_0.png
[86]:
%%manim $param
dot= Dot(color= YELLOW, radius=0.5)
image = ImageMobject(np.uint8([[200, 233, 111, 200],
                               [255, 100, 190, 100]])).shift(2*RIGHT)
image.height = 1
class Example(Scene):
    def construct(self):
        self.add(dot, image)
        try: # Image is not a VMobject!
            VGroup(dot,image).shift(3*RIGHT)
        except TypeError:
            print("Adding an Mobject to a VGroup is not possible!")
            self.add(NO)
Adding an Mobject to a VGroup is not possible!
_images/ch3_100_1.png

Group#

Groups Mobjects and VMobjects togehter. You can only use the methods of Mobject here. Methods of VMobject wont be supported.

[87]:
%%manim $param
dot= Dot(color= YELLOW, radius=0.5)
image = ImageMobject(np.uint8([[200, 233, 111, 200],
                               [255, 100, 190, 100]])).shift(2*RIGHT)
image.height = 1
class Example(Scene):
    def construct(self):
        self.add(dot, image)
        Group(dot,image).shift(3*RIGHT)
_images/ch3_102_0.png
[88]:
%%manim $param
blue1,blue2, yellow1,yellow2 = create_dots()
class Example(Scene): #
    def construct(self):
        g=Group(yellow1,yellow2,blue1,blue2)
        try:
            g.set_stroke(color=PURPLE_D, width=20)
        except TypeError:
            print("TypeError!")
            self.add(NO)
        self.add(g)
TypeError!
_images/ch3_103_1.png

Note: z_index is not supported, neither for VGroup nor for Group

[89]:
%%manim $param
blue1,blue2, yellow1,yellow2 = create_dots()
class Example(Scene):
    def construct(self):
        a=VGroup(yellow1,yellow2).shift(0.5*DOWN)
        b=VGroup(blue1,blue2)
        a.set_z_index(2)
        b.set_z_index(1)
        self.add(a,b)
        self.add(NO)
_images/ch3_105_0.png

Making Mobject Classes#

[90]:
param   = "-v WARNING -s -r 300,100 --disable_caching --progress_bar None Example"
[91]:
%%manim $param
class Example(Scene):
    def construct(self):
        d1 = Dot(point= [0,0,0], radius=2)
        d2 = Dot(point= [1,0,0], radius=2)
        diff = Difference(d1,d2,fill_opacity=1,stroke_width=0)
        self.add(diff)
_images/ch3_108_0.png
[92]:
%%manim $param
class Moon(VGroup):
    def __init__(self):
        super().__init__()
        d1 = Dot(point= [0,0,0], radius=2)
        d2 = Dot(point= [1,0,0], radius=2)
        diff = Difference(d1,d2,fill_opacity=1,stroke_width=0, fill_color=BLUE)
        self.add(diff)

class Example(Scene):
    def construct(self):
        m = Moon()
        self.add(m)
_images/ch3_109_0.png

Note: Replacing super().__init__() with VGroup().__init__(self) would also work, but is discouraged to use.

Note: The class can be of type VGroup,Group, VMobject, and Mobject. It depends on what class features you want to use when choosing the classtype. VGroup is recommended.

[93]:
%%manim $param
class Moon(VGroup): # <- Try what happens when you change it to VMobject
    def __init__(self):
        super().__init__()
        d1 = Dot(point= [0,0,0], radius=2)
        d2 = Dot(point= [1,0,0], radius=2)
        diff = Difference(d1,d2,fill_opacity=1,stroke_width=0, fill_color=BLUE)
        self.add(diff)

class Example(Scene):
    def construct(self):
        m = Moon()
        m += Line(stroke_width=40, color=BLUE_E)
        self.add(m)
_images/ch3_112_0.png
[94]:
%%manim $param
class Moon(VGroup):
    def __init__(self,moon_color): # <- here one can init the classes with certain parameters.
        super().__init__()
        d1 = Dot(point= [0,0,0], radius=2)
        d2 = Dot(point= [1,0,0], radius=2)
        diff = Difference(d1,d2,fill_opacity=1, fill_color= moon_color)  # <- here the parameter is used
        self.add(diff)

class Example(Scene):
    def construct(self):
        m = Moon(moon_color=YELLOW) # <- here the parameter is used
        self.add(m)
_images/ch3_113_0.png

Congratulations!

You are now a master in setting up your Mobjects on a scene. Let’s go on with the part you came to manim for in the first place: Animations!