Mit Manim programmieren Sie mit wenigen Zeilen Python-Code Videosequenzen, die mathematische Problemstellungen wissenschaftlich präzise darstellen.
Eine präzise Beschreibung eines komplizierten Sachverhalts fällt häufig schwer. Purer Text geht zwar immer, erfordert vom Leser aber häufig viel Vorstellungskraft. Eine gut aufeinander abgestimmte Kombination aus Text und Bildern erleichtert es, einen Sachverhalt zu verstehen. Filme oder Videosequenzen stehen noch eine Stufe darüber.
Allerdings erfordert das Aufnehmen, Zurechtschneiden und Nachbearbeiten von Filmmaterial viel Zeit und Wissen um die Materie. Die Fähigkeit, grafische Objekte und deren Eigenschaften festzulegen und mithilfe des Computers berechnen und zeichnen zu lassen, kommt seit Längerem zum Einsatz und ordnet sich in der Informatik unter der Kategorie Computergrafik ein. Als Hilfsmittel dafür dient beispielsweise die Bibliothek OpenGL oder die freie Variante des OpenGL Utility Toolkits FreeGlut [1].
Es lassen sich nicht nur einzelne Grafikobjekte “programmieren”, das funktioniert auch für komplette Videos. Die Grafikobjekte fassen Sie dann zu Sequenzen aus einzelnen Objekten zusammen, die mithilfe von Bildeffekten ineinander übergehen. Genau dieser Idee folgt Manim [2], das es zum Ziel erklärt, mathematische Zusammenhänge präzise darzustellen.
Basierend auf der Programmiersprache Python kombiniert Manim die Grafikbibliothek Cairo, das Aufnahmeprogramm Ffmpeg, das Sound-Werkzeug Sox und das Textverarbeitungssystem LaTeX miteinander. Sox und LaTeX dienen optional zum Erzeugen akustischer Zusatzeffekte sowie zur Ausgabe mathematischer Formeln. Als Ergebnis liefert die Software eine MP4-Videodatei.
Wer, weshalb, warum
Der Name Manim kürzt die beiden Worte “mathematical animations” ab und beschreibt die Idee des Gesamtprojekts, mathematische Animationen darzustellen. Die Software erstellte der amerikanische Mathematiker und Entwickler Grant Sanderson, der sie auch für seine mathematischen Erklärvideos auf seinem Wissenschaftskanal 3blue1brown verwendet [3]. Von der Software gibt es auch eine Community-Variante, die zwar auf dem Code von Sanderson aufbaut, den die Community aber separat pflegt [4]. Beide Varianten von Manim stehen auf Github zum Herunterladen bereit [5].
Die Software besteht aus zwei Teilen: dem Programmcode zum Erzeugen der Visualisierungseffekte der Videos auf 3blue1brown sowie allgemeinem Code. Ersterer ist proprietär lizenziert (die Rechte liegen bei 3blue1brown), Letzterer steht unter einer MIT-Lizenz. Das gilt für beide Manim-Varianten. Für diesen Artikel benutzt der Autor die Originalvariante.
Installation
Derzeit existieren noch keine Manim-Pakete für gängige Linux-Distributionen, weswegen ein wenig Handarbeit zum Übersetzen und Installieren anfällt. Als Abhängigkeiten setzt Manim neben Python ab Version 3.7 und der Python-Paketverwaltung Pip einige Entwicklungsbibliotheken sowie Ffmpeg, Sox, Git, und LaTeX voraus. Letzteres ist optional, da diese Komponente etwa 2,5 GByte Platz benötigt, die Ihnen eventuell nicht zur Verfügung steht.
Als Basis diente dem Autor Debian GNU/Linux 10.6. Sollten sich oben genannte Software-Pakete noch nicht auf Ihrem System befinden, holen Sie das über Ihre Paketverwaltung nach (Listing 1, Zeile 1).
Listing 1
Installation und erster Start
# apt-get install python3.7 python3-pip ffmpeg sox libcairo2-dev libjpeg-dev libgif-dev git # apt-get install texlive-full # apt-get install texlive-latex-base texlive-latex-extra texlive-fonts-extra $ git clone https://github.com/3b1b/manim.git $ cd manim/ $ python3 -m pip install -r requirements.txt $ python3 manim.py example_scenes.py SquareToCircle -lp
Für LaTeX benötigen Sie entweder das Paket texlive-full oder die drei Pakete texlive-latex-base, texlive-latex-extra und texlive-fonts-extra. Die Vollinstallation erledigt der Aufruf aus der zweiten Zeile von Listing 1, die der drei Pakete Zeile 3.
Zeile 4 bezieht die Manim-Bibliothek aus dem Github-Repository. Dabei entsteht im aktuellen Verzeichnis der Ordner manim/, in den Sie anschließend wechseln (Zeile 5). Weitere eventuell noch fehlende Bibliotheken ergänzen Sie danach mit dem Kommando aus Zeile 6. Je nach Hardware-Ausstattung nimmt dieser Schritt einige Zeit in Anspruch, da er den aktuellen Quellcode der Bibliotheken bezieht und ihn für Ihr System kompiliert.
Zu guter Letzt erzeugen Sie mit dem Befehl aus der letzten Zeile von Listing 1 Ihr erstes Video. Dazu benutzen Sie das mitgelieferte Beispielskript example-scenes.py. Der erste beim Aufruf angegebene Parameter benennt die Manim-Bibliothek als lokale Python-Datei. Danach folgen das Beispielskript mit den Animationen und als dritter Parameter der Name der Klasse im Beispielskript, dessen Animationen Manim ausführen soll. Gleichzeitig dient er als Name der Ausgabedatei, die automatisch die Erweiterung .mp4 erhält.
Am Ende folgen zwei Schalter: -l (“lower”) veranlasst das Rendern des Videos in etwas geringerer Qualität von 480p15 statt 1440p60. -p (“preview”) sorgt für das sofortige Abspielen der erzeugten Videodatei (Abbildung 1).
In der Grundeinstellung speichert Manim die erzeugten Dateien unter ./media/videos/. Diesen Pfad passen Sie über die Umgebungsvariable MEDIA_DIR an Ihre Wünsche an.
Animationen verstehen
Der Quellcode für das Video aus Abbildung 1 umfasst nur wenige Zeilen. Er besteht aus der Python-Klasse SquareToCircle(), die sich von der internen Python-Klasse Scene() ableitet (Listing 2, Zeile 1). SquareToCircle() enthält lediglich eine Methode namens construct() (Zeile 2).
Die Zeilen 3 und 4 definieren ein Manim-Objekt namens circle vom Typ Circle() und square vom Typ Square(). Die Zeilen 5 und 6 initialisieren zuerst eine Rechtsdrehung des Quadrats über die Methode rotate() und danach eine Drehung um den angegebenen Winkel. Der Code aus Zeile 7 färbt den Kreis rosa ein, mit einer Deckkraft von 50 Prozent.
Die Zeilen 9 bis 11 enthalten drei Animationen mithilfe der Methode play(). Der Aufruf von ShowCreation(square) erzeugt das Quadrat, Transform(square, circle) rendert die stufenweise Umwandlung des Quadrats in einen rosafarbenen Kreis, und FadeOut(square) blendet diesen langsam aus.
Listing 2
Beispielskript
class SquareToCircle(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))
Die Tabelle “Geometrische Objekte” listet auszugsweise auf, welche geometrischen Objekte Manim derzeit unterstützt. Die Zusammenstellung basiert auf der Analyse des Quellcodes, da die Dokumentation die Informationen derzeit nicht enthält. Die Tabelle “Unterstützte Animationen” stellt auszugsweise zusammen, welche Animationen Manim unterstützt. Hier ließ sich auf die bestehende Dokumentation zurückgreifen.
|
Objekt |
Klasse |
|---|---|
|
Bogen |
|
|
Pfeil |
|
|
Kreis |
|
|
Punkt |
|
|
Ellipse |
|
|
Linie |
|
|
Polygon |
|
|
Dreieck |
|
|
Viereck |
|
|
Animation |
Methode |
|---|---|
|
Ein- und Ausblenden |
|
|
Vergrößern |
|
|
Umwandeln und Drehen |
|
|
Rotieren |
|
Darüber hinaus bringt Manim die Möglichkeit mit, die Kameraposition zu wechseln. Das benötigen Sie, wenn Sie Teile des Gesamtbilds durch Hinein- und Herauszoomen hervorheben oder eine Bewegung entlang einer Achse visualisieren möchten.
Manim in der Praxis
Die beigefügten Beispiele eignen sich gut zum Verständnis, wie die einzelnen Methoden zusammenspielen. Die Dokumentation weist allerdings noch Lücken auf, die den Einstieg in die Materie erschweren. Als hilfreich erweisen sich daher auch Blog-Einträge [6], die das Vorgehen für spezifische Anwendungsfälle in Form einer Schritt-für-Schritt-Anleitung erklären [7]. Im Folgenden demonstrieren wir anhand zweier überschaubarer Beispiele den Funktionsumfang von Manim.
In Listing 3 definieren die Zeilen 3 bis 6 eine mathematische Formel in LaTeX-Schreibweise. Die Zeilen 7 und 8 legen zwei Rechtecke fest und ordnen sie der zweiten respektive vierten Komponente der Formel zu. Zunächst gibt Zeile 9 die Formel vollständig aus. Zeile 10 ergänzt sie um das erste Rechteck, danach sorgt die Methode wait() für eine Pause. Zeile 12 ersetzt das Rechteck 1 durch das Rechteck 2. Manim ergänzt dazu eine Bewegung: Das Rechteck gleitet nach rechts ans Ende der Formel. In Zeile 13 folgt wiederum eine kurze Pause, bevor das Video endet.
Listing 3
box.py
class MoveFrameBox(Scene):
def construct(self):
text=MathTex(
"\\frac{d}{dx}f(x)g(x)=","f(x)\\frac{d}{dx}g(x)","+",
"g(x)\\frac{d}{dx}f(x)"
)
framebox1 = SurroundingRectangle(text[1], buff = .1)
framebox2 = SurroundingRectangle(text[3], buff = .1)
self.play(Write(text))
self.play(ShowCreation(framebox1),)
self.wait()
self.play(ReplacementTransform(framebox1,framebox2),)
self.wait()
Um den Effekt zu sehen, speichern Sie die Klasse in Ihrem Manim-Verzeichnis als Python-Skript box.py ab. Das Rendern des Videos (Abbildung 2) erledigen Sie mit dem Befehl aus der ersten Zeile von Listing 4.
Listing 4
Beispiele rendern
$ python3 manim.py box.py MoveFrameBox -pl $ python3 manim.py funktion.py SinusPlot -pl
Das letzte Beispiel erzeugt den Graphen der Sinus-Funktion und plottet ihn in einem kartesischen Koordinatensystem (Listing 5). Dazu kommt eine Datenstruktur namens CONFIG ins Spiel, über die Sie das Aussehen des Koordinatensystems festlegen. Hier läuft die y-Achse von 0 bis 100 (Zeile 3 und 4). Die x- und y-Achse bekommen alle 10 Einheiten einen senkrechten beziehungsweise waagerechten Strich zur Markierung (Zeile 5 und 6). Nur die y-Achse enthält auch die dazugehörigen Werte.
Listing 5
funktion.py
class SinusPlot(GraphScene):
CONFIG = {
"y_min": 0,
"y_max": 100,
"y_axis_config": {"tick_frequency": 10},
"y_labeled_nums": np.arange(0, 100, 10)
}
def construct(self):
self.setup_axes()
dot = Dot().move_to(self.coords_to_point(PI / 2, 20))
func_graph = self.get_graph(lambda x: 20 * np.sin(x))
self.add(dot, func_graph)
Der Code ab Zeile 9 gibt zunächst die beiden Achsen mithilfe der Methode setup_axes() aus (Zeile 10). Zeile 11 erzeugt einen Punkt, den sie mithilfe der Methode move_to() an die Position (Pi/2,**20) legt. Zeile 12 definiert via get_graph() die Anweisung zur Sinus-Funktion, Zeile 13 gibt den Punkt und die Sinus-Funktion aus.
Sie speichern diese Klasse wieder in Ihrem Manim-Verzeichnis als Python-Skript ab, das diesmal funktion.py heißt. Das Rendern des Videos lösen Sie mit dem Kommando aus der letzten Zeile von Listing 4 aus (Abbildung 3).
Fazit
Manim erweist sich als perfektes Werkzeug zum Darstellen mathematischer Zusammenhänge als Video. Es lässt sich vergleichsweise einfach bedienen und liefert Ergebnisse, die auf herkömmlichem Weg erheblich mehr Aufwand verursachen würden. (tle/jlu)
Der Autor
Frank Hofmann arbeitet zumeist von unterwegs, bevorzugt aus Berlin, Genf und Kapstadt als Entwickler, Trainer und Autor. Er gehört zu den Verfassern des Debian-Paketmanagement-Buchs.
Infos
-
FreeGlut: http://freeglut.sourceforge.net/
-
3blue1brown: https://www.3blue1brown.com/
-
Manim, Community-Webseite: https://docs.manim.community/en/v0.1.0/index.html
-
Manim-Community-Version: https://github.com/ManimCommunity/manim/
-
“Creating math animations in Python with Manim”: https://gilberttanner.com/blog/creating-math-animations-in-python-with-manim
-
“Getting Started Animating with manim and Python 3.7”: https://talkingphysics.wordpress.com/2019/01/08/getting-started-animating-with-manim-and-python-3-7/








