You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
After running two consecutive ReplacementTransform calls- first replacing a circle with a square, then that square with a triangle - the original circle and/or square sometimes remain in self.mobjects, resulting in extra, empty shapes (“ghosts”) being rendered alongside the intended transform.
Expected behavior
Only one triangle instance should remain on‑screen after the two ReplacementTransform calls, and self.mobjects should contain exactly that single triangle.
(manim) PS D:\Programming\manim-test> manim test.py Test -pql -v DEBUG
Manim Community v0.19.0
[05/04/25 22:19:22] DEBUG Hashing ... hashing.py:352
DEBUG Hashing done in 0.009381 s. hashing.py:364
DEBUG Hash generated : 1185818338_4190402543_223132457 hashing.py:367
INFO Animation 0 : Using cached data (hash : cairo_renderer.py:89
1185818338_4190402543_223132457)
DEBUG List of the first few animation hashes of the scene: cairo_renderer.py:98
['1185818338_4190402543_223132457']
DEBUG Hashing ... hashing.py:352
DEBUG Hashing done in 0.009456 s. hashing.py:364
DEBUG Hash generated : 624642324_537848572_4156405120 hashing.py:367
INFO Animation 1 : Using cached data (hash : cairo_renderer.py:89
624642324_537848572_4156405120)
DEBUG List of the first few animation hashes of the scene: cairo_renderer.py:98
['1185818338_4190402543_223132457', '624642324_537848572_4156405120']
DEBUG Hashing ... hashing.py:352
DEBUG Hashing done in 0.009287 s. hashing.py:364
DEBUG Hash generated : 624642324_2607346297_110000080 hashing.py:367
INFO Animation 2 : Using cached data (hash : cairo_renderer.py:89
624642324_2607346297_110000080)
DEBUG List of the first few animation hashes of the scene: cairo_renderer.py:98
['1185818338_4190402543_223132457', '624642324_537848572_4156405120',
'624642324_2607346297_110000080']
DEBUG Hashing ... hashing.py:352
DEBUG Hashing done in 0.010183 s. hashing.py:364
DEBUG Hash generated : 624642324_289194527_836597036 hashing.py:367
INFO Animation 3 : Using cached data (hash : 624642324_289194527_836597036) cairo_renderer.py:89
DEBUG List of the first few animation hashes of the scene: cairo_renderer.py:98
['1185818338_4190402543_223132457', '624642324_537848572_4156405120',
'624642324_2607346297_110000080', '624642324_289194527_836597036']
DEBUG Hashing ... hashing.py:352
DEBUG Hashing done in 0.008176 s. hashing.py:364
DEBUG Hash generated : 624642324_3194600842_1010701616 hashing.py:367
INFO Animation 4 : Using cached data (hash : cairo_renderer.py:89
624642324_3194600842_1010701616)
DEBUG List of the first few animation hashes of the scene: cairo_renderer.py:98
['1185818338_4190402543_223132457', '624642324_537848572_4156405120',
'624642324_2607346297_110000080', '624642324_289194527_836597036',
'624642324_3194600842_1010701616']
DEBUG Animation with empty mobject animation.py:190
DEBUG Hashing ... hashing.py:352
DEBUG Hashing done in 0.006768 s. hashing.py:364
DEBUG Hash generated : 624642324_2872842549_4071541655 hashing.py:367
INFO Animation 5 : Using cached data (hash : cairo_renderer.py:89
624642324_2872842549_4071541655)
DEBUG List of the first few animation hashes of the scene: cairo_renderer.py:98
['1185818338_4190402543_223132457', '624642324_537848572_4156405120',
'624642324_2607346297_110000080', '624642324_289194527_836597036',
'624642324_3194600842_1010701616']
DEBUG Hashing ... hashing.py:352
DEBUG Hashing done in 0.010292 s. hashing.py:364
DEBUG Hash generated : 624642324_3653221575_1206155369 hashing.py:367
INFO Animation 6 : Using cached data (hash : cairo_renderer.py:89
624642324_3653221575_1206155369)
DEBUG List of the first few animation hashes of the scene: cairo_renderer.py:98
['1185818338_4190402543_223132457', '624642324_537848572_4156405120',
'624642324_2607346297_110000080', '624642324_289194527_836597036',
'624642324_3194600842_1010701616']
DEBUG Animation with empty mobject animation.py:190
DEBUG Hashing ... hashing.py:352
DEBUG Hashing done in 0.008523 s. hashing.py:364
DEBUG Hash generated : 624642324_2872842549_3178527957 hashing.py:367
INFO Animation 7 : Using cached data (hash : cairo_renderer.py:89
624642324_2872842549_3178527957)
DEBUG List of the first few animation hashes of the scene: cairo_renderer.py:98
['1185818338_4190402543_223132457', '624642324_537848572_4156405120',
'624642324_2607346297_110000080', '624642324_289194527_836597036',
'624642324_3194600842_1010701616']
Triangle
Square
Triangle
Mobject
Mobject
INFO Combining to Movie file. scene_file_writer.py:739
DEBUG Partial movie files to combine (8 files): scene_file_writer.py:622
['D:\\Programming\\manim-test\\media\\videos\\test\\480p15\\partia
l_movie_files\\Test\\1185818338_4190402543_223132457.mp4',
'D:\\Programming\\manim-test\\media\\videos\\test\\480p15\\partial
_movie_files\\Test\\624642324_537848572_4156405120.mp4',
'D:\\Programming\\manim-test\\media\\videos\\test\\480p15\\partial
_movie_files\\Test\\624642324_2607346297_110000080.mp4',
'D:\\Programming\\manim-test\\media\\videos\\test\\480p15\\partial
_movie_files\\Test\\624642324_289194527_836597036.mp4',
'D:\\Programming\\manim-test\\media\\videos\\test\\480p15\\partial
_movie_files\\Test\\624642324_3194600842_1010701616.mp4']
INFO scene_file_writer.py:886
File ready at
'D:\Programming\manim-test\media\videos\test\480p15\Test.mp4'
INFO Rendered Test scene.py:255
Played 8 animations
[05/04/25 22:19:23] INFO Previewed File at: file_ops.py:237
'D:\Programming\manim-test\media\videos\test\480p15\Test.mp4'
System specifications
System Details
OS: Windows 10 Education (10.0.19045 Build 19045)
RAM: 16GB
Python version (python/py/python3 --version): 3.12.10
To the best of my knowledge, the issue arises because ReplacementTransform always invokes the scene’s replace logic, which unconditionally inserts the target mobject at the source’s position - even if that target is already present - then removes only the source. This can leave behind a duplicate reference or the original target, producing “ghost” shapes after the animation .
A straightforward remedy would be to adjust ReplacementTransform so that it:
Detects Existing Targets
Before performing any insertion, check whether target_mobject is already in scene.mobjects.
Skips Redundant Inserts
If the target is present, only removes the source_mobject from the scene, rather than inserting the target again.
Falls Back Gracefully
If the target isn’t yet on-screen, proceed with the normal replace behaviour (insert + remove) so nothing else changes.
By doing this, after the transform finishes there will only ever be one instance of the target - no leftover “ghost” copies remain.
The text was updated successfully, but these errors were encountered:
Description of bug / unexpected behavior
After running two consecutive
ReplacementTransform
calls- first replacing a circle with a square, then that square with a triangle - the original circle and/or square sometimes remain inself.mobjects
, resulting in extra, empty shapes (“ghosts”) being rendered alongside the intended transform.Expected behavior
Only one triangle instance should remain on‑screen after the two
ReplacementTransform
calls, andself.mobjects
should contain exactly that single triangle.How to reproduce the issue
Code for reproducing the problem
Additional media files
Images/GIFs
Test.mp4
Logs
Terminal output
System specifications
System Details
python/py/python3 --version
): 3.12.10Additional comments
Discord help link
Suggestions:
To the best of my knowledge, the issue arises because
ReplacementTransform
always invokes the scene’s replace logic, which unconditionally inserts the target mobject at the source’s position - even if that target is already present - then removes only the source. This can leave behind a duplicate reference or the original target, producing “ghost” shapes after the animation .A straightforward remedy would be to adjust
ReplacementTransform
so that it:Before performing any insertion, check whether
target_mobject
is already inscene.mobjects
.If the target is present, only removes the
source_mobject
from the scene, rather than inserting the target again.If the target isn’t yet on-screen, proceed with the normal replace behaviour (insert + remove) so nothing else changes.
By doing this, after the transform finishes there will only ever be one instance of the target - no leftover “ghost” copies remain.
The text was updated successfully, but these errors were encountered: