Creating math animations in Python with Manim

by Gilbert Tanner on Feb 03, 2020

Creating math animations in Python with Manim

Creating animations for math explanations can be quite challenging and requires good video-editing skills. Over the last couple of days, I tried Manim, a mathematical animation engine made by 3Blue1Brown.

3Blue1Brown is an exceptional math-YouTuber how tries to explain topics visually, which gives you a completely different view on the subject.

Using Manim, he creates videos like the following:

Figure 1: Explaining Fourier Transforms with Manim

In this article, I will walk you through the basics of Manim, including:

  • How to install Manim
  • How to run a project with Manim
  • And how to create simple projects

You can find all the code covered in this article on my Github.

Installation

To install Manim, execute the following commands:

git clone https://github.com/3b1b/manim.git
pip3 install manimlib
python3 -m pip install -r requirements.txt

If you want to use LaTeX to display math you'll also need some further packages installed:

Linux Installation

On Linux you can install these requirements with the following commands:

sudo apt install ffmpeg sox
sudo apt-get install libcairo2-dev libjpeg-dev libgif-dev
sudo apt install texlive-latex-base texlive-full texlive-fonts-extra

Windows Installation

On Windows, the installation is a little bit more involved.

  1. Install FFmpeg.
  2. Install Cairo. For most users, pycairo‑1.18.0‑cp37‑cp37m‑win32.whl will do fine.
  3. Install a LaTeX distribution. MiKTeX is recommended.
  4. Install SoX.
  5. Install the remaining Python packages. Make sure that pycairo==1.17.1 is changed to pycairo==1.80.0 in requirements.txt.
git clone https://github.com/3b1b/manim.git
cd manim
pip3 install -r requirements.txt
python3 manim.py example_scenes.py SquareToCircle -pl

Running Manim projects

An easy way to test whether your installation is working is by running the following command:

python3 -m manim example_scenes.py SquareToCircle -pl

The -p flag in the command above stands for previewing. The -l flag is for faster rendering with lower quality.

Live Streaming

You can also stream your animation by running manim with the --livestream option.

> python -m manim --livestream
Writing to media/videos/scene/scene/1080p30/LiveStreamTemp.mp4

Manim is now running in streaming mode. Stream animations by passing
them to manim.play(), e.g.
>>> c = Circle()
>>> manim.play(ShowCreation(c))

>>>

Creating your first Scene

Now that you have installed everything correctly, you're ready to write your first application.

from manimlib.imports import *

class SquareToCircle(Scene):
    def construct(self):
        # Creating shapes
        circle = Circle()
        square = Square()

        #Showing shapes
        self.play(ShowCreation(square))
        self.play(Transform(square, circle))
        self.play(FadeOut(square))
python3 -m manim square_to_circle.py SquareToCircle
Figure 2: SquareToCircle

Let us break this down step-by-step:

  • The import statement on top imports everything needed to use Manim.
  • For running animations, you have to create a class that inherits from Manims Scene class.
  • Inside the class, you need to create the construct method. The construct method is essentially the main method for the class. In it, you can write all the code for the animation.
  • Inside the construct method, I first created two MObjects (Manim Objects) – a circle and a square. Lastly, I displayed the shapes using the play method.

We can also modify the appearance of the objects by adding a few lines of code:

from manimlib.imports import *

class SquareToCircleWithModifications(Scene):
    def construct(self):
        circle = Circle()
        square = Square()
        square.flip(RIGHT)
        square.rotate(-3 * TAU / 8)
        circle.set_fill(PINK, opacity=0.5)

        self.play(ShowCreation(square))
        self.play(Transform(square, circle))
        self.play(FadeOut(square))
Figure 3: Modifying the appearence of the square and circle

Displaying text

Displaying text is also pretty straight forward.

from manimlib.imports import *


class displayText(Scene):
    def construct(self):
        # Create TextMobjects
        first_line = TextMobject('Create cool animations')
        second_line = TextMobject('using Manim')
        third_line = TextMobject('Try it out yourself.', color=RED)

        # Position second line underneath first line
        second_line.next_to(first_line, DOWN)

        # Displaying text
        self.wait(1)
        self.play(Write(first_line), Write(second_line))
        self.wait(1)
        self.play(ReplacementTransform(first_line, third_line), FadeOut(second_line))
        self.wait(2)

In order to display text, you need to create a TextMobject and pass it the text you want to write to the screen. After that, you can display the text using the play method and some animation.

Figure 4: Displaying text

Math equations

