This article is the 7th day article of the Hannari Python Advent Calendar.
I found an animation tool used in the YouTube channel "3Blue1Brown (YouTube)" that introduces famous mathematics overseas.
The name is called "** Manim **" (short for Mathematical Animation Engine).
Although it is not well known in Japan, it is under active development and is MIT licensed, so it is likely to become famous in the future.
You can easily create such an animation in Python.
This time, install the well-maintained community edition github.com/ManimCommunity/manim instead of github.com/3b1b/manim, which includes the version used for 3Blue1Brown.
Manim is cross-platform and can be installed on Mac, GNU/Linux and Windows.
Click here for ** installation details **! ↓ Installation
For WSL (Ubuntu 18.04)
First, update.
sudo apt update
sudo apt upgrade
Install pycairo
.
pycairo
is a Python wrapper for the library cairo
that draws 2D vector images.
sudo apt install libcairo2-dev
ffmpeg
is a library for recording, converting and playing video and audio.
sudo apt install ffmpeg
Install Latex
sudo apt install texlive texlive-latex-extra texlive-fonts-extra \
texlive-latex-recommended texlive-science texlive-fonts-extra tipa
If you don't have python3-pip
sudo apt install python3-pip
pip3 install manim
Create an appropriate project directory and work in it.
mkdir project
cd project
Create a file called scene.py
as a trial and write the following program.
** Learn more about the modules, functions, and variables included in Manim ** Click here ↓ Reference
from manim import *
class HelloWorld(Scene):
def construct(self):
#######Code#######
#Define text
first_text = Text("Hello, World!")
#Show text
self.wait(1)
self.play(Write(first_text))
self.wait(1)
#2 texts up
self.play(ApplyMethod(first_text.shift,2*UP))
self.wait(1)
math_text=MathTex(
"\\frac{d}{dx}f(x)g(x)=","f(x)\\frac{d}{dx}g(x)","+",
"g(x)\\frac{d}{dx}f(x)"
)
#Show formula
self.play(Write(math_text))
framebox1 = SurroundingRectangle(math_text[1], buff = .1)
framebox2 = SurroundingRectangle(math_text[3], buff = .1)
self.play(
ShowCreation(framebox1),
)
self.wait()
# manim.animation.transform
self.play(
ReplacementTransform(framebox1,framebox2),
)
self.wait()
Specify the HelloWorld
class name of scene.py
, low quality rendering, and save in gif
format.
manim scene.py HelloWorld -ql -i
[12/15/20 13:21:22] INFO Text now uses Pango for rendering. In case of text_mobject.py:719
problems, the old implementation is available as
CairoText.
[12/15/20 13:21:24] INFO Animation 0 : Partial movie file written in {'/mn scene_file_writer.py:393
t/c/Users/tonoy/Dev/manim/project/media/videos/sc
ene/480p15/partial_movie_files/HelloWorld/3070002
022_3972803965_223132457.mp4'}
...
Command configuration Quoted from https://github.com/ManimCommunity/manim/#command-line-arguments
** Click here for command details ** ↓ A list of all CLI flags
-ql
: Low quality rendering, 480p 15fps
-qe
: High quality rendering, 1080p 60fps
-qk
: 4K rendering, 4K 60fps
-p
: Instruct manim to play the video once the scene is rendered
-s
: Output the last frame of the scene. Use this when you want to take a still image.
-i
: Save in gif format
-a
: Multiple (Scene
) can be rendered together.
Let's animate the activation function.
from manim import *
import math
class Graphing(GraphScene):
CONFIG = {
"x_min": -4,
"x_max": 4,
"y_min": -2,
"y_max": 2,
"graph_origin": ORIGIN,
"function_color": WHITE,
"axes_color": BLUE
}
def construct(self):
#Make graph
self.setup_axes(animate=True)
func_graph = self.get_graph(lambda x: 1 / (1 + np.exp(-x)), color=WHITE)
graph_title = Tex("sigmoid function")
graph_title.scale(1.5)
graph_title.to_corner(UP + LEFT)
func_graph_2 = self.get_graph(lambda x: np.tanh(x), color=GREEN)
graph_title_2 = Tex("tanh function")
graph_title_2.scale(1.5)
graph_title_2.to_corner(UP + LEFT)
func_graph_3 = self.get_graph(lambda x: np.maximum(0, x), color=YELLOW)
graph_title_3 = Tex("ReLU function")
graph_title_3.scale(1.5)
graph_title_3.to_corner(UP + LEFT)
#Display graph
self.play(ShowCreation(func_graph))
self.add(graph_title)
self.wait(1)
self.play(FadeOut(graph_title))
self.play(ShowCreation(func_graph_2))
self.add(graph_title_2)
self.wait(1)
self.play(FadeOut(graph_title_2))
self.play(ShowCreation(func_graph_3))
self.add(graph_title_3)
self.wait(2)
Let's graph the partial differentials that are often used in neural network learning.
Since it is 3D, it will take some time.
from manim import *
class ThreeDSurface(ParametricSurface):
def __init__(self, **kwargs):
kwargs = {
"u_min": -1.5,
"u_max": 1.5,
"v_min": -1.5,
"v_max": 1.5,
"checkerboard_colors": [GREEN, BLUE],
"checkerboard_opacity": 0.5
}
ParametricSurface.__init__(self, self.func, **kwargs)
def func(self, x, y):
return np.array([x,y,x**2 + y**2])
class Test(ThreeDScene):
def construct(self):
self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES)
axes = ThreeDAxes()
self.add(axes)
surface = ThreeDSurface()
self.play(ShowCreation(surface))
d = Dot(np.array([0,0,0]), color = YELLOW)
self.play(ShowCreation(d))
self.wait()
self.move_camera(phi=45 * DEGREES, theta=30 * DEGREES)
self.begin_ambient_camera_rotation()
self.wait(9)
I never thought that difficult animations could be done so easily with matplotlib
. I will use it more and more from now on.
Recommended Posts