# How to Import and Utilize SVG Files Using SVGMobject in Manim Animations

> Import and utilize SVG files in Manim animations with SVGMobject. Convert SVGs to vectorized Manim objects for transformations, styling, and animation. Learn how to integrate custom graphics seamlessly.

- Repository: [Grant Sanderson/manim](https://github.com/3b1b/manim)
- Tags: how-to-guide
- Published: 2026-02-28

---

**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

```python
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.

```python

# 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

```python
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.

```python

# 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`](https://github.com/3b1b/manim/blob/main/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

```python
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")` triggers `file_name_to_svg_string` (lines 158–160) to locate and read the file.
* `logo.submobjects` exposes the vectorized hierarchy created by `mobjects_from_svg` (lines 203–227).

### Example 2: Overriding Colors and Combining with Other Objects

```python
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

```python
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 `VMobject` hierarchies via [`manimlib/mobject/svg/svg_mobject.py`](https://github.com/3b1b/manim/blob/main/manimlib/mobject/svg/svg_mobject.py).
- The constructor accepts either `file_name` or `svg_string`, automatically handling XML preprocessing, Y-axis flipping, and style injection through `modify_xml_tree` and `generate_config_style_dict`.
- Internal caching via `SVG_HASH_TO_MOB_MAP` and `PATH_TO_POINTS` eliminates 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_stroke` affect 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`](https://github.com/3b1b/manim/blob/main/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`](https://github.com/3b1b/manim/blob/main/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.