Manim

Workflow in Bash

manim is the greatest tool for creating scientific illustrations, besides Powerpoint's built-in animation framework. Since I use Linux, I will write this guide for those interested in this pipeline of work.

First things first, let's install entr and vlc. This neat Unix command will re-run the command following it each time the source (main.py) changes. We will actually use cvlc instead of vlc, just so we don't have any annoying interface to worry about.

sudo pacman -S vlc entr

Second of all, let us create a virtual python environment (this is the recommended approach to avoid breaking your system with python packages), activate the environment, and install manim. I recommend opening a bash instance for this one, as the use of commands in any other shells might be different from my approach. We will use boolean AND operator && so all commands are ran after each other (if successful):

bash && python -m venv .venv && source .venv/bin/activate && pip install manim

Whenever you'd like to exit this environment, just type in deactivate.

Now, we are all set to write the Manim python code in main.py, such as:

from manim import *

class CreateCircle(Scene):
    def construct(self):
        circle = Circle()  # This creates a circle
        circle.set_fill(RED, opacity=0.5) # Gives it red color, with an opacity of 0.5
        self.play(Create(circle)) # And this just displays the circle

Now, we will run the most important command of our day:

while true; do find . -name main.py | entr -d sh -c "manim -ql main.py CreateCircle && cvlc --one-instance --play-and-pause ./media/videos/main/480p15/CreateCircle.mp4 > /dev/null 2>&1 &"; done

where:

  • while true runs the process infinitely, so entr never exists
  • find . -name main.py is needed for the piping with entr (to check if main.py is changing)
  • entr -d sh -c runs the full manim command on the aforementioned file (main.py)
  • cvlc --one-instance --play-and-pause ./media/videos/main/480p15/CreateCircle.mp4 > /dev/null 2>&1 &" runs the cvlc command (interface-less VLC) on the class (CreateCircle) which we used in our Python file, and sends the output to /dev/null.

Creating a bash script for easier usage for further occasions:

manimplay () {
    while true; do find . -name $1 | entr -d sh -c "manim -ql $1 $2 && cvlc --one-instance --play-and-pause ./media/videos/main/480p15/$2.mp4 > /dev/null 2>&1 &"; done
}

So if you run manimplay in your terminal, it will expect two (2) arguments:

  • $1 is file name
  • $2 is scene name

This simplifies our long-ass code to:

manimplay main.py CreateCircle

Note however, that you will have to restart your bash instance so you can start using it.

Workflow in Fish shell

Not gonna go over everything yet again, so I'll just paste the function you can copy to your ~/.config/fish/config.fish file:

function manimplay -a file scene
    while true
    find . -name $file | entr -d sh -c "manim -ql $file $scene && cvlc --one-instance --play-and-pause ./media/videos/main/480p15/$scene.mp4 > /dev/null 2>&1 &"
    end
end

And instead of sourcing the activate file like the usual way, you will source it in fish shell via

source .venv/bin/activate.fish