How to Import and Utilize SVG Files Using SVGMobject in Manim Animations
Use SVGMobject to convert any SVG file or raw SVG markup into a vectorized Manim object that supports standard transformations, styling overrides, and granular sub-object animation.
To import and utilize SVG files using SVGMobject in Manim animations, you leverage the vector graphics pipeline in the 3b1b/manim repository. This class transforms static SVG data into a hierarchy of VMobject instances, enabling you to animate complex logos, diagrams, and illustrations with the same API used for native Manim primitives.
How SVGMobject Processes SVG Data Internally
SVGMobject inherits from VMobject (defined at manimlib/mobject/svg/svg_mobject.py:L53), which provides the foundational vector functionality for strokes, fills, and geometric transformations. The initialization sequence (__init__ at lines 58–78) accepts either a file_name or an svg_string, stores user-provided style overrides, and triggers the build pipeline.
The construction process follows these stages:
Caching and Hashing – The system computes a hash seed (lines 134–144) based on the class name, default style dictionary, path string configuration, and raw SVG data. This populates SVG_HASH_TO_MOB_MAP and PATH_TO_POINTS, ensuring that identical SVGs are parsed only once.
XML Preprocessing – The method modify_xml_tree (lines 161–185) strips original root attributes, creates a fresh <svg> element, and injects a configuration style node. This isolates the SVG from viewBox unit conversions and allows Manim to reliably apply global style overrides.
Element Conversion – mobjects_from_svg (lines 203–227) walks the parsed svgelements.SVG object and dispatches each primitive—Path, Line, Rect, Circle, Ellipse, Polygon, Polyline—to dedicated helpers like path_to_mobject or line_to_mobject.
Path Parsing – VMobjectFromSVGPath (lines 336–424) handles the heavy lifting of converting SVG path commands (move, line, cubic/quadratic Bezier, arcs) into Manim point arrays. Results are cached in PATH_TO_POINTS to accelerate repeated use.
Coordinate Adjustment – After construction, init_svg_mobject (lines 123–133) flips the Y-axis (self.flip(RIGHT)) to align SVG coordinates with Manim’s coordinate system where positive Y is up.
Importing and Using SVG Files in a Scene
Follow these steps to integrate external vector graphics into your animation.
1. Import the Class
from manim import *
2. Instantiate from File or String
Place your SVG file in the media directory or provide an absolute path. Alternatively, pass raw markup.
# Load from disk
logo = SVGMobject("company_logo.svg")
# Load from raw string
raw_svg = """<svg viewBox="0 0 100 100">
<rect x="10" y="10" width="80" height="80" fill="blue"/>
</svg>"""
icon = SVGMobject(svg_string=raw_svg)
3. Apply Transformations and Styling
logo.set_height(4) # Scale to 4 Manim units
logo.move_to(ORIGIN) # Center in frame
logo.set_fill(PURE_RED, opacity=0.8) # Override SVG fill
logo.set_stroke(WHITE, width=2) # Override stroke
4. Animate Sub-objects
The SVG hierarchy exposes individual paths as submobjects.
# Sequential fade-in of each path
self.play(LaggedStartMap(FadeIn, logo.submobjects, lag_ratio=0.1))
# Color cycle individual elements
for i, submob in enumerate(logo.submobjects):
submob.set_color([RED, GREEN, BLUE][i % 3])
Advanced SVGMobject Techniques
Leverage these strategies for production-quality animations.
Global Color Override – Pass color, fill_color, or stroke_color to the constructor. These values feed into generate_config_style_dict (lines 186–202) and are injected into the SVG’s style node, affecting every path element uniformly.
Selective Partial Styling – After construction, index specific sub-objects (logo[0], logo[3]) to apply distinct styles. This is effective for multi-color logos where you need to preserve brand colors on specific elements.
Caching for Performance – The internal SVG_HASH_TO_MOB_MAP ensures that repeated instantiations of the same SVG (e.g., inside a loop or function) reuse pre-parsed geometry. No manual intervention is required; simply instantiate normally.
Custom Path Parsing – For SVGs with non-standard elements, subclass SVGMobject and override path_to_mobject or modify_xml_tree. This allows bespoke handling of custom markers or proprietary SVG extensions while retaining the base rendering pipeline.
LaTeX-Style Text via StringMobject – For animated typography, use StringMobject (located in manimlib/mobject/svg/string_mobject.py). It builds upon SVGMobject and adds text-selection utilities, making it ideal for equations and formatted text animations.
Complete Code Examples
Example 1: Simple SVG Import and Basic Animation
from manim import *
class SvgDemo(Scene):
def construct(self):
# Load the SVG file placed in the "media/svg_images" folder
logo = SVGMobject("3b1b_logo.svg")
logo.set_height(3) # Scale to a convenient size
logo.move_to(UP) # Position near the top
# Animate the whole logo
self.play(FadeIn(logo, shift=UP))
self.wait(1)
# Animate the individual parts with a lag
self.play(
LaggedStartMap(
Rotate,
logo.submobjects,
angle=TAU,
run_time=3,
lag_ratio=0.15,
)
)
self.wait()
Key implementation details:
SVGMobject("3b1b_logo.svg")triggersfile_name_to_svg_string(lines 158–160) to locate and read the file.logo.submobjectsexposes the vectorized hierarchy created bymobjects_from_svg(lines 203–227).
Example 2: Overriding Colors and Combining with Other Objects
from manim import *
class SvgStyleDemo(Scene):
def construct(self):
# Load an SVG of a lightbulb
bulb = SVGMobject("lightbulb.svg")
bulb.set_fill(WHITE, opacity=0.8) # Force a light fill
bulb.set_stroke(GREY, width=3) # Override stroke
# Create a surrounding frame
frame = Rectangle(width=8, height=5, color=BLUE_D).surround(bulb)
# Group them
group = VGroup(frame, bulb).center()
# Animate the group appearing
self.play(Write(frame))
self.play(FadeIn(bulb, scale=0.5))
self.wait()
Example 3: Generating an SVG from a String
from manim import *
class SvgFromString(Scene):
def construct(self):
raw = """
<svg viewBox="0 0 100 100">
<polygon points="10,10 90,10 50,80" fill="orange"/>
<circle cx="50" cy="30" r="10" fill="purple"/>
</svg>
"""
shape = SVGMobject(svg_string=raw)
shape.scale(2).move_to(ORIGIN)
self.play(FadeIn(shape))
self.wait()
Summary
- SVGMobject converts SVG files or raw markup into manipulable
VMobjecthierarchies viamanimlib/mobject/svg/svg_mobject.py. - The constructor accepts either
file_nameorsvg_string, automatically handling XML preprocessing, Y-axis flipping, and style injection throughmodify_xml_treeandgenerate_config_style_dict. - Internal caching via
SVG_HASH_TO_MOB_MAPandPATH_TO_POINTSeliminates redundant parsing of identical graphics. - Each SVG element becomes a submobject accessible through
.submobjects, enabling granular animation of individual paths, shapes, or groups. - Style overrides applied at construction time or via
set_fill/set_strokeaffect the entire object, while indexing specific submobjects allows partial colorization.
Frequently Asked Questions
How do I position an SVG file correctly in the scene?
Place your SVG file in the media/ directory or a subdirectory within your project path. SVGMobject uses get_full_vector_image_path (defined in manimlib/utils/images.py) to resolve the file location. Once loaded, use .move_to(ORIGIN), .to_edge(UP), or .shift(RIGHT * 2) to position the object using standard Manim coordinates.
Can I animate individual parts of an imported SVG separately?
Yes. SVGMobject parses the SVG into a hierarchy of submobjects—one for each path, rectangle, circle, or polygon. Access these via the .submobjects attribute or by indexing (e.g., svg[0], svg[1]). You can then apply distinct styles or animations to each element, such as svg[0].set_fill(RED) or LaggedStartMap(FadeIn, svg.submobjects).
Why does my SVG appear upside down or mirrored?
Manim automatically flips the Y-axis during construction via self.flip(RIGHT) inside init_svg_mobject (lines 123–133 of svg_mobject.py). This corrects the coordinate mismatch between SVG standards (where Y increases downward) and Manim’s scene coordinates (where Y increases upward). If your graphic still appears incorrect, verify that your SVG’s viewBox and width/height attributes are properly defined, as these guide the scaling logic in modify_xml_tree.
How can I override the colors defined in the original SVG file?
Pass style arguments directly to the SVGMobject constructor, such as fill_color=PURE_BLUE, stroke_color=WHITE, or color=RED. These values feed into generate_config_style_dict (lines 186–202), which creates a configuration style node injected into the SVG XML. This node globally overrides attributes for all path elements. Alternatively, call set_fill() or set_stroke() after instantiation to apply styles post-construction.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →