Manim Community Edition — Prise en main
Guide concret pour installer, structurer et rendre une animation Manim CE. Ce cheatsheet couvre l’installation, la structure de base d’une scène, trois exemples copiables, et le rendu headless en CLI.
Installation
# Dépendance système indispensable
sudo apt-get install ffmpeg cmake
# Manim CE via pip (version recommandée ≥ 0.17)
pip install manim
# Vérification
manim --versionPitfall : sans
ffmpeginstallé au niveau système, Manim rend la scène sans erreur visible mais ne produit aucun fichier vidéo. Vérifier avecffmpeg -versionavant toute tentative de rendu.
Sur macOS, remplacer sudo apt-get install ffmpeg cmake par
brew install ffmpeg cmake.
Structure minimale d’une scène
Tout projet Manim repose sur trois ingrédients :
- Une classe qui hérite de
Scene— c’est le point d’entrée. - La méthode
construct()— le corps de la scène. - Un rendu CLI —
manimtraduit le code en vidéo via ffmpeg.
Exemple de squelette minimum (main.py) :
from manim import *
class MaScene(Scene):
def construct(self):
texte = Text("Bonjour le monde", font_size=48)
self.play(Write(texte))
self.wait(1.0)# Rendu rapide (brouillon 480p, 15 fps)
manim -ql main.py MaScene
# Rendu production (1080p, 60 fps)
manim -qh main.py MaScene
# Render en fond (headless, pas d'affichage graphique)
manim -pqh main.py MaSceneLe flag -p ouvre un aperçu vidéo à la fin. Retirer -p pour un rendu
strictement headless (serveur, CI, conteneur Docker).
Exemple 1 — Texte animé
from manim import *
class TexteAnime(Scene):
def construct(self):
titre = Text("Formation Manim CE", font_size=48, color=BLUE)
sous = Text("Guide pratique", font_size=28, color=GRAY)
sous.next_to(titre, DOWN, buff=0.4)
self.play(Write(titre))
self.play(FadeIn(sous, shift=UP))
self.wait(1.5)
# Remplacement progressif
nouveau = Text("Premier rendu réussi !", font_size=36, color=GREEN)
self.play(ReplacementTransform(titre, nouveau))
self.wait(1.0)
self.play(FadeOut(Group(*self.mobjects)))Points clés :
next_to()positionne un mobject relativement à un autre.ReplacementTransformfait morpher un objet en un autre.FadeOut(Group(*self.mobjects))nettoie la scène en un appel.
Exemple 2 — Diagramme de vecteurs
from manim import *
class Vecteurs(Scene):
def construct(self):
self.camera.background_color = "#1C1C1C"
# Axes
ax = Axes(
x_range=[-4, 4], y_range=[-3, 3],
x_length=8, y_length=5,
axis_config={"include_numbers": True}
)
# Vecteurs (flèches)
v1 = Arrow(
ORIGIN, np.array([2, 1.5, 0]),
buff=0, color=BLUE, stroke_width=3
)
v2 = Arrow(
ORIGIN, np.array([-1, 2.5, 0]),
buff=0, color=GREEN, stroke_width=3
)
# Labels
l1 = MathTex(r"\vec{v}", color=BLUE).next_to(v1, UR, buff=0.2)
l2 = MathTex(r"\vec{w}", color=GREEN).next_to(v2, UL, buff=0.2)
# Somme visuelle (parallélogramme)
somme = Arrow(
ORIGIN, np.array([1, 4, 0]),
buff=0, color=YELLOW, stroke_width=3
)
self.play(Create(ax), run_time=1.5)
self.play(Create(v1), Write(l1))
self.play(Create(v2), Write(l2))
self.play(Create(somme), run_time=1.5)
self.wait(2.0)
self.play(FadeOut(Group(*self.mobjects)))Points clés :
np.array([x, y, 0])pour les positions 3D (le0est la coordonnée Z).Arrowaccepte directement des pointeurs source/destination.MathTexutilise LaTeX — toujours une chaîne bruter"..."pour les expressions LaTeX (contre-exemple :MathTex("\\\\frac")au lieu deMathTex("\\frac")qui génère un backslash non reconnu).
Exemple 3 — Graphique de fonctions
from manim import *
class GraphiqueFonction(Scene):
def construct(self):
self.camera.background_color = "#1C1C1C"
ax = Axes(
x_range=[-2 * PI, 2 * PI], y_range=[-1.5, 1.5],
x_length=10, axis_config={"include_numbers": True}
)
labels = ax.get_axis_labels(
MathTex("x"), MathTex("\\\\sin(x)")
)
# Courbe sin(x)
courbe = ax.plot(lambda x: np.sin(x), color=BLUE)
# Repère de l'axe + label + courbe
self.play(Create(ax), Create(labels), run_time=1.5)
self.play(Create(courbe), run_time=2)
self.wait(1.5)
self.play(FadeOut(Group(*self.mobjects)))Points clés :
ax.plot(f)trace la courbe def(x)dans les limites de l’axe.get_axis_labels()attachent automatiquement les labels aux axes.- PI doit être importé depuis
manim(équivalent demath.pi) pour garder la cohérence de rendu avec les repères.
Flags de rendu (raccourci)
| Flag | Signification |
|---|---|
-q | Qualité : l (480p/15fps), m (720p/30fps), h (1080p/60fps), k (4K) |
-p | Aperçu vidéo automatique après rendu |
-s | Exporter en PNG (image statique, pas de vidéo) |
-n | Accélérer en sautant les N premiers frames (ex: -n 2,5 saute les 2 frames initiales et les 5 dernières) |
--format=mp4 | Forcer le format de sortie (par défaut) |
Commande de rendu headless en production :
manim -pqh mon_scene.py MaScene > /dev/null 2>&1Rediriger stdout et stderr pour un rendu propre dans un conteneur ou un pipeline CI.
Rendu multi-scènes en une commande
Plusieurs classes dans le même fichier se rendent d’un coup :
manim -pqh main.py TexteAnime Vecteurs GraphiqueFonctionLes vidéos se trouvent dans :
media/videos/main/1080p60/
├── TexteAnime.mp4
├── Vecteurs.mp4
├── GraphiqueFonction.mp4Liens utiles
- Documentation officielle : https://docs.manim.community
- Galerie d’exemples : https://docs.manim.community/en/stable/examples.html
- Référence API : https://docs.manim.community/en/stable/reference.html
- Issue tracker GitHub : https://github.com/ManimCommunity/manim/issues
Un fichier Python, quelques flags CLI, une vidéo en sortie. Pas d’IDE, pas de template boilerplate.