How to Render LaTeX Equations and Text Using TexMobject in Manim Animations
Manim renders LaTeX by converting strings to SVG images through external compilers, wrapping them in the Tex class that handles scaling, coloring, and symbol isolation for animation.
In the 3b1b/manim library, mathematical typesetting is powered by the Tex class (historically referred to as TexMobject) defined in manimlib/mobject/svg/tex_mobject.py. This Mobject compiles LaTeX source into scalable vector graphics, enabling precise control over individual symbols and seamless integration with Manim's animation system.
The LaTeX-to-SVG Architecture
Manim's LaTeX rendering relies on three coordinated components that transform raw strings into animatable Mobjects.
Core Components
-
Texclass (manimlib/mobject/svg/tex_mobject.py, lines 35-78): The high-level interface that parses LaTeX strings, manages color mappings, and scales the resulting SVG to match Manim's coordinate system. -
latex_to_svg(manimlib/utils/tex_file_writing.py, lines 40-82): The low-level utility that orchestrates the external compilation pipeline, converting LaTeX → DVI → SVG. -
tex_templates.yml(manimlib/tex_templates.yml): Configuration file defining compiler presets (e.g.,default,xelatex,tikz) and preamble settings.
The Compilation Pipeline
When you instantiate Tex(r"E=mc^2"), the following sequence occurs:
-
String Processing: The
Tex.__init__method (lines 38-79) stores the raw LaTeX string and merges thetex_to_color_mapdictionary with legacyt2carguments (line 67). -
SVG Generation: The method
get_svg_string_by_contentforwards the string tolatex_to_svg(lines 81-83), which builds a temporary LaTeX document viaget_full_tex. -
External Compilation:
latex_to_svg(lines 50-82) selects a compiler and preamble fromget_tex_config, writes the temporary file, invokes the LaTeX compiler anddvisvgm, and returns the SVG string. -
Scaling Calibration: The resulting Mobject is scaled by
get_tex_mob_scale_factor() * font_size(lines 77-78). This factor is computed by rendering a reference "0" and measuring its height, ensuring afont_sizeof 48 yields a height of 1 Manim unit. -
Color Injection: The
set_color_by_tex_to_color_mapmethod (line 76) parses the LaTeX source to find matching spans and injects\color[RGB]{…}commands viaget_color_commandandget_command_string.
Configuring Templates and Unicode Support
The template argument (line 44) allows switching between LaTeX engines without modifying source code. This is essential for Unicode support or TikZ graphics.
from manim import *
class UnicodeExample(Scene):
def construct(self):
text = Tex(
r"\text{Привет, мир!}",
template="xelatex" # Uses xelatex compiler from tex_templates.yml
)
self.play(Write(text))
self.wait()
The tex_templates.yml file defines the compiler path, preamble packages, and font settings for each template name.
Isolating Symbols for Granular Animation
The isolate argument (lines 51-56) marks specific substrings as separate sub-Mobjects, enabling individual symbol animation.
class IsolateExample(Scene):
def construct(self):
expr = Tex(r"x^2 + y^2 = r^2", isolate=["x", "y", "r"])
x, y, r = expr.get_parts_by_tex(["x", "y", "r"])
self.play(Write(expr))
self.play(
x.animate.shift(UP),
y.animate.shift(LEFT),
r.animate.scale(2)
)
self.wait()
Each isolated part becomes its own sub-Mobject accessible via get_parts_by_tex, allowing targeted transformations.
Coloring Mathematical Expressions
Use tex_to_color_map to apply colors to specific symbols without manual index tracking. The class automatically injects color commands into the generated LaTeX.
class ColorMapExample(Scene):
def construct(self):
formula = Tex(
r"\frac{a}{b} = c",
tex_to_color_map={"a": RED, "b": BLUE, "c": GREEN}
)
self.play(FadeIn(formula))
self.wait()
Performance Optimization Through Caching
Both latex_to_svg and get_tex_mob_scale_factor are decorated with @lru_cache (as implemented in manimlib/utils/tex_file_writing.py). Identical LaTeX strings compile only once per session, dramatically reducing render times for repeated equations.
Handling Edge Cases
The Tex class includes safeguards for common LaTeX issues:
- Empty Strings: Automatically substitutes a dummy line break (
\\) to prevent LaTeX compilation errors (lines 59-62). - Alignment Environments: Supports standard LaTeX environments like
align*through the raw string interface.
class AlignExample(Scene):
def construct(self):
system = Tex(r"""
\begin{align*}
a &= b + c \\
d &= e - f
\end{align*}
""", font_size=72)
self.play(FadeIn(system))
self.wait()
Summary
- Manim's
Texclass (located inmanimlib/mobject/svg/tex_mobject.py) converts LaTeX strings to SVG via external compilers. - The
latex_to_svgutility inmanimlib/utils/tex_file_writing.pyhandles the LaTeX → DVI → SVG pipeline with LRU caching for performance. - Scaling is calibrated automatically so that
font_size=48equals 1 Manim unit height. tex_to_color_mapinjects color commands automatically;isolatecreates separate sub-Mobjects for individual symbol animation.- Templates defined in
manimlib/tex_templates.ymlenable switching between compilers (e.g.,xelatexfor Unicode) via thetemplateargument.
Frequently Asked Questions
What is the difference between Tex and TexMobject in Manim?
In the 3b1b/manim library, the class is named Tex and is defined in manimlib/mobject/svg/tex_mobject.py. Older documentation and community versions often refer to this functionality as "TexMobject," but the modern implementation uses the Tex class with an improved API including tex_to_color_map and isolate parameters.
Why is my LaTeX compilation slow on the first run?
Manim must invoke external LaTeX compilers and dvisvgm to generate SVG files. However, the latex_to_svg function uses @lru_cache to store results. Subsequent uses of identical LaTeX strings retrieve the cached SVG instantly, eliminating compilation overhead.
How do I use Unicode characters or custom fonts in Manim equations?
Pass template="xelatex" to the Tex constructor. This selects the XeLaTeX compiler configuration from manimlib/tex_templates.yml, which supports Unicode input and system fonts. Ensure your LaTeX installation includes xelatex and the necessary font packages.
Can I animate individual parts of a fraction or subscript?
Yes. Use the isolate parameter when creating the Tex object, passing a list of strings to treat as separate sub-Mobjects. For example, Tex(r"\frac{a}{b}", isolate=["a", "b"]) allows you to target the numerator and denominator independently via get_parts_by_tex("a") and standard animation methods.
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 →