How to Use TextMobject and Manage Fonts for Text Rendering in Manim
Manim renders vector-based text using the Pango library via manimpango, where the Text class (historically referred to as TextMobject) inherits from MarkupText in manimlib/mobject/svg/text_mobject.py and resolves fonts through a three-tier hierarchy of global configuration, scene-level overrides, and per-instance constructor arguments.
The 3b1b/manim repository (Grant Sanderson’s original animation engine) handles text rendering through a sophisticated SVG-based pipeline. Whether you are displaying mathematical explanations or UI labels, understanding how to use the Text class and manage font selection is essential for crisp, scalable typography in your animations.
Understanding the Text Class Hierarchy
Manim’s text system is built on a chain of inheritance that converts strings into SVG paths. The core implementation lives in manimlib/mobject/svg/text_mobject.py.
Text, MarkupText, and StringMobject
The hierarchy flows from SVGMobject down to concrete text classes:
StringMobject– Base class for string-based SVG mobjects.MarkupText– Inherits fromStringMobject. It builds an SVG by converting a Pango markup string viamarkup_to_svg(see lines 53‑62).Text– Inherits fromMarkupText. It overrides the markup parsing to treat input as plain text, escaping only the markup characters (see the overridden static methods at lines 21‑35).
This architecture means Text objects are ultimately collections of VMobject paths derived from font glyphs, allowing for standard Manim transforms like Write, FadeIn, and complex color mapping.
Font Resolution and Configuration
Font selection in Manim operates through a cascading priority system defined in the __init__ method of MarkupText around lines 68‑78.
Global Defaults in default_config.yml
The base font configuration resides in manimlib/default_config.yml at lines 88‑90:
text:
font: "Consolas"
alignment: "LEFT"
By default, all Text objects render using Consolas unless overridden.
Per-Scene and Instance Overrides
You can override fonts at two additional levels:
- Scene-level – Modify
manim_config.text.fontat runtime or via a custom--config_file:
from manimlib import *
config.text.font = "Times New Roman"
class Example(Scene):
def construct(self):
# This uses Times New Roman by default
t = Text("Scene Default Font")
self.add(t)
- Instance-level – Pass
font="Font Name"directly to the constructor. This takes highest priority (see line 75 whereself.font = font or text_config.font):
Text("Override Example", font="Arial")
Registering Custom Font Files
Manim does not ship with every system font. To use a custom TTF or OTF file that is not installed system-wide, use the register_font context manager defined at lines 69‑99 in the same file.
This context manager temporarily adds the font file to Pango’s search path:
from manimlib import *
class CustomFontScene(Scene):
def construct(self):
with register_font("fonts/UbuntuMono-R.ttf"):
# "Ubuntu Mono" must match the font family name inside the TTF
text = Text(
"Custom Font Rendering",
font="Ubuntu Mono",
t2f={"Custom": "Comic Sans MS"} # Mix fonts within text
)
self.play(Write(text))
Critical note: The string passed to font= must match the font family name embedded in the TTF metadata, not the filename.
Text Scaling and Alignment
Scaling Calibration
The size of a Text object is calibrated so that a reference glyph "0" has a height of 1 Manim unit. This scaling factor is calculated by get_text_mob_scale_factor at lines 103‑113.
When you call .scale(2), the text doubles in size relative to this calibrated baseline.
Alignment Options
Horizontal alignment defaults to the config value (text.alignment) but can be overridden per object via the alignment parameter:
"LEFT"(default)"CENTER""RIGHT"
Text("Right aligned", alignment="RIGHT").to_corner(DR)
For multiline text, control vertical spacing with lsh (line spacing height):
Text("Line 1\nLine 2", lsh=1.5) # 1.5x default spacing
Styling Shortcuts for Text
The Text class supports dictionary-based styling that maps text selectors to visual properties. These are applied after SVG generation (see get_configured_items at lines 98‑116):
t2c– Text to colort2f– Text to fontt2g– Text to gradientt2s– Text to slant (ITALIC, NORMAL, OBLIQUE)t2w– Text to weight (BOLD, THIN, etc.)
Text(
"Colorful Bold Manim",
t2c={"Colorful": BLUE, "Manim": RED},
t2w={"Bold": BOLD},
t2f={"Manim": "Times New Roman"}
)
Summary
- Inheritance chain:
Text→MarkupText→StringMobjectinmanimlib/mobject/svg/text_mobject.py, converting strings to SVG paths via Pango. - Font resolution: Three-tier priority system—global config (
default_config.yml), scene override (config.text.font), and instance argument (font="Name"). - Custom fonts: Use the
register_fontcontext manager to temporarily load TTF/OTF files not installed system-wide. - Scaling: Reference glyph
"0"equals 1 Manim unit; usealignmentandlshfor positioning and line spacing. - Styling: Apply
t2c,t2f,t2g,t2s, andt2wdictionaries for per-word formatting.
Frequently Asked Questions
What is the difference between Text and TextMobject in Manim?
In the 3b1b/manim repository (ManimGL), the modern class is Text, which inherits from MarkupText. Earlier versions and the community edition (ManimCE) historically used TextMobject for LaTeX-based text and Text for Pango-based rendering. In current ManimGL, Text is the standard class for plain text rendering using system fonts via Pango.
How do I use a custom TTF font that is not installed on my system?
Wrap your Text instantiation in the register_font context manager imported from manimlib.mobject.svg.text_mobject. Pass the path to your .ttf or .otf file as the argument. Inside the context block, reference the font by its family name (as defined in the font metadata) in the font parameter of Text.
Why is my text appearing as squares or not rendering correctly?
Squares typically indicate missing glyph coverage or font not found. Verify that the font name passed to font= exactly matches the family name in the font file metadata (not the filename). If using a custom font file, ensure you are using register_font. Additionally, check that manimpango and Pango are properly installed in your environment, as these are required for SVG text generation.
How do I change the default font for all text in a scene?
Modify the config.text.font attribute before constructing your Text objects. You can set this in your scene’s __init__ or at the module level: config.text.font = "Arial". Alternatively, create a custom default_config.yml and pass it via the --config_file CLI argument to override the global defaults defined in manimlib/default_config.yml.
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 →