1. Введение: Зачем вообще кодить видео?
Если вы хоть раз видели ролики на YouTube-канале 3Blue1Brown, вы знаете этот стиль: плавные трансформации фигур, «живые» формулы и графики, которые строятся сами собой. Многие думают, что это результат адского ручного труда моушн-дизайнера. На самом деле — это чистый Python.
Библиотека называется Manim. И давайте сразу определимся: если вам нужно смонтировать влог из отпуска, закрывайте статью, Manim вам не нужен. Но если вы хотите визуализировать структуры данных, алгоритмы или физмат-модели, классические видеоредакторы (After Effects, Premiere) становятся проблемой.
Попытка построить динамический график функции или анимировать сортировку массива мышкой — это часы возни с кейфреймами (keyframe) и ручным выравниванием. Любая правка в логике заставляет переделывать всё с нуля.
Manim предлагает другой подход — Programmatic Animation:
Абсолютная точность: Всё описывается математически. Если нужен сдвиг на вектор
(2, 0, 0), он будет идеальным.Реюзабельность: Видео — это код. Его можно закоммитить в Git, отрефакторить и использовать куски в других проектах.
Массовость: Нужно изменить цвет тысячи объектов? Вы меняете одну переменную в цикле
for, а не кликаете по каждому объекту на таймлайне.
По сути, мы меняем монтажный стол на IDE. Для тех, кому проще написать скрипт, чем двигать ползунки, это глоток свежего воздуха.
2. Подготовка почвы: Manim Community vs ManimGL
Прежде чем писать pip install, нужно прояснить момент, на котором спотыкаются 90% новичков. Существует две основные версии библиотеки, и они несовместимы между собой.
-
ManimGL (manimlib): Оригинальная версия от Гранта Сандерсона (автора 3Blue1Brown). Работает на OpenGL.
Плюсы: Очень быстрый рендеринг (GPU), возможность интерактива в реальном времени.
Минусы: Написана «под себя», слабая документация, нестабильна, сложно настраивается на Windows.
-
Manim Community (manim): Форк, поддерживаемый сообществом разработчиков.
Плюсы: Стабильные ежемесячные релизы, отличная документация, кроссплатформенность, плагины.
Минусы: Рендерится на CPU (Cairo), поэтому медленнее на сложных сценах.
Вердикт: Для работы используем Manim Community. Это стандарт де-факто для всех, кто не является Грантом Сандерсоном. В статье мы работаем именно с ней.
Зависимости (System Dependencies)
Manim — это не просто Python-пакет, это обертка над системными инструментами. Без них магии не будет:
FFmpeg: Критически важен. Python гене��ирует кадры (картинки), а FFmpeg склеивает их в MP4. Он должен быть установлен в системе и прописан в переменных среды (
PATH).LaTeX: Нужен для рендеринга красивых математических формул. Если у вас в системе нет TeX-дистрибутива, Manim будет падать при попытке создать объект
MathTex.
Установка
Когда системные зависимости на месте, ставим саму библиотеку. Обратите внимание на имя пакета:
# Ставит Community версию (то, что нам нужно)
pip install manim
# НЕ перепутайте с manimlib (это версия 3b1b)
# pip install manimlib — ЭТО НАМ НЕ НУЖНО
Проверяем, что всё взлетело:
manim --version
Если видите номер версии (например, Manim Community v0.19.1), окружение готово.
3. Анатомия сцены: Hello World
В Manim единица контента — это класс, наследуемый от Scene. Внутри него есть метод construct(), который работает как main() в C-подобных языках. Всё, что написано внутри construct, будет выполнено и отрендерено.
Минимально рабочий скрипт выглядит так (сохраните как scene.py):
from manim import *
class HelloWorld(Scene):
def construct(self):
# 1. Создаем Mobject (Mathematical Object)
box = Square()
box.set_fill(BLUE, opacity=0.5) # Настройка свойств
# 2. Добавляем объект на сцену
self.add(box)
Разбор ключевых компонентов:
from manim import *: Обычноimport *— это дурной тон (PEP8 не одобряет), но в контексте Manim это стандарт. Библиотека экспортирует сотни классов (цвета, фигуры, константы), и импортировать их поштучно — мучение.Mobject(Mathematical Object): Базовый класс для всего, что отображается на экране. Геометрия (Circle,Line), текст (Text,Tex), графики — всё это наследники Mobject.-
Координатная система: Центр экрана — это
(0, 0, 0).Высота кадра по умолчанию: 8 единиц (от -4 до +4 по Y).
Ширина: завист от соотношения сторон (при 16:9 это ~14.22 единицы, от -7.11 до +7.11 по X).
Поэтому
Square()без аргументов создается ровно в центре.
Позиционирование
Вместо того чтобы высчитывать координаты вручную (x=3.5, y=-2), в Manim принят относительный подход.
circle = Circle()
square = Square()
# Сдвиг относительно центра или текущей позиции
circle.shift(LEFT * 2) # Сдвинуть влево на 2 единицы
square.next_to(circle, RIGHT, buff=0.5) # Поставить справа от круга с отступом 0.5
Запуск рендера
Чтобы превратить этот код в видео (или картинку), идем в терминал:
manim -pql scene.py HelloWorld
-p(preview): автоматически открыть файл после рендера.-q(quality): флаг качества.l— low (480p, быстро),h— high (1080p),k— 4k.scene.py: имя файла.HelloWorld: имя класса сцены.

Результатом выполнения кода выше будет статичная картинка с синим квадратом. Чтобы он задвигался, нам нужны анимации, о которых в следующем пункте.
4. Основы магии: Анимация и Трансформация
Если self.add() просто шлепает объект на кадр, то метод self.play() запускает генерацию кадров видео. Именно он отвечает за интерполяцию состояний от начала до конца действия.
Базовая логика
В метод play передается экземпляр анимации. Библиотека блокирует выполнение скрипта на время этой анимации (по умолчанию 1 секунда), рендерит нужное количество кадров и переходит к следующей строчке.
def construct(self):
square = Square()
# Рисует контуры квадрата (Create — самая частая анимация появления)
self.play(Create(square))
# Пауза на 1 секунду. ВАЖНО: time.sleep() здесь не работает!
# self.wait() генерирует статические кадры.
self.wait(1.0)

Трансформации (The Killer Feature)
То, ради чего используют Manim — это Transform. Библиотека берет векторные точки первого объекта и плавно перемещает их в координаты точек второго объекта.
Это позволяет делать морфинг чего угодно во что угодно: буквы в цифру, квадрата в звезду, графика в прямую линию.
circle = Circle()
circle.set_fill(PINK, opacity=0.5)
# Квадрат плавно превращается в Круг
self.play(Transform(square, circle))

Важный нюанс архитектуры:
Метод Transform(A, B) модифицирует объект A, заставляя его выглядеть как B. Объект B при этом на сцену не добавляется, он служит лишь целевым шаблоном.
Если вам нужно, чтобы в итоге на сцене остался именно объект B (например, чтобы потом работать с его методами), используйте ReplacementTransform(A, B).
Синтаксис .animate
Для простых изменений свойств (сдвинуть, перекрасить, повернуть) не обязательно создавать целевой объект вручную. У каждого Mobject есть свойство .animate.
# Вместо создания нового квадрата в другом месте:
# self.play(square.animate.shift(RIGHT * 3).rotate(PI/4))
# Также можно управлять скоростью через run_time
self.play(
square.animate.set_color(RED),
run_time=2.0
)

Итоговый пайплайн анимации:
Creation: Появление (
Create,FadeIn,Write,DrawBorderThenFill).Mutation: Изменение (
Transform,.animate).Destruction: Исчезновение (
Uncreate,FadeOut,ShrinkToCenter).
Всё это комбинируется последовательно или параллельно (через запятую внутри одного play), давая полный контроль над таймингом видео.
5. Главная фишка: LaTeX и Формулы
Если вы пробовали вставить красивое уравнение в Adobe Premiere или DaVinci Resolve, вы знаете эту боль: нужно идти в онлайн-редактор LaTeX, генерировать PNG с прозрачным фоном, скачивать, вставлять на таймлайн. Если нашли ошибку в формуле — повторяем цикл заново.
Manim был рожден математиком для математики, поэтому поддержка LaTeX здесь нативная.
Как это работает
Вы пишете строку в синтаксисе TeX, Manim под капотом стучится в системный дистрибутив, генерирует SVG-вектор и превращает его в набор кривых Безье. Для нас это значит одно: формула — это не картинка, это геометрия. Её можно гнуть, перекрашивать по частям и трансформировать.
Используем класс MathTex:
# Обязательно используйте r-строки (raw strings),
# иначе Python сойдет с ума от количества бэкслешей
equation = MathTex(
r"e^{i\pi} + 1 = 0",
font_size=96
)
self.play(Write(equation))

разделения (Substrings)
Самая мощная фича — доступ к отдельным символам формулы. Поскольку Manim видит формулу как массив векторных контуров, вы можете обратиться к конкретному символу по индексу, как в списке Python.
Но высчитывать индекс символа «x» в длинном уравнении неудобно. Лучшая практика — разбивать формулу на части при создании:
# Передаем части формулы отдельными строками
eq = MathTex("a^2", "+", "b^2", "=", "c^2")
# Теперь eq — это VGroup (группа векторов) из 5 элементов.
# Мы можем обращаться к ним по отдельности:
# Перекрасим "a^2" в синий
eq[0].set_color(BLUE)
# Перекрасим "b^2" в желтый
eq[2].set_color(YELLOW)
self.play(Write(eq))
# Анимация акцента: масштабируем "c^2"
self.play(
eq[4].animate.scale(1.5).set_color(RED)
)

TransformMatchingTex
Для создания тех самых видео, где одна формула перетекает в другую с сохранением общих символов (например, сокращение дроби, где одинаковые x перелетают и исчезают), используется TransformMatchingTex.
Это работает почти автоматически: Manim анализирует исходный и целевой TeX-код, находит одинаковые куски и плавно перемещает их на новые места, а всё, что не совпало — фейдит. Это выглядит профессионально, а пишется в две строчки.
6. Практический кейс: Визуализация графика и ValueTracker
Двигать квадратики — это весело, но давайте сделаем что-то полезное для Data Science или физики. Построим график функции (синусоиды) и пустим по нему точку, которая будет бежать в реальном времени и показывать свои текущие координаты.
Здесь нам понадобятся три важные концепции:
Axes: Система координат. Manim умеет сам рисовать оси, расставлять засечки и цифры.c2p(Coordinates to Point): Метод, который переводит математические координаты (x=2, y=5) в пиксельные координаты на экране.ValueTracker: Это невидимый объект, который хранит число. Мы анимируем изменение этого числа, а все остальные объекты (точка, текст) «слушают» его и обновляются автоматически.
Задача
Нарисовать синусоиду и заставить точку пробежать по ней от до
, отображая значение
над собой.
Код примера (сохраните как graph_scene.py):
from manim import *
import numpy as np
class PlottingStats(Scene):
def construct(self):
# 1. Настраиваем оси
# x_range=[min, max, step]
axes = Axes(
x_range=[-4, 4, 1],
y_range=[-1.5, 1.5, 0.5],
x_length=8,
y_length=5,
axis_config={"color": GREY},
tips=False # Убрать стрелочки на концах осей
).add_coordinates()
# 2. Строим график
# axes.plot принимает лямбда-функцию
sin_curve = axes.plot(lambda x: np.sin(x), color=BLUE)
sin_label = MathTex("y = \\sin(x)").next_to(sin_curve, UP + RIGHT)
# 3. Магия ValueTracker
# Создаем "хранилище" значения X. Стартуем с -3
t = ValueTracker(-3)
# 4. Создаем точку, которая зависит от t
# always_redraw пересоздает объект каждый кадр
dot = always_redraw(lambda: Dot(
# c2p берет (x, y) и возвращает координаты на экране
point=axes.c2p(t.get_value(), np.sin(t.get_value())),
color=RED
))
# 5. Динамический текст (показания Y)
# ИСПРАВЛЕНИЕ: Используем параметр number (или позиционный аргумент),
# параметра num в DecimalNumber нет.
number_label = always_redraw(lambda: DecimalNumber(
number=np.sin(t.get_value()),
num_decimal_places=2,
color=RED
).next_to(dot, UP))
self.play(Create(axes), Create(sin_curve), Write(sin_label))
self.add(dot, number_label)
# 6. Запуск анимации
# Мы анимируем ТОЛЬКО ValueTracker.
# Точка и цифра обновятся сами благодаря always_redraw.
self.play(
t.animate.set_value(3),
run_time=4,
rate_func=linear
)
self.wait()

