Manim in Jupyter#

Working with manim in jupyter notebooks has several advantages:

  • code snippets and rendered outputs are close together

  • easy to iterate examples

  • easy to try different varieties of one scene in multiple cells

  • computation intensive code can be executed separately from the scenes

  • global Mobjects can be used in multiple scenes.

Simple Example#

First, we need to import manim

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

Now we build up our scene

[2]:
%%manim -v WARNING  --progress_bar None -s -ql --disable_caching MyExample
class MyExample(Scene):
    def construct(self):
        m= ManimBanner()
        self.add(m)
_images/ch1_6_0.png

Note, that I use the following parameters:

  • -v WARNING means that only warnings are shown in the log

  • --progress_bar None will not show the animation progress bar

  • -s will only show the last frame

  • -ql renders in low quality

  • --disable_caching will disable the manim caching system

  • MyExample gives the scene name

for rendering a video, just remove the -s flag. To lower the resolution, you can use -r 400,200 (pixel values in x and y direction).

[3]:
%%manim -v WARNING  --progress_bar None  -r 400,200  --disable_caching HelloManim
class HelloManim(Scene):
    def construct(self):
        self.camera.background_color = "#ece6e2"
        banner_large = ManimBanner(dark_theme=False).scale(0.7)
        self.play(banner_large.create())
        self.play(banner_large.expand())

Rendering with a transparent background can be done like this:

[4]:
%%manim -v ERROR  --progress_bar None  -r 400,200 -t --disable_caching HelloManim
class HelloManim(Scene):
    def construct(self):
        self.camera.background_color = "#ece6e2"
        banner_large = ManimBanner(dark_theme=False).scale(1.5)
        self.add(banner_large)
[06/25/23 14:48:43] WARNING  Output format set as webm, this can be slower than other formats          utils.py:992
_images/ch1_10_1.png

We can define the parameters as a string param and call this string by the cell magic with $param

[5]:
param = "-v WARNING  -s -ql  --disable_caching Example"
paramSMALL = "-v WARNING -r 400,200 -s  --disable_caching Example"
[6]:
%%manim $param
class Example(Scene):
    def construct(self):
        m= ManimBanner()
        self.add(m)
_images/ch1_13_0.png

Initializing Mobjects Outside the Class#

In some cases, it might be convenient to define mobjects outside the Scene class (e.g. for uncluttering or for speeding up the animation).

[7]:
m = ManimBanner()
[8]:
%%manim $paramSMALL
class Example(Scene):
    def construct(self):
        m.scale(0.4        )
        m.shift(1.5*UP)
        self.add(m)
_images/ch1_16_0.png

Because the mobject is manipulated in the class, the next cell might show some unexpected scaling and shifting:

[9]:
%%manim $paramSMALL
class Example(Scene):
    def construct(self):
        m.scale(0.4)
        m.shift(1.5*UP)
        self.add(m)
_images/ch1_18_0.png

To aviod this, it is better to add only a copy of these mobjects to scenes, and keep the originals untouched:

[10]:
m_reference = ManimBanner()
[11]:
%%manim $paramSMALL
class Example(Scene):
    def construct(self):
        m = m_reference.copy()
        m.scale(0.4)
        m.shift(2*UP)
        self.add(m)
_images/ch1_21_0.png
[12]:
%%manim $paramSMALL
class Example(Scene):
    def construct(self):
        m = m_reference.copy()
        m.scale(0.4)
        m.shift(2*UP)
        self.add(m)
_images/ch1_22_0.png

Defining Global Mobjects#

When you have to build complex scenes, you might want to use parts of that scene for your next scene. That is possible with global variables, which can be accessed in any other scene.

[13]:
%%manim $paramSMALL
class Example(Scene):
    def construct(self):
        stars= VGroup()
        for i in range(0,20):
            s= Star(color= random_bright_color(), fill_opacity=1).scale(0.8)
            stars.add(s)
        stars.arrange_in_grid()
        self.add(stars)
        global favoritstar
        favoritstar = stars[9]
_images/ch1_24_0.png
[14]:
%%manim $paramSMALL
class Example(Scene):
    def construct(self):
        self.add(favoritstar)
