How to Use Transform and TransformMatchingParts Animations in Manim

Use Transform to interpolate every sub‑mobject of a source Mobject into a target Mobject by aligning their hierarchical data and applying a path function, while TransformMatchingParts automatically groups individual transforms for matching shapes and fades unmatched parts.

The 3b1b/manim library provides a robust animation framework built around the abstract Animation base class. Mastering the Transform and TransformMatchingParts animations in Manim allows you to create seamless morphs between geometric shapes, text, and complex mathematical expressions. This guide examines the source‑level implementation in manimlib/animation/transform.py and manimlib/animation/transform_matching_parts.py, and provides runnable examples for common use cases.

How Transform Works Under the Hood

The Transform class handles the fundamental mechanics of morphing one Mobject into another. Its implementation in manimlib/animation/transform.py follows a strict pipeline:

  1. Target creation – The constructor accepts a target_mobject argument. If none is provided, the subclass method create_target generates the destination object.
  2. Data alignment – The begin method calls self.mobject.align_data_and_family(self.target_copy). This ensures both source and target possess identical family trees, establishing a one‑to‑one mapping between sub‑mobjects.
  3. Path function initializationinit_path_func selects the interpolation trajectory:
    • path_arc == 0straight_path (linear motion).
    • Non‑zero path_arcpath_along_arc (imported from manimlib/utils/paths), generating a circular arc through 3D space.
  4. Per‑submobject interpolation – During each frame, interpolate_submobject calls submob.interpolate(start, target_copy, alpha, self.path_func), moving points along the chosen path.
  5. Scene cleanup – When replace_mobject_with_target_in_scene is True (as in ReplacementTransform), the scene swaps the source for the target upon completion.

How TransformMatchingParts Works Under the Hood

TransformMatchingParts (defined in manimlib/animation/transform_matching_parts.py) automates the creation of multiple synchronized transforms for complex objects such as Tex strings. It operates by decomposing source and target into their atomic vector components:

  1. Piece collection – The constructor gathers all sub‑mobjects containing points via source.family_members_with_points() and target.family_members_with_points().
  2. Explicit pairing – User‑provided tuples of (source_piece, target_piece) are processed through add_transform, creating individual Transform instances (or any specified animation class).
  3. Shape‑based auto‑matchingfind_pairs_with_matching_shapes iterates through remaining pieces, identifying pairs where has_same_shape_as returns True. Each match is converted into a match_animation (default Transform).
  4. Mismatch handling – Unmatched source pieces execute FadeOutToPoint toward the target’s center, while unmatched target pieces execute FadeInFromPoint from the source’s center.
  5. Group execution – All generated animations are bundled into an AnimationGroup (defined in manimlib/animation/composition.py) with a configurable lag_ratio, allowing concurrent playback with optional staggered timing.

Specialized subclasses TransformMatchingStrings and TransformMatchingTex extend this logic by employing SequenceMatcher to identify longest matching substrings before applying the part‑matching algorithm.

Practical Code Examples

Simple Transform Morphing

Use Transform to morph a circle into a square with an arced trajectory. The path_arc parameter leverages path_along_arc from manimlib/utils/paths.

from manim import *

class TransformDemo(Scene):
    def construct(self):
        circle = Circle(radius=1, color=BLUE).shift(LEFT)
        square = Square(side_length=2, color=RED).shift(RIGHT)

        # Morph with a quarter-circle arc path

        self.play(Transform(circle, square, path_arc=PI/4))
        self.wait()

ReplacementTransform for Scene Updates

ReplacementTransform (a subclass where replace_mobject_with_target_in_scene=True) removes the source Tex object and leaves the target in the scene.

class ReplacementDemo(Scene):
    def construct(self):
        tex_a = Tex(r"\int_a^b f(x)\,dx")
        tex_b = Tex(r"F(b)-F(a)").next_to(tex_a, DOWN)

        # Original is removed; new Tex remains

        self.play(ReplacementTransform(tex_a, tex_b))
        self.wait()

TransformMatchingParts for Equations