Разбор механики
Ключевая строка здесь: dot = always_redraw(lambda: ... ).
Функция always_redraw говорит Manim: "Вызывай эту лямбду перед отрисовкой каждого кадра видео".
Каждый кадр Manim смотрит на текущее значение
t(которое плавно меняется от -3 до 3).Вычисляет новый
np.sin(t).Строит новую точку и обновляет цифру в
DecimalNumber.
Без этой техники вам пришлось бы вручную рассчитывать тысячи координат. С ValueTracker вы управляете одной переменной, а вся сцена реагирует на её изменение.
7. Тонкости рендеринга и CLI
Код написан, но результат пока существует только в вашей голове. Чтобы превратить его в пиксели, нужно освоить командную строку (CLI). Manim имеет богатую систему флагов, которые определяют раз��ешение, фреймрейт и формат.
Базовая команда выглядит так:
manim [флаги] [имя_файла.py] [ИмяКлассаСцены]
Управление качеством (-q)
Самая частая ошибка новичка — пытаться рендерить сразу в высоком качестве. Manim работает на CPU (по большей части), и рендер 60 fps в 4K может занять минуты даже для простой сцены.
Используйте флаг -q (quality) с одной из букв:
-ql(Low): 480p, 15 fps. Используйте для разработки. Рендерится мгновенно, позволяет быстро оценить анимацию.-qm(Medium): 720p, 30 fps. Хороший компромисс для черновиков.-qh(High): 1080p, 60 fps. Стандарт для YouTube. Ставьте только когда код полностью отлажен.-qk(4K): 2160p, 60 fps. Для перфекционистов.
Полезные флаги
-p(Preview): После рендера сразу открывает видео в плеере по умолчанию. Без этого флага вам придется каждый раз лезть в папкуmedia/videos/....-t(Transparent): Рендерит видео с альфа-каналом (прозрачным фоном). Критически важно, если вы делаете анимацию для наложения поверх живого видео в Premiere или DaVinci. Формат файла будет.mov(ProRes).--format gif: Сохраняет результат не в MP4, а в GIF. Удобно для статей на Хабр или GitHub Readme.
Конфигурация (manim.cfg)
Чтобы не писать каждый раз manim -pqh --disable_caching ..., можно создать в папке с проектом файл manim.cfg. Библиотека подхватит настройки автоматически.
Пример конфига:
[CLI]
frame_rate = 60
pixel_height = 1080
pixel_width = 1920
background_color = BLACK
background_opacity = 1
scene_names = DefaultScene
Почему так долго?
Если рендер зависает на э��апе Latex error или просто долго думает перед началом:
LaTeX: Каждая формула компилируется через системный TeX. Это медленная операция, но Manim кэширует результаты. Второй запуск будет быстрее.
Кэш: Manim сохраняет промежуточные анимации. Если вы поменяли цвет одного круга в конце сцены, он не будет пересчитывать начало. Но иногда кэш ломается. Если видите странные глитчи — удалите папку
media/и пересоберите проект.
Итоговая рекомендация:
Пишите код с флагом -pql.
Финальный билд делайте с -pqh.
Для интеграции с монтажом используйте -t.
8. Заключение и «Куда копать дальше»
Manim — это не «убийца» After Effects. Пытаться монтировать в нем блог или клип — изощренная форма мазохизма. Но как только задача касается точной геометрии, математических абстракций или алгоритмов, Manim перестает быть просто библиотекой и становится супероружием.
Вам больше не нужно выравнивать пиксели мышкой. Вы описываете логику поведения, а рендеринг — это просто побочный эффект выполнения кода. Это дает вам:
Контроль версий: Ваше видео лежит в Git. Вы можете сделать ветку, поэкспериментировать с цветами и откатиться назад.
Масштабируемость: Написать скрипт для сортировки 10 элементов так же сложно, как для 1000.
Переиспользование: Создав однажды красивую визуализацию нейросети, вы будете использовать этот класс во всех будущих презентациях.
Что мы не затронули (но стоит изучить)
В рамках одной статьи невозможно охватить всё. Вот ключевые темы для самостоятельного изучения:
3D Scenes (
ThreeDScene): Вращение камеры, оси Z, поверхности. Выглядит эффектно, но требует хорошего пространственного мышления.Graph Theory: В Manim встроен мощный движок для отрисовки графов и деревьев (Dijkstra, BFS/DFS визуализируются на раз-два).
Звук: Методы
self.add_sound()для синхронизации аудиодорожки с анимацией.
Анонсы новых статей, полезные материалы, а так же если в процессе у вас возникнут сложности, обсудить их или задать вопрос по этой статье можно в моём Telegram-сообществе. Смело заходите, если что-то пойдет не так, — постараемся разобраться вместе.
Полезные ссылки
Документация Manim Community: Она отлично структурирована и полна примеров.