_images/ch1_25_0.png

Pre-Execute Slow Code#

In this example, calculating a random walk for 500 particles and 100000 steps takes about 4 seconds.
This step can be done before the actual scene construction, which takes about 0.2 seconds.
Making aesthetic changes to the scene will then become easier.
Note: The %%time command will print the execution time of the cells.
[15]:
%%time
np.random.seed(20)
steps = np.random.choice(a=[-1, 0, 1], size=(100000,1000))
stop = steps.cumsum(0)
end_points= stop[-1]/stop[-1].max()
end_pointsX = end_points[0:499]
end_pointsY = end_points[500:-1]
CPU times: user 2.15 s, sys: 576 ms, total: 2.73 s
Wall time: 2.73 s
[16]:
%%time
%%manim $param
class Example(Scene):
    def construct(self):
        radius= (end_pointsX*end_pointsX + end_pointsY * end_pointsY)**0.5
        dots = VGroup()
        for  x,y,r in zip(end_pointsX, end_pointsY,radius):
            c= interpolate_color(YELLOW, RED, r)
            dots.add(Dot(color=c,point=[3*x,3*y,0]).scale(0.7))
        self.add(dots)
_images/ch1_28_0.png
CPU times: user 452 ms, sys: 7.98 ms, total: 460 ms
Wall time: 459 ms

Installing Plugins#

plugins can be found at https://plugins.manim.community/

[17]:
!pip install manim-physics
Collecting manim-physics
  Downloading manim_physics-0.3.0-py3-none-any.whl (14 kB)
Collecting Shapely<2.0.0,>=1.8.0 (from manim-physics)
  Downloading Shapely-1.8.5.post1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.2 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.2/2.2 MB 18.1 MB/s eta 0:00:00
Requirement already satisfied: manim<0.18.0,>=0.17.3 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim-physics) (0.17.3)
Collecting pymunk<7.0.0,>=6.0.0 (from manim-physics)
  Downloading pymunk-6.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.0 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.0/1.0 MB 36.7 MB/s eta 0:00:00
Requirement already satisfied: Pillow<10.0,>=9.1 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (9.5.0)
Requirement already satisfied: Pygments<3.0.0,>=2.10.0 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (2.15.1)
Requirement already satisfied: click<=9.0,>=7.2 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (8.1.3)
Requirement already satisfied: click-default-group<2.0.0,>=1.2.2 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (1.2.2)
Requirement already satisfied: cloup<0.14.0,>=0.13.0 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (0.13.1)
Requirement already satisfied: colour<0.2.0,>=0.1.5 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (0.1.5)
Requirement already satisfied: decorator<6.0.0,>=5.0.7 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (5.1.1)
Requirement already satisfied: isosurfaces==0.1.0 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (0.1.0)
Requirement already satisfied: manimpango<0.5.0,>=0.4.0.post0 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (0.4.3)
Requirement already satisfied: mapbox-earcut<2.0.0,>=1.0.0 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (1.0.1)
Requirement already satisfied: moderngl<6.0.0,>=5.6.3 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (5.8.2)
Requirement already satisfied: moderngl-window<3.0.0,>=2.3.0 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (2.4.4)
Requirement already satisfied: networkx<3.0,>=2.5 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (2.8.8)
Requirement already satisfied: numpy<2.0,>=1.19 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (1.25.0)
Requirement already satisfied: pycairo<2.0,>=1.21 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (1.24.0)
Requirement already satisfied: pydub<0.26.0,>=0.25.1 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (0.25.1)
Requirement already satisfied: requests<3.0.0,>=2.26.0 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (2.31.0)
Requirement already satisfied: rich!=12.0.0,>=6.0 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (13.4.2)
Requirement already satisfied: scipy<2.0.0,>=1.7.3 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (1.10.1)
Requirement already satisfied: screeninfo<0.9,>=0.8 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (0.8.1)
Requirement already satisfied: skia-pathops<0.8.0,>=0.7.0 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (0.7.4)
Requirement already satisfied: srt<4.0.0,>=3.5.0 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (3.5.3)
Requirement already satisfied: svgelements<2.0.0,>=1.8.0 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (1.9.5)
Requirement already satisfied: tqdm<5.0.0,>=4.62.3 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (4.65.0)
Requirement already satisfied: watchdog<3.0.0,>=2.1.6 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from manim<0.18.0,>=0.17.3->manim-physics) (2.3.1)
Collecting cffi>=1.15.0 (from pymunk<7.0.0,>=6.0.0->manim-physics)
  Downloading cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (462 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 462.6/462.6 kB 49.6 MB/s eta 0:00:00
Collecting pycparser (from cffi>=1.15.0->pymunk<7.0.0,>=6.0.0->manim-physics)
  Downloading pycparser-2.21-py2.py3-none-any.whl (118 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 118.7/118.7 kB 26.5 MB/s eta 0:00:00
Requirement already satisfied: glcontext<3,>=2.3.6 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from moderngl<6.0.0,>=5.6.3->manim<0.18.0,>=0.17.3->manim-physics) (2.3.7)
Requirement already satisfied: pyglet>=2.0dev23 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from moderngl-window<3.0.0,>=2.3.0->manim<0.18.0,>=0.17.3->manim-physics) (2.0.8)
Requirement already satisfied: pyrr<1,>=0.10.3 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from moderngl-window<3.0.0,>=2.3.0->manim<0.18.0,>=0.17.3->manim-physics) (0.10.3)
Requirement already satisfied: charset-normalizer<4,>=2 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from requests<3.0.0,>=2.26.0->manim<0.18.0,>=0.17.3->manim-physics) (3.1.0)
Requirement already satisfied: idna<4,>=2.5 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from requests<3.0.0,>=2.26.0->manim<0.18.0,>=0.17.3->manim-physics) (3.4)
Requirement already satisfied: urllib3<3,>=1.21.1 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from requests<3.0.0,>=2.26.0->manim<0.18.0,>=0.17.3->manim-physics) (2.0.3)
Requirement already satisfied: certifi>=2017.4.17 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from requests<3.0.0,>=2.26.0->manim<0.18.0,>=0.17.3->manim-physics) (2023.5.7)
Requirement already satisfied: markdown-it-py>=2.2.0 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from rich!=12.0.0,>=6.0->manim<0.18.0,>=0.17.3->manim-physics) (3.0.0)
Requirement already satisfied: mdurl~=0.1 in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from markdown-it-py>=2.2.0->rich!=12.0.0,>=6.0->manim<0.18.0,>=0.17.3->manim-physics) (0.1.2)
Requirement already satisfied: multipledispatch in /home/docs/checkouts/readthedocs.org/user_builds/flyingframes/envs/latest/lib/python3.11/site-packages (from pyrr<1,>=0.10.3->moderngl-window<3.0.0,>=2.3.0->manim<0.18.0,>=0.17.3->manim-physics) (0.6.0)
Requirement already satisfied: six in /home/docs/.asdf/installs/python/3.11.0/lib/python3.11/site-packages (from multipledispatch->pyrr<1,>=0.10.3->moderngl-window<3.0.0,>=2.3.0->manim<0.18.0,>=0.17.3->manim-physics) (1.16.0)
Installing collected packages: Shapely, pycparser, cffi, pymunk, manim-physics
Successfully installed Shapely-1.8.5.post1 cffi-1.15.1 manim-physics-0.3.0 pycparser-2.21 pymunk-6.5.0
[18]:
%%manim -v WARNING  --progress_bar None  -qm --disable_caching Example

from manim_physics import *

class Example(SpaceScene):
    def construct(self):
        circle = Dot(radius=1).shift(1.5*LEFT+3*UP)
        rect = Square(color=YELLOW, fill_opacity=1)
        ground = Line([-4, -3.5, 0], [4, -3.5, 0])
        wall1 = Line([-4, -3.5, 0], [-4, 3.5, 0])
        wall2 = Line([4, -3.5, 0], [4, 3.5, 0])
        walls = VGroup(ground, wall1, wall2)
        self.add(walls)
        self.add(rect, circle)
        self.make_rigid_body(rect, circle)
        self.make_static_body(walls)
        self.wait(5)