Math equations can be written in Manim using LaTeX – a typesetting system widely used in academia. One of LaTeX big advantages is that it allows you to create good looking math equation with an intuitive system.

I won't go over LaTeX in this article, but if you are curious, there are lots of great tutorials out there.

Equations, just like text, can be created using TextMobjects. When making an equation, you need to put a $ at the start and end of the text.

text = TextMobject('some text')
equation = TextMobject('$some equation$')

You can add symbols like the summation or integral symbols with two backslashes.

alpha = TextMobject('$\\alpha$')

Displaying some text and an equation could look like the following:

from manimlib.imports import *


class displayEquations(Scene):
    def construct(self):
        # Create TextMobjects
        first_line = TextMobject('Manim also allows you')
        second_line = TextMobject('to show beautiful math equations')
        equation = TextMobject('$d\\left(p, q\\right)=d\\left(q, p\\right)=\\sqrt{(q_1-p_1)^2+(q_2-p_2)^2+...+(q_n-p_n)^2}=\\sqrt{\\sum_{i=1}^n\\left(q_i-p_i\\right)^2}$')
        
        # Position second line underneath first line
        second_line.next_to(first_line, DOWN)

        # Displaying text and equation
        self.play(Write(first_line), Write(second_line))
        self.wait(1)
        self.play(ReplacementTransform(first_line, equation), FadeOut(second_line))
        self.wait(3)
Figure 5: Displaying a math equation

Creating graphs

Manim also allows us to create and display graphs. For this, you need to create a class that inherits from the GraphScene class. Furthermore, you need to specify a config dictionary that contains the most basic configuration of the graph.

The defaults look as follows:

CONFIG = {
        "x_min": -1,
        "x_max": 10,
        "x_axis_width": 9,
        "x_tick_frequency": 1,
        "x_leftmost_tick": None,  # Change if different from x_min
        "x_labeled_nums": None,
        "x_axis_label": "$x$",
        "y_min": -1,
        "y_max": 10,
        "y_axis_height": 6,
        "y_tick_frequency": 1,
        "y_bottom_tick": None,  # Change if different from y_min
        "y_labeled_nums": None,
        "y_axis_label": "$y$",
        "axes_color": GREY,
        "graph_origin": 2.5 * DOWN + 4 * LEFT,
        "exclude_zero_label": True,
        "default_graph_colors": [BLUE, GREEN, YELLOW],
        "default_derivative_color": GREEN,
        "default_input_color": YELLOW,
        "default_riemann_start_color": BLUE,
        "default_riemann_end_color": GREEN,
        "area_opacity": 0.8,
        "num_rects": 50,
    }

After specifying the config, you can create a graph inside the construct method.

from manimlib.imports import *


class CreateGraph(GraphScene):
    CONFIG = {
        'x_min': -3,
        'x_max': 3,
        'y_min': -5,
        'y_max': 5,
        'graph_origin': ORIGIN,
        'axes_color': BLUE
    }

    def construct(self):
        # Create Graph
        self.setup_axes(animate=True)
        graph = self.get_graph(lambda x: x**2, WHITE)
        graph_label = self.get_graph_label(graph, label='x^{2}')

        graph2 = self.get_graph(lambda x: x**3, WHITE)
        graph_label2 = self.get_graph_label(graph2, label='x^{3}')

        # Display graph
        self.play(ShowCreation(graph), Write(graph_label))
        self.wait(1)
        self.play(Transform(graph, graph2), Transform(graph_label, graph_label2))
        self.wait(1)
Figure 6: Creating a graph

As you can see to create a graph, you need to create a method that returns a y value for every x value it gets. In the code above, I used lambda functions to specify them, but you can also use any other method. After you have created the method, you need to pass it to self.get_graph, which creates a mobject out of the method.

Note that the method only specifies how the graph should look like and doesn't actually calculate any values yet. The number of points, which are calculated are determined by the CONFIG dictionary specified above the construct method.

Other great resources

malhotra5/Manim-Tutorial
A tutorial for manim, a mathematical animation engine made by 3b1b - malhotra5/Manim-Tutorial

Conclusion

Manim is a powerful mathematical animation engine written in Python. With it, you can create beautiful animations with only a few lines of code. I really like the process of creating animations using code because, in my opinion, it makes things way more reproducible and easy to change.

That’s all from this article. If you have any questions or just want to chat with me, feel free to leave a comment below or contact me on social media. If you want to get continuous updates about my blog make sure to follow me on Medium and join my newsletter.