# How to Use Manim's Interactive IPython Embedding Mode with the `-e` Flag

> Master Manim's interactive IPython embedding mode with the -e flag. Manipulate mobjects and animations in real-time directly from the command line for faster scene development.

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

---

**Manim's `-e` (or `--embed`) flag drops you into an interactive IPython shell while your scene is running, allowing real-time manipulation of mobjects and animations directly from the command line.**

Manim's interactive IPython embedding mode transforms static animation scripts into live coding sessions. By invoking the `‑e` flag from the 3b1b/manim library, you gain direct access to your scene's objects and shortcuts without restarting the renderer. This workflow accelerates debugging and iterative development by letting you inspect, modify, and re-render animations on the fly.

## How the `-e` Flag Works Under the Hood

Understanding the internal mechanism helps you leverage the embedding mode effectively. The process involves three main stages: CLI argument parsing, source code transformation, and IPython shell initialization.

### CLI Parsing in [`config.py`](https://github.com/3b1b/manim/blob/main/config.py)

In [`manimlib/config.py`](https://github.com/3b1b/manim/blob/main/manimlib/config.py), the argument parser registers the `‑e/--embed` option between lines 165–169. When you provide a line number (e.g., `‑e 42`), the parser stores that integer in `run_config.embed_line`. If you use the flag without a number, it stores `None`, signaling the system to embed at the end of the `construct` method.

### Code Injection via [`extract_scene.py`](https://github.com/3b1b/manim/blob/main/extract_scene.py)

The `insert_embed_line_to_module` function in [`manimlib/extract_scene.py`](https://github.com/3b1b/manim/blob/main/manimlib/extract_scene.py) (lines 46–58) performs a runtime source transformation. It rewrites your Python module to insert `self.embed()` at the specified location:

- **With a line number**: Inserts the call immediately before that line number
- **Without a line number**: Appends `self.embed()` to the end of the `construct` method

If you omit the scene name, lines 65–72 in the same file infer the nearest class above the insertion point and automatically populate `run_config.scene_names`.

### Interactive Shell Initialization

When execution reaches the injected `self.embed()` call, it triggers `Scene.embed()` (inherited from [`interactive_scene.py`](https://github.com/3b1b/manim/blob/main/interactive_scene.py)). This instantiates `InteractiveSceneEmbed` from [`manimlib/scene/scene_embed.py`](https://github.com/3b1b/manim/blob/main/manimlib/scene/scene_embed.py) (lines 23–38), which:

1. Creates an `InteractiveShellEmbed` preloaded with your scene's namespace
2. Registers GUI input hooks for live frame updates
3. Configures autoreload behavior if `--autoreload` was passed
4. Injects helper shortcuts like `play`, `add`, and `remove`

The `launch` method then calls `self.shell()`, presenting you with an IPython REPL that has full access to your scene's state.

## Common Use Cases and Commands

The `‑e` flag supports multiple workflows depending on where you need to interrupt execution.

### Embedding at the End of a Scene

Use this approach for post-animation inspection or when you want to experiment after the standard `construct` logic completes:

```bash
manim -e my_scene.py MyScene

```

**What happens:**
- `run_config.embed_line` is set to `None`
- `insert_embed_line_to_module` appends `self.embed()` to the end of `MyScene.construct`
- The scene renders normally, then opens an IPython prompt

### Debugging at a Specific Line

Target a precise breakpoint when you need to inspect the state before a particular animation runs:

```bash
manim -e 120 my_scene.py MyScene

```

**What happens:**
- `self.embed()` inserts before line 120 in [`my_scene.py`](https://github.com/3b1b/manim/blob/main/my_scene.py)
- Execution pauses at that line, giving you access to all mobjects created up to that point
- You can inspect variables, modify positions, or test alternative animations

### Live Development with Autoreload

Enable automatic module reloading to see code changes without restarting Manim:

```bash
manim -e --autoreload my_scene.py MyScene

```

**Behavior:**
- The `InteractiveSceneEmbed` registers a `pre_run_cell` hook that re-imports your module before each IPython cell executes
- Edit your source file, save, and run a cell in the embedded shell to see changes instantly
- Exception handling flashes a red border around the viewport for visual error feedback

## Working Inside the IPython Shell

Once embedded, you have access to scene-specific shortcuts injected by `InteractiveSceneEmbed.get_shortcuts` (lines 59–79 in [`scene_embed.py`](https://github.com/3b1b/manim/blob/main/scene_embed.py)):

```python
In [1]: play(my_mobject.animate.shift(RIGHT))
In [2]: my_mobject.get_center()
Out[2]: array([1., 0., 0.])
In [3]: add(circle)  # Adds mobject to the scene immediately

In [4]: undo()       # Reverts the last operation

```

Available shortcuts include:
- **play()** – Render an animation immediately
- **add() / remove()** – Modify the scene's mobject list
- **undo() / redo()** – Navigate operation history
- **clear()** – Remove all mobjects
- **reload()** – Manually trigger module reimport (when not using `--autoreload`)

## Key Source Files for Embedding

According to the 3b1b/manim source code, these files implement the embedding functionality:

- **[`manimlib/config.py`](https://github.com/3b1b/manim/blob/main/manimlib/config.py)** – Registers the `‑e/--embed` CLI argument and stores the target line number
- **[`manimlib/extract_scene.py`](https://github.com/3b1b/manim/blob/main/manimlib/extract_scene.py)** – Handles the AST transformation to inject `self.embed()` calls and infers scene names when omitted
- **[`manimlib/scene/scene_embed.py`](https://github.com/3b1b/manim/blob/main/manimlib/scene/scene_embed.py)** – Implements `InteractiveSceneEmbed`, configuring the IPython shell with custom namespaces and GUI hooks
- **[`manimlib/scene/interactive_scene.py`](https://github.com/3b1b/manim/blob/main/manimlib/scene/interactive_scene.py)** – Provides the `embed()` method available on all Scene instances and defines base shortcut behaviors

## Summary

- **The `‑e` flag** triggers Manim's IPython embedding mode, either at a specific line number or at the end of your scene's `construct` method
- **[`manimlib/extract_scene.py`](https://github.com/3b1b/manim/blob/main/manimlib/extract_scene.py)** rewrites your module at runtime to insert `self.embed()` calls before execution begins
- **`InteractiveSceneEmbed`** creates a customized IPython shell with scene-specific shortcuts like `play`, `add`, and `undo`
- **Autoreload support** (`‑e --autoreload`) enables iterative development by reimporting your module before every cell execution
- All interactive features are implemented in [`scene_embed.py`](https://github.com/3b1b/manim/blob/main/scene_embed.py) and [`interactive_scene.py`](https://github.com/3b1b/manim/blob/main/interactive_scene.py), with CLI parsing handled in [`config.py`](https://github.com/3b1b/manim/blob/main/config.py)

## Frequently Asked Questions

### What is the difference between the `-e` and `-p` flags in Manim?

The `‑p` flag plays the rendered video file after compilation using your system's default media player, while the `‑e` flag drops you into an interactive IPython shell during scene execution. Use `‑p` for passive viewing and `‑e` for active debugging and experimentation with live scene objects.

### Can I use embedding mode without specifying a scene name?

Yes. If you provide a line number with `‑e` but omit the scene name, [`manimlib/extract_scene.py`](https://github.com/3b1b/manim/blob/main/manimlib/extract_scene.py) automatically infers the nearest class definition above that line and adds it to the execution list. This is useful when you want to debug a specific section without typing the full class name.

### How do I reload code changes while inside the embedded IPython shell?

If you launched with `‑e ‑‑autoreload`, your module automatically reloads before each IPython cell executes. Otherwise, manually call the `reload()` shortcut function inside the shell to reimport your source file and reflect any changes made to your mobject definitions or animation methods.

### Which keyboard shortcuts are available in Manim's interactive mode?

The embedded shell provides Python shortcuts like `play()`, `add()`, `remove()`, `undo()`, `redo()`, and `clear()`. These are injected into the IPython namespace by `InteractiveSceneEmbed.get_shortcuts` and map directly to your scene instance methods, allowing you to manipulate the canvas without typing `self.` prefixes.