Animating Arrays#
Manim Array - MArray#
The most basic data structure this package provides is the MArray
(short for Manim Array 😄). To create a MArray
simply create an instance by passing a python list
.
1class MyScene(Scene):
2 def construct(self):
3 arr = MArray([1, 2, 3])
4 self.play(Create(arr))
5 self.wait(1)
Animating MArray#
To animate the MArray
, simply invoke the animate
property as shown below:
1self.play(arr.animate.shift(UP * 2 + LEFT * 5))
Moreover, you can also use the MArray.animate_elem()
method to animate a single element of the MArray
as well:
1self.play(arr.animate_elem(1).shift(DOWN))
Lastly, you can also animate the body, value and the index of any element using the MArray.animate_elem_square()
, MArray.animate_elem_value()
and MArray.animate_elem_index()
respectively.
1self.play(
2 arr.animate_elem_square(1).set_fill(BLACK),
3 arr.animate_elem_value(1).set_fill(RED),
4 arr.animate_elem_index(1).rotate(PI / 2)
5)
Customizing MArray#
The MArray
also allows you to alter the way your array looks. While creating your array pass arguments to Square
(used to represent the element body) and Text
(used to represent the element value and index) mobjects.
1arr = MArray(
2 [1, 2, 3],
3 mob_square_args={'fill_color': RED_D},
4 mob_value_args={'color': BLACK},
5 mob_index_args={'color': GOLD_A}
6)
Growth Direction#
Furthermore, you can also create MArray
that grows in different directions (e.g. up, down, right and left etc.).
To do this, simply pass your preferred direction enum from MArrayDirection
as the arr_dir
argument to the constructor. The code snippet below generates four different arrays in each direction.
1class MyScene(Scene):
2 def construct(self):
3 arr_up = MArray([1, 2], arr_dir=MArrayDirection.UP)
4 arr_right = MArray([3, 4], arr_dir=MArrayDirection.RIGHT)
5 arr_down = MArray([5, 6], arr_dir=MArrayDirection.DOWN)
6 arr_left = MArray([7, 8], arr_dir=MArrayDirection.LEFT)
7
8 self.play(Create(arr_up))
9 self.play(arr_up.animate.shift(UP * 2))
10 self.play(Create(arr_right))
11 self.play(arr_right.animate.shift(RIGHT * 2))
12 self.play(Create(arr_down))
13 self.play(arr_down.animate.shift(DOWN * 2))
14 self.play(Create(arr_left))
15 self.play(arr_left.animate.shift(LEFT * 2))
16
17 self.wait(1)
Array Label#
For an MArray
, you can also a label with the array via specifying the label
argument.
Similar to how we specify the growth direction using MArrayDirection
enum, we can dictate the position of the label.
1class MyScene(Scene):
2 def construct(self):
3 arr_label_left = MArray([1, 2, 3], label='Arr')
4 arr_label_right = MArray([1, 2, 3], label='Arr', arr_label_pos=MArrayDirection.RIGHT)
5 arr_label_down = MArray([1, 2, 3], label='Arr', arr_label_pos=MArrayDirection.DOWN)
6 arr_label_up = MArray([1, 2, 3], label='Arr', arr_label_pos=MArrayDirection.UP, arr_label_gap=0.75)
7
8 self.play(Create(arr_label_left))
9 self.play(arr_label_left.animate.shift(UP * 2 + LEFT * 4))
10 self.play(Create(arr_label_right))
11 self.play(arr_label_right.animate.shift(DOWN * 2 + LEFT * 4))
12 self.play(Create(arr_label_down))
13 self.play(arr_label_down.animate.shift(UP * 2 + RIGHT))
14 self.play(Create(arr_label_up))
15 self.play(arr_label_up.animate.shift(DOWN * 2 + RIGHT))
16
17 self.wait(1)
Note
The arr_label_gap
argument specifies the distance between the MArrayElement
‘s manim.Square
and the array label itself.
Hex Indices#
Lets say you want to show a 4-byte integer array with its addresses. You can simply achieve this by using index_hex_display
and index_offset
arguments of the MArray
constructor.
1class MyScene(Scene):
2 def construct(self):
3 arr = MArray(
4 [1, 2, 3, 4],
5 index_hex_display=True,
6 index_offset=4
7 )
8 self.play(Create(arr))
9 self.wait(1)
Hide Indices#
Or if you don’t want to show the indices at all, simply pass True
as the hide_index
argument to the constructor
1class MyScene(Scene):
2 def construct(self):
3 arr = MArray(
4 [1, 2, 3, 4],
5 hide_index=True
6 )
7 self.play(Create(arr))
8 self.wait(1)
Misc Functions#
The MArray
provides some auxiliary methods which this secion will discuss.
Append Element#
For an existing array, you can also append an element simply by invoking the MArray.append_elem()
method.
1class MyScene(Scene):
2 def construct(self):
3 arr = MArray([1, 2, 3], label='Array', arr_label_pos=MArrayDirection.DOWN)
4 self.add(arr)
5 self.wait(1)
6 self.play(*arr.append_elem(4))
7 self.wait(1)
Note
You can also pass mob_*_args
to this method to customize the inserted element.
Did you notice the the *
before we invoked the MArray.append_elem()
method? Since the method returns a list of manim.Animation
therefore, we unpack it while feeding it to the self.play
method of the Scene
.
Moreover, you can also specify the animation that is played for the inserted element via the append_anim
argument. The code snippet below passes the manim.GrowFromCenter
animation to the MArray.append_elem
method:
1self.play(*arr.append_elem(4, append_anim=GrowFromCenter))
Note
You can also specify arguments to the passed animation via the append_anim_args
parameter and also set the target of the animation using the append_anim_target
parameter that takes in MArrayElementComp
enum.
Remove Element#
To remove an element simply invoke the MArray.remove_elem
method with the index of element you wish to remove. The method returns two the removal animation and a function that udpates the indices of the remaining elements.
1(remove_anim, update_indices) = arr.remove_elem(1)
2self.play(remove_anim)
3self.play(*update_indices())
Similar to how you were able to pass the append animation to the MArray.append_elem
function, you can specify two animations for the MArray.remove_elem
method:
1. Element removal animation via the removal_anim
parameter.
2. Indices update animation via the update_anim
parameter.
The code snippet below provides an example:
1(remove_anim, update_indices) = arr.remove_elem(1, removal_anim=ShowPassingFlash , update_anim=Indicate)
Note
You can also specify arguments to the passed animation via the *_anim_args
parameter and also set the target of the animation using the *_anim_target
parameter.
Update Element#
You can also update the value and the index of an existing array using the MArray.update_elem_value
and MArray.update_elem_index
methods respectively.
1class MyScene(Scene):
2 def construct(self):
3 arr = MArray([1, 2, 3])
4 self.add(arr)
5 self.wait(1)
6 self.play(
7 Write(arr.update_elem_value(1, 20)),
8 Write(arr.update_elem_index(1, -2))
9 )
10 self.wait(1)
Note
You can also pass mob_value_args
and mob_index_args
to respective methods to customize the updated element mobject.
With this we conclude this guide. We hope you found it useful! ✌️