Automatically match identical characters between two Tex objects while fading non-matching parts. This uses the find_pairs_with_matching_shapes logic internally.

class MatchingPartsDemo(Scene):
    def construct(self):
        src = Tex(r"E = mc^2")
        tgt = Tex(r"F = ma").shift(RIGHT)

        # Auto-match '=' and 'm', fade 'E', 'c^2' / 'F', 'a'

        self.play(TransformMatchingParts(src, tgt, run_time=3))
        self.wait()

Custom Match and Mismatch Animations

Override match_animation and mismatch_animation to use different animation classes (e.g., rotating transforms or scaling fades).

class CustomMatchDemo(Scene):
    def construct(self):
        src = Tex(r"\alpha + \beta")
        tgt = Tex(r"\gamma + \delta").shift(UP)

        # Use rotating transform for matches, custom fade for mismatches

        self.play(
            TransformMatchingParts(
                src, tgt,
                match_animation=Transform,
                mismatch_animation=FadeInFromPoint,
                path_arc=PI/2,
                run_time=2,
                lag_ratio=0.2,
            )
        )
        self.wait()

Key Implementation Files

Understanding the source architecture helps when debugging or extending these animations.

File Purpose
manimlib/animation/animation.py Base Animation class defining the lifecycle (begin, interpolate, finish).
manimlib/animation/transform.py Core Transform and ReplacementTransform implementations, including align_data_and_family and path logic.
manimlib/animation/transform_matching_parts.py TransformMatchingParts, TransformMatchingStrings, and TransformMatchingTex with shape matching and AnimationGroup orchestration.
manimlib/animation/composition.py AnimationGroup used by TransformMatchingParts to play concurrent animations.
manimlib/mobject/mobject.py Mobject methods align_data_and_family, get_family, and has_same_shape_as used for data alignment and shape comparison.
manimlib/utils/paths.py Path functions straight_path and path_along_arc used by Transform.

Summary

  • Transform interpolates every sub‑mobject of a source into a target by first aligning their family trees via align_data_and_family, then applying a path function (straight line or arc) during interpolate_submobject.
  • ReplacementTransform is a subclass that sets replace_mobject_with_target_in_scene=True, swapping the source for the target in the scene graph after playback.
  • TransformMatchingParts automates the creation of multiple Transform instances by matching sub‑mobjects with identical shapes using find_pairs_with_matching_shapes, fading unmatched parts via FadeOutToPoint and FadeInFromPoint, and grouping everything into an AnimationGroup.
  • Customization options include path_arc for curved trajectories, and match_animation/mismatch_animation parameters to substitute different animation classes for the default behaviors.

Frequently Asked Questions

What is the difference between Transform and ReplacementTransform?

Transform morphs the source Mobject into the target but leaves the original object in the scene’s memory unless manually removed. ReplacementTransform (defined in manimlib/animation/transform.py) sets the flag replace_mobject_with_target_in_scene=True, which tells the scene to remove the source and insert the target upon completion, effectively swapping them.

How does TransformMatchingParts decide which parts to match?

The class uses find_pairs_with_matching_shapes in manimlib/animation/transform_matching_parts.py to compare every sub‑mobject from the source and target via the has_same_shape_as method. Pairs with identical point arrays are linked and animated with the match_animation class (default Transform). Unmatched pieces are faded out or in using FadeOutToPoint and FadeInFromPoint.

Can I use custom animations for matching or mismatching parts?

Yes. TransformMatchingParts accepts match_animation and mismatch_animation parameters in its constructor. You can pass any Animation subclass—such as Rotate, ScaleInPlace, or a custom Transform variant—to override the default behaviors for matched and unmatched sub‑mobjects respectively.

Why do my objects flicker or misalign during a Transform?

Flickering usually occurs when the source and target Mobjects have different family tree structures. The begin method of Transform calls align_data_and_family (from manimlib/mobject/mobject.py) to synchronize sub‑mobject lists. If you manually construct Mobjects with mismatched hierarchies, override create_target or ensure both objects have identical sub‑mobject counts to prevent alignment artifacts.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →