manim
manim copied to clipboard
ReplacementTransform of DiGraphs with different number of edges does not animate
Description of bug / unexpected behavior
When trying to perform the ReplacementTransform from one DiGraph with n edges to another DiGraph with m edges (where n≠m) manim prints an errors message during animation.
Expected behavior
The video file is animated and the result shows the graph being transformed into another version.
How to reproduce the issue
Code for reproducing the problem
from manim import *
class ReplacementBugDemo(Scene):
def construct(self):
# Create a graph with two edges
graph1 = DiGraph(["A", "B", "C"], [("A", "B"), ("A", "C"), ("B", "C")])
# Create another graph with three edges
graph2 = DiGraph(["A", "B", "C"], [("A", "B"), ("A", "C")])
# Display the first graph
self.play(Create(graph1))
self.wait(1)
# Attempt to transform graph1 into graph2
self.play(ReplacementTransform(graph1, graph2))
self.wait(1)
Additional media files
None, since the animation fails.
Logs
Terminal output
Manim Community v0.18.1
[10/05/24 20:35:40] DEBUG Hashing ... hashing.py:352
DEBUG Hashing done in 0.009862 s. hashing.py:364
DEBUG Hash generated : 1185818338_3935286645_223132457 hashing.py:367
DEBUG List of the first few animation hashes of the scene: ['1185818338_3935286645_223132457'] cairo_renderer.py:97
INFO Animation 0 : Partial movie file written in '/home/niplav/proj/site/anim/turning/media/videos/bug/480p15/partial_movie_files/ReplacementBugDemo/1185818338_3935286645_223132457.mp4' scene_file_writer.py:527
DEBUG Animation with empty mobject animation.py:175
DEBUG Hashing ... hashing.py:352
DEBUG Hashing done in 0.100260 s. hashing.py:364
DEBUG Hash generated : 624642324_3890345977_177987387 hashing.py:367
DEBUG List of the first few animation hashes of the scene: ['1185818338_3935286645_223132457', '624642324_3890345977_177987387'] cairo_renderer.py:97
INFO Animation 1 : Partial movie file written in '/home/niplav/proj/site/anim/turning/media/videos/bug/480p15/partial_movie_files/ReplacementBugDemo/624642324_3890345977_177987387.mp4' scene_file_writer.py:527
DEBUG Hashing ... hashing.py:352
[10/05/24 20:35:41] DEBUG Hashing done in 0.096162 s. hashing.py:364
DEBUG Hash generated : 624642324_1163978281_3169679834 hashing.py:367
DEBUG List of the first few animation hashes of the scene: ['1185818338_3935286645_223132457', '624642324_3890345977_177987387', '624642324_1163978281_3169679834'] cairo_renderer.py:97
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /usr/local/conda/envs/manim/lib/python3.12/site-packages/manim/cli/render/commands.py:120 in │
│ render │
│ │
│ 117 │ │ │ try: │
│ 118 │ │ │ │ with tempconfig({}): │
│ 119 │ │ │ │ │ scene = SceneClass() │
│ ❱ 120 │ │ │ │ │ scene.render() │
│ 121 │ │ │ except Exception: │
│ 122 │ │ │ │ error_console.print_exception() │
│ 123 │ │ │ │ sys.exit(1) │
│ │
│ /usr/local/conda/envs/manim/lib/python3.12/site-packages/manim/scene/scene.py:229 in render │
│ │
│ 226 │ │ """ │
│ 227 │ │ self.setup() │
│ 228 │ │ try: │
│ ❱ 229 │ │ │ self.construct() │
│ 230 │ │ except EndSceneEarlyException: │
│ 231 │ │ │ pass │
│ 232 │ │ except RerunSceneException as e: │
│ │
│ /home/niplav/proj/site/anim/turning/bug.py:32 in construct │
│ /home/niplav/proj/site/anim/turning/bug.py:32 in construct │
│ │
│ 29 │ │ self.wait(1) │
│ 30 │ │ │
│ 31 │ │ # Attempt to transform graph1 into graph2 │
│ ❱ 32 │ │ self.play(ReplacementTransform(graph1, graph2)) │
│ 33 │ │ self.wait(1) │
│ 34 │
│ │
│ /usr/local/conda/envs/manim/lib/python3.12/site-packages/manim/scene/scene.py:1092 in play │
│ │
│ 1089 │ │ │ return │
│ 1090 │ │ │
│ 1091 │ │ start_time = self.renderer.time │
│ ❱ 1092 │ │ self.renderer.play(self, *args, **kwargs) │
│ 1093 │ │ run_time = self.renderer.time - start_time │
│ 1094 │ │ if subcaption: │
│ 1095 │ │ │ if subcaption_duration is None: │
│ │
│ /usr/local/conda/envs/manim/lib/python3.12/site-packages/manim/renderer/cairo_renderer.py:114 in │
│ play │
│ │
│ 111 │ │ │ # In this case, as there is only a wait, it will be the length of the wait. │
│ 112 │ │ │ self.freeze_current_frame(scene.duration) │
│ 113 │ │ else: │
│ ❱ 114 │ │ │ scene.play_internal() │
│ 115 │ │ self.file_writer.end_animation(not self.skip_animations) │
│ 116 │ │ │
│ 117 │ │ self.num_plays += 1 │
│ │
│ /usr/local/conda/envs/manim/lib/python3.12/site-packages/manim/scene/scene.py:1259 in │
│ play_internal │
│ │
│ 1256 │ │ │ self.duration, │
│ 1257 │ │ ) │
│ 1258 │ │ for t in self.time_progression: │
│ ❱ 1259 │ │ │ self.update_to_time(t) │
│ 1260 │ │ │ if not skip_rendering and not self.skip_animation_preview: │
│ 1261 │ │ │ │ self.renderer.render(self, t, self.moving_mobjects) │
│ 1262 │ │ │ if self.stop_condition is not None and self.stop_condition(): │
│ │
│ /usr/local/conda/envs/manim/lib/python3.12/site-packages/manim/scene/scene.py:1500 in │
│ update_to_time │
│ │
│ 1497 │ │ for animation in self.animations: │
│ 1498 │ │ │ animation.update_mobjects(dt) │
│ 1499 │ │ │ alpha = t / animation.run_time │
│ ❱ 1500 │ │ │ animation.interpolate(alpha) │
│ 1501 │ │ self.update_mobjects(dt) │
│ 1502 │ │ self.update_meshes(dt) │
│ 1503 │ │ self.update_self(dt) │
│ │
│ /usr/local/conda/envs/manim/lib/python3.12/site-packages/manim/animation/animation.py:329 in │
│ interpolate │
│ │
│ │
│ 326 │ │ │ The relative time to set the animation to, 0 meaning the start, 1 meaning │
│ 327 │ │ │ the end. │
│ 328 │ │ """ │
│ ❱ 329 │ │ self.interpolate_mobject(alpha) │
│ 330 │ │
│ 331 │ def interpolate_mobject(self, alpha: float) -> None: │
│ 332 │ │ """Interpolates the mobject of the :class:`Animation` based on alpha value. │
│ │
│ /usr/local/conda/envs/manim/lib/python3.12/site-packages/manim/animation/animation.py:344 in │
│ interpolate_mobject │
│ │
│ 341 │ │ families = list(self.get_all_families_zipped()) │
│ 342 │ │ for i, mobs in enumerate(families): │
│ 343 │ │ │ sub_alpha = self.get_sub_alpha(alpha, i, len(families)) │
│ ❱ 344 │ │ │ self.interpolate_submobject(*mobs, sub_alpha) │
│ 345 │ │
│ 346 │ def interpolate_submobject( │
│ 347 │ │ self, │
│ │
│ /usr/local/conda/envs/manim/lib/python3.12/site-packages/manim/animation/transform.py:241 in │
│ interpolate_submobject │
│ │
│ 238 │ │ target_copy: Mobject, │
│ 239 │ │ alpha: float, │
│ 240 │ ) -> Transform: │
│ ❱ 241 │ │ submobject.interpolate(starting_submobject, target_copy, alpha, self.path_func) │
│ 242 │ │ return self │
│ 243 │
│ 244 │
│ │
│ /usr/local/conda/envs/manim/lib/python3.12/site-packages/manim/mobject/mobject.py:2763 in │
│ interpolate │
│ │
│ 2760 │ │ │ │ │ │
│ 2761 │ │ │ │ │ self.add(dotL, dotR, dotMiddle) │
│ 2762 │ │ """ │
│ ❱ 2763 │ │ self.points = path_func(mobject1.points, mobject2.points, alpha) │
│ 2764 │ │ self.interpolate_color(mobject1, mobject2, alpha) │
│ 2765 │ │ return self │
│ 2766 │
│ │
│ /usr/local/conda/envs/manim/lib/python3.12/site-packages/manim/utils/bezier.py:274 in │
│ interpolate │
│ │
│ 271 def interpolate( │
│ 272 │ start: int | float | Point3D, end: int | float | Point3D, alpha: float | Point3D │
│ 273 ) -> float | Point3D: │
│ ❱ 274 │ return (1 - alpha) * start + alpha * end │
│ 275 │
│ 276 │
│ 277 def integer_interpolate( │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
ValueError: operands could not be broadcast together with shapes (4,3) (32,3)
System specifications
System Details
- OS Void Linux:
› uname -a (manim)
Linux REDACTED 6.6.52_1 #1 SMP PREEMPT_DYNAMIC Sat Sep 21 15:47:36 UTC 2024 x86_64 GNU/Linux
› cat /etc/os-release (manim)
NAME="Void"
ID="void"
PRETTY_NAME="Void Linux"
HOME_URL="https://voidlinux.org/"
DOCUMENTATION_URL="https://docs.voidlinux.org/"
LOGO="void-logo"
ANSI_COLOR="0;38;2;71;128;97"
DISTRIB_ID="void"
- RAM: 16GB
- Python version (
python/py/python3 --version):
python3 --version (manim)
Python 3.12.5
- Installed modules (provide output from
pip list):
Package Version
-------------------- -----------
Brotli 1.1.0
build 1.2.1
CacheControl 0.14.0
certifi 2024.7.4
cffi 1.17.0
charset-normalizer 3.3.2
cleo 2.1.0
click 8.1.7
click-default-group 1.2.4
cloup 3.0.5
colorama 0.4.6
crashtest 0.4.1
cryptography 43.0.0
decorator 5.1.1
distlib 0.3.8
dulwich 0.21.7
fastjsonschema 2.20.0
filelock 3.15.4
future 1.0.0
glcontext 2.5.0
h2 4.1.0
hpack 4.0.0
hyperframe 6.0.1
idna 3.7
importlib_metadata 8.2.0
installer 0.7.0
isosurfaces 0.1.2
jaraco.classes 3.4.0
jeepney 0.8.0
keyring 24.3.1
manim 0.18.1
ManimPango 0.5.0
mapbox_earcut 1.0.1
markdown-it-py 3.0.0
mdurl 0.1.2
moderngl 5.10.0
moderngl-window 2.4.1
more-itertools 10.4.0
msgpack 1.0.8
multipledispatch 0.6.0
networkx 3.3
numpy 1.26.4
packaging 24.1
pexpect 4.9.0
pillow 10.4.0
pip 24.2
pkginfo 1.11.1
platformdirs 4.2.2
poetry 1.8.3
poetry-core 1.9.0
poetry-plugin-export 1.8.0
ptyprocess 0.7.0
pycairo 1.26.1
pycparser 2.22
pydub 0.25.1
pyglet 1.5.27
Pygments 2.18.0
pyproject_hooks 1.1.0
pyrr 0.10.3
PySocks 1.7.1
PyYAML 6.0.2
rapidfuzz 3.9.6
requests 2.32.3
requests-toolbelt 1.0.0
rich 13.7.1
scipy 1.14.0
screeninfo 0.8.1
SecretStorage 3.3.3
setuptools 72.1.0
shellingham 1.5.4
six 1.16.0
skia-pathops 0.8.0.post1
srt 3.5.3
svgelements 1.9.6
tomli 2.0.1
tomlkit 0.13.0
tqdm 4.66.5
trove-classifiers 2024.7.2
typing_extensions 4.12.2
urllib3 2.2.2
virtualenv 20.26.3
watchdog 4.0.1
wheel 0.44.0
zipp 3.19.2
zstandard 0.23.0
LaTeX details
- LaTeX distribution (e.g. TeX Live 2020):
- Installed LaTeX packages: