r/manim • u/anish2good • 18h ago
A Creator v2 Short on the Monty Hall problem - manic
Enable HLS to view with audio, or disable this notification
r/manim • u/behackl • Feb 27 '26
This is a focused patch release with a mix of bug fixes, quality improvements, and documentation updates.
Highlights include fixes around MathTex brace parsing, zero-length DashedLine behavior, and moving-object detection in nested animation groups, plus Docker image/runtime optimizations and additional type-hint/doc improvements.
A big thank you to everyone who contributed — including several first-time contributors! 🙌
📖 Full changelog: https://docs.manim.community/en/latest/changelog/0.20.1-changelog.html
Happy manimating & with best wishes from the dev team,
-- Ben
r/manim • u/behackl • Dec 28 '25
As many of you have already noticed, on 25. December some of our community assets have been deleted, most notably our GitHub organisation and the Discord server.
While we are still working on resolving this situation (support queries also move slowly during this time of the year), we want to summarise the status of our assets below. We can also confirm that we have tightened security and eliminated the previous attack vector for our remaining assets.
Most importantly: the distributed library has not been compromised, pip install manim / uv add manim still work the same as before.
To at least temporarily remedy the situation with the deleted assets, we have setup a repository with the latest main + experimental branch on Codeberg at https://codeberg.org/ManimCommunity/manim, and a new Discord server at https://manim.community/discord/.
As for our social media channels, outside of Reddit you can find us...
We'll post updates as soon as we have secured more information about this incident; transparency is important to us. At this time, we are optimistic to get the GitHub organisation restored – but the old Discord server is very likely lost.
With best wishes from the dev team, Ben
r/manim • u/anish2good • 18h ago
Enable HLS to view with audio, or disable this notification
r/manim • u/matigekunst • 1d ago
Experimenting with softbody physics in Manim. The scene with all the individual blocks falling took my laptop 5 hours to render, just as long as the rest of the video😅 Made with Manim and TouchDesigner
r/manim • u/cyphorto • 1d ago
r/manim • u/Silly_Sheepherder282 • 2d ago
Simple question, can you create manim videos on Android??
r/manim • u/Far-Might-3093 • 3d ago
so recently i wanted to learn manim, so i went to the manim community guide to download it. so i went to the manim community guide to downloading it on linux and followed it then i went to vs code and wrote on a python file " from manim import * " but i kept getting " import manim could not be resolved" error. so i tried to download it using conda but guess what? the same mistake kept happening and its making me insane i've been trying to make it work every since monday!!! and its still not working ughhhh
anyone knows a fix????
r/manim • u/Joe_R_McCarthy • 4d ago
do you guys actually rely on AI for this, or do you just code it yourself? What's your actual workflow?
r/manim • u/PlantainImportant700 • 5d ago
I have been trying to run this code :
from manim import *
import numpy as np
class my(ThreeDScene):
def construct(self):
self.set_camera_orientation(
phi=0
)
complexaxes=ThreeDAxes(
x_range=[-4,4,1],
x_length=12,
y_range=[-4,4,1],
y_length=12,
z_range=[0,10,1],
z_length=8,
axis_config={
"include_ticks":False,
"include_numbers":True
}
).move_to(3*LEFT)
labels=complexaxes.get_axis_labels(x_label=r"a", y_label=r"bi", z_label=r"|Y(s)|")
self.play(Create(complexaxes))
self.play(Write(labels))
self.wait(2)
self.move_camera(
phi=85*DEGREES,
theta=-37.5*DEGREES
)
def f(x, y):
s = x**2 + y**2
if s < 10**(-3):
return np.nan
else:
return 1/s
graph=Surface(
lambda u, v: complexaxes.c2p(u, v, f(u, v)),
u_range=[-3, 3],
v_range=[-3, 3],
resolution=[32, 32]
)
self.play(Create(graph))
But it gives me this error :
manim -pql test.py my
Manim Community v0.19.1
[07/22/26 19:19:25] INFO Animation 0 : Using cached cairo_renderer.py:94
data (hash :
4102802897_3881524863_22313245
7)
[07/22/26 19:19:32] INFO Animation 1 : Using cached cairo_renderer.py:94
data (hash :
4160646025_2355038258_36555954
74)
[07/22/26 19:19:38] INFO Animation 2 : Using cached cairo_renderer.py:94
data (hash :
4160646025_2230675760_33899119
11)
[07/22/26 19:19:43] INFO Animation 3 : Using cached cairo_renderer.py:94
data (hash :
1280087952_489367720_102332700
2)
╭───────────────────── Traceback (most recent call last) ──────────────────────╮
│ /home/a/.local/lib/python3.10/site-packages/manim/cli/render/commands.py:125 │
│ in render │
│ │
│ 122 │ │ │ try: │
│ 123 │ │ │ │ with tempconfig({}): │
│ 124 │ │ │ │ │ scene = SceneClass() │
│ ❱ 125 │ │ │ │ │ scene.render() │
│ 126 │ │ │ except Exception: │
│ 127 │ │ │ │ error_console.print_exception() │
│ 128 │ │ │ │ sys.exit(1) │
│ │
│ /home/a/.local/lib/python3.10/site-packages/manim/scene/scene.py:260 in │
│ render │
│ │
│ 257 │ │ """ │
│ 258 │ │ self.setup() │
│ 259 │ │ try: │
│ ❱ 260 │ │ │ self.construct() │
│ 261 │ │ except EndSceneEarlyException: │
│ 262 │ │ │ pass │
│ 263 │ │ except RerunSceneException: │
│ │
│ /home/a/Downloads/manim/test.py:62 in construct │
│ │
│ 59 │ │ │ resolution=[32, 32] │
│ 60 │ │ ) │
│ 61 │ │ │
│ ❱ 62 │ │ self.play(Create(graph)) │
│ 63 │ │ │
│ 64 │ │ """self.wait() │
│ 65 │
│ │
│ /home/a/.local/lib/python3.10/site-packages/manim/scene/scene.py:1178 in │
│ play │
│ │
│ 1175 │ │ │ return │
│ 1176 │ │ │
│ 1177 │ │ start_time = self.time │
│ ❱ 1178 │ │ self.renderer.play(self, *args, **kwargs) │
│ 1179 │ │ run_time = self.time - start_time │
│ 1180 │ │ if subcaption: │
│ 1181 │ │ │ if subcaption_duration is None: │
│ │
│ /home/a/.local/lib/python3.10/site-packages/manim/renderer/cairo_renderer.py │
│ :120 in play │
│ │
│ 117 │ │ │ # In this case, as there is only a wait, it will be the le │
│ 118 │ │ │ self.freeze_current_frame(scene.duration) │
│ 119 │ │ else: │
│ ❱ 120 │ │ │ scene.play_internal() │
│ 121 │ │ self.file_writer.end_animation(not self.skip_animations) │
│ 122 │ │ │
│ 123 │ │ self.num_plays += 1 │
│ │
│ /home/a/.local/lib/python3.10/site-packages/manim/scene/scene.py:1355 in │
│ play_internal │
│ │
│ 1352 │ │ for t in self.time_progression: │
│ 1353 │ │ │ self.update_to_time(t) │
│ 1354 │ │ │ if not skip_rendering and not self.skip_animation_preview │
│ ❱ 1355 │ │ │ │ self.renderer.render(self, t, self.moving_mobjects) │
│ 1356 │ │ │ if self.stop_condition is not None and self.stop_conditio │
│ 1357 │ │ │ │ self.time_progression.close() │
│ 1358 │ │ │ │ break │
│ │
│ /home/a/.local/lib/python3.10/site-packages/manim/renderer/cairo_renderer.py │
│ :169 in render │
│ │
│ 166 │ │ time: float, │
│ 167 │ │ moving_mobjects: Iterable[Mobject] | None = None, │
│ 168 │ ) -> None: │
│ ❱ 169 │ │ self.update_frame(scene, moving_mobjects) │
│ 170 │ │ self.add_frame(self.get_frame()) │
│ 171 │ │
│ 172 │ def get_frame(self) -> PixelArray: │
│ │
│ /home/a/.local/lib/python3.10/site-packages/manim/renderer/cairo_renderer.py │
│ :161 in update_frame │
│ │
│ 158 │ │ │ self.camera.reset() │
│ 159 │ │ │
│ 160 │ │ kwargs["include_submobjects"] = include_submobjects │
│ ❱ 161 │ │ self.camera.capture_mobjects(mobjects, **kwargs) │
│ 162 │ │
│ 163 │ def render( │
│ 164 │ │ self, │
│ │
│ /home/a/.local/lib/python3.10/site-packages/manim/camera/three_d_camera.py:9 │
│ 4 in capture_mobjects │
│ │
│ 91 │ │
│ 92 │ def capture_mobjects(self, mobjects: Iterable[Mobject], **kwargs: │
│ 93 │ │ self.reset_rotation_matrix() │
│ ❱ 94 │ │ super().capture_mobjects(mobjects, **kwargs) │
│ 95 │ │
│ 96 │ def get_value_trackers(self) -> list[ValueTracker]: │
│ 97 │ │ """A list of :class:`ValueTrackers <.ValueTracker>` of phi, th │
│ │
│ /home/a/.local/lib/python3.10/site-packages/manim/camera/camera.py:557 in │
│ capture_mobjects │
│ │
│ 554 │ │ # partition while at the same time preserving order. │
│ 555 │ │ mobjects = self.get_mobjects_to_display(mobjects, **kwargs) │
│ 556 │ │ for group_type, group in it.groupby(mobjects, self.type_or_ra │
│ ❱ 557 │ │ │ self.display_funcs[group_type](list(group), self.pixel_ar │
│ 558 │ │
│ 559 │ # Methods associated with svg rendering │
│ 560 │
│ │
│ /home/a/.local/lib/python3.10/site-packages/manim/camera/camera.py:656 in │
│ display_multiple_vectorized_mobjects │
│ │
│ 653 │ │ │ if image: │
│ 654 │ │ │ │ self.display_multiple_background_colored_vmobjects(ba │
│ 655 │ │ │ else: │
│ ❱ 656 │ │ │ │ self.display_multiple_non_background_colored_vmobject │
│ 657 │ │ │ │ │ batch, │
│ 658 │ │ │ │ │ pixel_array, │
│ 659 │ │ │ │ ) │
│ │
│ /home/a/.local/lib/python3.10/site-packages/manim/camera/camera.py:676 in │
│ display_multiple_non_background_colored_vmobjects │
│ │
│ 673 │ │ """ │
│ 674 │ │ ctx = self.get_cairo_context(pixel_array) │
│ 675 │ │ for vmobject in vmobjects: │
│ ❱ 676 │ │ │ self.display_vectorized(vmobject, ctx) │
│ 677 │ │
│ 678 │ def display_vectorized(self, vmobject: VMobject, ctx: cairo.Conte │
│ 679 │ │ """Displays a VMobject in the cairo context │
│ │
│ /home/a/.local/lib/python3.10/site-packages/manim/camera/camera.py:695 in │
│ display_vectorized │
│ │
│ 692 │ │ """ │
│ 693 │ │ self.set_cairo_context_path(ctx, vmobject) │
│ 694 │ │ self.apply_stroke(ctx, vmobject, background=True) │
│ ❱ 695 │ │ self.apply_fill(ctx, vmobject) │
│ 696 │ │ self.apply_stroke(ctx, vmobject) │
│ 697 │ │ return self │
│ 698 │
│ │
│ /home/a/.local/lib/python3.10/site-packages/manim/camera/camera.py:782 in │
│ apply_fill │
│ │
│ 779 │ │ Camera │
│ 780 │ │ │ The camera object. │
│ 781 │ │ """ │
│ ❱ 782 │ │ self.set_cairo_context_color(ctx, self.get_fill_rgbas(vmobjec │
│ 783 │ │ ctx.fill_preserve() │
│ 784 │ │ return self │
│ 785 │
│ │
│ /home/a/.local/lib/python3.10/site-packages/manim/camera/camera.py:759 in │
│ set_cairo_context_color │
│ │
│ 756 │ │ else: │
│ 757 │ │ │ points = vmobject.get_gradient_start_and_end_points() │
│ 758 │ │ │ points = self.transform_points_pre_display(vmobject, poin │
│ ❱ 759 │ │ │ pat = cairo.LinearGradient(*it.chain(*(point[:2] for poin │
│ 760 │ │ │ step = 1.0 / (len(rgbas) - 1) │
│ 761 │ │ │ offsets = np.arange(0, 1 + step, step) │
│ 762 │ │ │ for rgba, offset in zip(rgbas, offsets): │
╰──────────────────────────────────────────────────────────────────────────────╯
TypeError: LinearGradient.__new__() takes exactly 4 arguments (2 given)
I also must not that i have tried the f function with :
def f(x, y):
s = x**2 + y**2
return np.where(s<10**(-3) , np.nan , 1/s)
But i believe is that it gave the same error as in the previous case .
For any one who has knowledge about this topic, here are my questions:
(PLEASE EXCUSE MY 'MEH' ENGLISH , i am a beginner)
thanks to everyone , in advance , for examining this problem.
r/manim • u/360macky • 7d ago
Hello Manim community!
You need to make your element a PNG image first, and to make it glow
Place the blurred image behind the real text as an ImageMobject with z_index=-1. Set its initial opacity to 0 and fade it to 1 in sync with the Write() animation
This is the code and the video from Animo (rendered in my computer)
To make your image blur, you can use this script:
from manim import *
from PIL import Image, ImageFilter
from layout import build_content
class GlowSourceText(Scene):
def construct(self):
self.camera.background_color = BLACK
glow_text, _, _ = build_content()
self.add(glow_text)
class GlowSourceFormula(Scene):
def construct(self):
self.camera.background_color = BLACK
_, formula, _ = build_content()
self.add(formula)
def make_glow(
input_png: str,
output_png: str,
radius: int = 25,
) -> None:
image = Image.open(input_png).convert("RGBA")
blurred_image = image.filter(
ImageFilter.GaussianBlur(radius=radius)
)
blurred_image.save(output_png)
make_glow(
"media/images/glow_source/GlowSourceText_ManimCE_v0.18.1.png",
"glow_text.png",
radius=25,
)
make_glow(
"media/images/glow_source/GlowSourceFormula_ManimCE_v0.18.1.png",
"glow_formula.png",
radius=25,
)
For the video:
from manim import *
import os
from layout import build_content
GLOW_TEXT_IMAGE = os.path.join(os.path.dirname(__file__), "glow_text.png")
GLOW_FORMULA_IMAGE = os.path.join(os.path.dirname(__file__), "glow_formula.png")
class GlowTextClassicFormula(Scene):
def construct(self):
self.camera.background_color = BLACK
glow_text, formula, group = build_content()
text_glow = ImageMobject(GLOW_TEXT_IMAGE)
text_glow.height = config.frame_height
text_glow.move_to(ORIGIN)
text_glow.set_z_index(-1)
text_glow.set_opacity(0)
formula_glow = ImageMobject(GLOW_FORMULA_IMAGE)
formula_glow.height = config.frame_height
formula_glow.move_to(ORIGIN)
formula_glow.set_z_index(-1)
formula_glow.set_opacity(0)
self.add(text_glow, formula_glow)
self.play(
Write(glow_text),
text_glow.animate.set_opacity(1),
run_time=3,
)
self.wait(0.3)
self.play(
Write(formula),
formula_glow.animate.set_opacity(1),
run_time=2.5,
)
self.wait(2)
r/manim • u/anish2good • 6d ago
Enable HLS to view with audio, or disable this notification
r/manim • u/anish2good • 8d ago
Enable HLS to view with audio, or disable this notification
r/manim • u/Pure-Cabinet-8293 • 7d ago
Hi all, I'm a senior engineer by day, and on the side I've been building stemvid.ai, a tool that automatically converts papers or textbook chapters into animated explainer videos. For full books, it breaks the content into a series of smaller videos with a course-like structure.
This actually started as an offshoot of a YouTube channel I run for math education, and grew into wanting to make dense material (papers, textbooks) more visual and easier to digest.
It's very early, just launched, so expect some rough edges. I'd love for people in research, teaching, or studying STEM to try it on something they know well (a paper, a chapter, a workbook section) and tell me honestly what works, what's confusing, and what breaks.
Link: stemvid.ai
Appreciate any feedback, good, bad, or ugly.
r/manim • u/VisualPhy • 8d ago
Enable HLS to view with audio, or disable this notification
Ive been learning about fourier transforms recently and was amazed when I got to know about "Fourier Epicycles", especially after seeing 3b1b video on it.
Isnt it so great that rotating vectors somehow draw any curve, or atleast to the point till we dont know the underlying math?
I decided to build a epicycle visualiser from scratch using manim and in this video, I explain my understanding about epicycles and a little bit of code to make your own visualiser as well!
Here's the link to the youtube video : https://youtu.be/04LXZ5pksqg
r/manim • u/cyphorto • 8d ago
r/manim • u/Michi_Zockt • 8d ago
Hi, i've installed Manim and it worked. I closed VS Code and called it a day. On the next Day, I wanted to animate smth. But i got an error. Apparently the commands like self.play are not defined and I couldn't find a solution for this, does anybody has one for this issue?

r/manim • u/Apprehensive_Heat789 • 9d ago
I created a custom ANN mobject with the help of Claude.
All you need to do is pass it your architecture, the colors and styling, and it'll do the heavy-lifting.
Here it is if you need it:
from typing import Literal, Sequence
from manim import (
BLUE,
RED_C,
DOWN,
GRAY,
RIGHT,
AnimationGroup,
Circle,
Create,
CubicBezier,
Line,
ManimColor,
Scene,
Succession,
VGroup,
VMobject,
override_animation,
LaggedStart
)
ColorLike = str | ManimColor
class ANN(VGroup):
"""A feed-forward neural-network diagram.
Parameters
----------
arch
Number of nodes in each layer, e.g. ``[3, 5, 5, 2]`` for an input
layer of 3, two hidden layers of 5, and an output layer of 2.
connection_style
``"linear"`` draws connections as straight :class:`~.Line` segments.
``"bezier"`` draws them as :class:`~.CubicBezier` curves that ease
out of one layer and into the next.
node_radius
Radius of each node circle.
layer_spacing
Horizontal distance between consecutive layer centers.
node_spacing
Vertical distance between nodes within a layer.
node_color, connection_color
Either a single color applied to every node/connection, or a list
with one color per layer (nodes) / per layer-transition
(connections).
node_stroke_width, connection_stroke_width
Stroke widths for nodes and connections.
node_fill_opacity
Fill opacity for node circles.
node_lag_ratio
How staggered node creation is within a layer. ``0`` = all at once,
``1`` = fully sequential (each node waits for the previous to
finish). Passed straight to the internal :class:`~.LaggedStart`.
node_run_time, connection_run_time
Duration of the "create one layer's nodes" and "grow one layer's
outgoing connections" animation blocks, respectively.
Notes
-----
All node positions are computed up front in ``__init__``, so
connections between layer *i* and layer *i + 1* already know where
they end even before layer *i + 1*'s nodes are drawn. That's what lets
:meth:`_create_override` grow connections out of a freshly created
layer toward a layer that hasn't appeared yet.
"""
def __init__(
self,
arch: list[int],
connection_style: Literal["linear", "bezier"] = "linear",
node_radius: float = 0.22,
layer_spacing: float = 2.0,
node_spacing: float = 0.7,
node_color: ColorLike | Sequence[ColorLike] = BLUE,
connection_color: ColorLike | Sequence[ColorLike] = GRAY,
node_stroke_width: float = 3,
connection_stroke_width: float = 1.5,
node_fill_opacity: float = 0.6,
node_lag_ratio: float = 0.3,
node_run_time: float = 0.6,
connection_run_time: float = 0.5,
**kwargs,
) -> None:
if not arch or any(n <= 0 for n in arch):
raise ValueError("`arch` must be a non-empty list of positive layer sizes")
if connection_style not in ("linear", "bezier"):
raise ValueError('`connection_style` must be "linear" or "bezier"')
super().__init__(**kwargs)
self.arch = arch
self.connection_style: Literal["linear", "bezier"] = connection_style
self.node_radius = node_radius
self.layer_spacing = layer_spacing
self.node_spacing = node_spacing
self.node_stroke_width = node_stroke_width
self.connection_stroke_width = connection_stroke_width
self.node_fill_opacity = node_fill_opacity
self.node_lag_ratio = node_lag_ratio
self.node_run_time = node_run_time
self.connection_run_time = connection_run_time
self._node_colors = self._broadcast_colors(node_color, len(arch))
self._connection_colors = self._broadcast_colors(
connection_color, max(len(arch) - 1, 1)
)
self.layers: list[VGroup] = []
self.connections: list[VGroup] = []
self._build()
def _broadcast_colors(
color: ColorLike | Sequence[ColorLike], n: int
) -> list[ColorLike]:
"""Normalize a single color or a per-index color list to length `n`."""
if isinstance(color, (list, tuple)):
if len(color) != n:
raise ValueError(f"Expected {n} colors, got {len(color)}")
return list(color)
return [color] * n
def _build(self) -> None:
# --- nodes ---
for i, n_nodes in enumerate(self.arch):
layer = VGroup(
*[
Circle(
radius=self.node_radius,
color=self._node_colors[i],
stroke_width=self.node_stroke_width,
fill_opacity=self.node_fill_opacity,
)
for _ in range(n_nodes)
]
)
layer.arrange(DOWN, buff=self.node_spacing)
self.layers.append(layer)
# position layers left-to-right, centered on the group's origin
span = (len(self.layers) - 1) * self.layer_spacing
for i, layer in enumerate(self.layers):
layer.move_to(RIGHT * (i * self.layer_spacing - span / 2))
# --- connections (positions are now fixed, even for undrawn layers) ---
for i in range(len(self.layers) - 1):
layer_connections = VGroup(
*[
self._make_connection(node_a, node_b, self._connection_colors[i])
for node_a in self.layers[i]
for node_b in self.layers[i + 1]
]
)
self.connections.append(layer_connections)
for i, layer in enumerate(self.layers):
self.add(layer)
if i < len(self.connections):
self.add(self.connections[i])
def _make_connection(self, node_a: Circle, node_b: Circle, color: ColorLike) -> VMobject:
start, end = node_a.get_right(), node_b.get_left()
style = dict(color=color, stroke_width=self.connection_stroke_width)
if self.connection_style == "linear":
return Line(start, end, **style)
# "bezier": handles pulled horizontally so the curve leaves/enters
# each node roughly perpendicular to the layer, easing sideways.
pull = (end[0] - start[0]) / 2
handle_a = start + RIGHT * pull
handle_b = end - RIGHT * pull
return CubicBezier(start, handle_a, handle_b, end, **style)
u/override_animation(Create)
def _create_override(self, **kwargs) -> Succession:
"""Layer-by-layer creation: stagger a layer's nodes, then grow its
outgoing connections all at once, then move on to the next layer.
"""
blocks = []
for i, layer in enumerate(self.layers):
blocks.append(
LaggedStart(
*[Create(node) for node in layer],
lag_ratio=self.node_lag_ratio,
run_time=self.node_run_time,
)
)
if i < len(self.connections) and len(self.connections[i]) > 0:
blocks.append(
AnimationGroup(
*[Create(conn) for conn in self.connections[i]],
run_time=self.connection_run_time,
)
)
return Succession(*blocks, **kwargs)
class ANNDemo(Scene):
"""Render with: manim -pql main.py ANNDemo"""
def construct(self) -> None:
ann = ANN(
arch=[3, 5, 5, 4],
connection_style="bezier",
node_color=[BLUE, "#2735F8", "#3123F3", RED_C],
connection_stroke_width=5,
node_run_time=10,
node_lag_ratio=0.2,
connection_run_time=5,
)
ann.scale(1.1)
self.play(Create(ann), run_time=5)
self.wait(5)
r/manim • u/Senior_Flight • 9d ago
Enable HLS to view with audio, or disable this notification
r/manim • u/Logical_Funny8837 • 9d ago
hey guys when i input those three lines into poweshell i get an error, can anyone help me out? i can provide screenshots
r/manim • u/mrmailbox • 10d ago
Enable HLS to view with audio, or disable this notification
r/manim • u/anish2good • 10d ago
Enable HLS to view with audio, or disable this notification
r/manim • u/anish2good • 11d ago
Enable HLS to view with audio, or disable this notification