呈现文本和公式#
有两种不同的方法可以在视频中渲染Text文本 :
-
Using Pango (
text_mobject
) -
Using LaTeX (
tex_mobject
)
如果您想呈现简单的文本,您应该使用 Text
或 MarkupText
,或者其中的一个派生类,比如 Paragraph
。
有关更多信息,请参阅 Text
Without
LaTeX。
当您需要进行数学排版时,应使用 LaTeX。有关更多信息,请参阅 Text With LaTeX。
没有 LaTeX 的文本#
向动画中添加文本的最简单方法是使用Text
类。
它使用 Pango 库来呈现文本。
使用 Pango,您还可以呈现像“你好 or こんにちは or 안녕하세요 or
مرحبا بالعالم.”等非英文字母的文本。
这是一个简单的 Hello World 动画.
Example: HelloWorld ¶
from manim import *
class HelloWorld(Scene):
def construct(self):
text = Text("Hello world", font_size=144)
self.add(text)
References: Text
您还可以使用 MarkupText
,
它允许使用 PangoMarkup(有关详细信息,请参阅 MarkupText
的文档)来呈现文本。例如:
Example: SingleLineColor ¶
from manim import *
class SingleLineColor(Scene):
def construct(self):
text = MarkupText(
f'all in red <span fgcolor="{YELLOW}">except this</span>', color=RED
)
self.add(text)
References: MarkupText
处理 Text
#
本节将解释 Text
的属性以及如何在您的动画中使用它。
使用 Fonts#
您可以使用 font
属性设置不同的字体。
Note
使用的字体必须已安装在您的系统中,并且 Pango 应该知道它。您可以使用 manimpango.list_fonts()
获取字体列表。
>>> import manimpango
>>> manimpango.list_fonts()
[...]
Example: FontsExample ¶
from manim import *
class FontsExample(Scene):
def construct(self):
ft = Text("Noto Sans", font="Noto Sans")
self.add(ft)
设置字体的斜体和加粗(Slant and Weight)#
斜体(Slant)是 Text 的样式,可以是 NORMAL
(默认值), ITALIC
或 OBLIQUE
。通常,对于许多字体,ITALIC
和 OBLIQUE
看起来相似,但是 ITALIC
使用 Roman
Style,而 OBLIQUE
使用 Italic Style。
Weight 指定字体的加粗程度。您可以在 manimpango.Weight
中查看权重列表。
Example: SlantsExample ¶
from manim import *
class SlantsExample(Scene):
def construct(self):
a = Text("Italic", slant=ITALIC)
self.add(a)
Example: DifferentWeight ¶
from manim import *
class DifferentWeight(Scene):
def construct(self):
import manimpango
g = VGroup()
weight_list = dict(
sorted(
{
weight: manimpango.Weight(weight).value
for weight in manimpango.Weight
}.items(),
key=lambda x: x[1],
)
)
for weight in weight_list:
g += Text(weight.name, weight=weight.name, font="Open Sans")
self.add(g.arrange(DOWN).scale(0.5))
使用 Colors#
您可以使用color
属性设置文本的颜色:
Example: SimpleColor ¶
from manim import *
class SimpleColor(Scene):
def construct(self):
col = Text("RED COLOR", color=RED)
self.add(col)
您可以使用像 t2c
这样的工具为特定字符着色。如果您的文本包含如迭代文本所述的Iterating Text连字,则可能会出现问题。
t2c
接受两种类型的字典,
-
键可以包含类似
[2:-1]
或[4:8]
的索引, 这类似于 Python 中的slicing切片工作原理。值应该是来自Color
的 Text 的颜色。 -
键包含应单独着色的单词或字符,而值应该是来自
Color
的颜色:
Example: Textt2cExample ¶
from manim import *
class Textt2cExample(Scene):
def construct(self):
t2cindices = Text('Hello', t2c={'[1:-1]': BLUE}).move_to(LEFT)
t2cwords = Text('World',t2c={'rl':RED}).next_to(t2cindices, RIGHT)
self.add(t2cindices, t2cwords)
如果您想避免使用颜色时出现问题(由于连字),请考虑使用 MarkupText
。
使用渐变(Gradients) #
您可以使用gradient
属性添加渐变。值必须是任意长度的可迭代对象:
Example: GradientExample ¶
from manim import *
class GradientExample(Scene):
def construct(self):
t = Text("Hello", gradient=(RED, BLUE, GREEN), font_size=96)
self.add(t)
您还可以使用 t2g
为文本的特定字符创建渐变。它具有与the
interface for colors颜色接口类似的语法:
Example: t2gExample ¶
from manim import *
class t2gExample(Scene):
def construct(self):
t2gindices = Text(
'Hello',
t2g={
'[1:-1]': (RED,GREEN),
},
).move_to(LEFT)
t2gwords = Text(
'World',
t2g={
'World':(RED,BLUE),
},
).next_to(t2gindices, RIGHT)
self.add(t2gindices, t2gwords)
设置行距(Setting Line Spacing) #
您可以使用 line_spacing
属性设置行距:
Example: LineSpacing ¶
from manim import *
class LineSpacing(Scene):
def construct(self):
a = Text("Hello\nWorld", line_spacing=1)
b = Text("Hello\nWorld", line_spacing=4)
self.add(Group(a,b).arrange(LEFT, buff=5))
禁用连字(Disabling Ligatures) #
通过禁用连字,您将获得字符和子对象之间的一对一映射。这解决了对文本进行着色的问题。
Warning
请注意,对于严重依赖连字的文本(如阿拉伯文本),使用此方法可能会产生意外的结果。
您可以通过将 disable_ligatures
传递给 Text
来禁用连字。例如:
Example: DisableLigature ¶
from manim import *
class DisableLigature(Scene):
def construct(self):
li = Text("fl ligature",font_size=96)
nli = Text("fl ligature", disable_ligatures=True, font_size=96)
self.add(Group(li, nli).arrange(DOWN, buff=.8))
迭代文本(Iterating Text
)#
Text 对象的行为类似于VGroups
。
因此,您可以对文本进行切片和索引。
例如,您可以通过迭代文本的每个字母来将它们设置为不同的颜色。
Example: IterateColor ¶
from manim import *
class IterateColor(Scene):
def construct(self):
text = Text("Colors", font_size=96)
for letter in text:
letter.set_color(random_bright_color())
self.add(text)
Warning
请注意,这里Ligature连字可能会导致问题。
如果您需要一个字符到子对象的一对一映射,您应该将 disable_ligatures
参数传递给
Text
。请参阅Disabling
Ligatures禁用连字。
使用 MarkupText
#
MarkupText 与 Text
相似,
它们之间唯一的区别在于 MarkupText 接受并处理 PangoMarkup(类似于 HTML),而不仅仅呈现纯文本。
有关 PangoMarkup 的更多详细信息和更多参考,请参阅MarkupText
的文档。
Example: MarkupTest ¶
from manim import *
class MarkupTest(Scene):
def construct(self):
text = MarkupText(
f'<span underline="double" underline_color="green">double green underline</span> in red text<span fgcolor="{YELLOW}"> except this</span>',
color=RED,
font_size=34
)
self.add(text)
使用 LaTeX 的文本#
就像您可以使用 Text 向视频中添加文本一样,您可以使用 Tex
插入
LaTeX。
比如,
Example: HelloLaTeX ¶
from manim import *
class HelloLaTeX(Scene):
def construct(self):
tex = Tex(r"\LaTeX", font_size=144)
self.add(tex)
注意
请注意,我们使用原始字符串(r'...'
)而不是常规字符串('...'
)。
这是因为 TeX 代码使用了许多特殊字符 - 例如 \
- 它们在常规 Python
字符串中具有特殊含义。另一种选择是使用 \\
转义反斜杠:Tex('\\LaTeX')
。
使用MathTex
#
默认情况下,传递给 MathTex
的所有内容都处于数学模式下。
更精确地说,
MathTex
在 align*
环境中进行处理。
您可以使用 $ 符号将您的公式括在其中,在 Tex
中实现类似的效果:$
符号:
$\xrightarrow{x^6y^8}$
:
Example: MathTeXDemo ¶
from manim import *
class MathTeXDemo(Scene):
def construct(self):
rtarrow0 = MathTex(r"\xrightarrow{x^6y^8}", font_size=96)
rtarrow1 = Tex(r"$\xrightarrow{x^6y^8}$", font_size=96)
self.add(VGroup(rtarrow0, rtarrow1).arrange(DOWN))
LaTeX 命令和关键字参数#
我们可以在 AMS 数学包中使用任何标准 LaTeX 命令,例如 mathtt
数学文本类型或 looparrowright
箭头。
Example: AMSLaTeX ¶
from manim import *
class AMSLaTeX(Scene):
def construct(self):
tex = Tex(r'$\mathtt{H} \looparrowright$ \LaTeX', font_size=144)
self.add(tex)
在 Manim 方面,Tex
类还接受属性来更改输出的外观。
这与 Text
类非常相似。
例如,color
关键字可以更改 TeX
mobject 的颜色。
Example: LaTeXAttributes ¶
from manim import *
class LaTeXAttributes(Scene):
def construct(self):
tex = Tex(r'Hello \LaTeX', color=BLUE, font_size=144)
self.add(tex)
额外的 LaTeX 包#
有些命令需要将特殊的包加载到 TeX 模板中。
例如,要使用 mathscr
字体,我们需要添加mathrsfs
包。由于此包默认未加载到 Manim 的 TeX 模板中,因此我们需要手动添加它。
Example: AddPackageLatex ¶
from manim import *
class AddPackageLatex(Scene):
def construct(self):
myTemplate = TexTemplate()
myTemplate.add_to_preamble(r"\usepackage{mathrsfs}")
tex = Tex(
r"$\mathscr{H} \rightarrow \mathbb{H}$}",
tex_template=myTemplate,
font_size=144,
)
self.add(tex)
子字符串和部分 #
TeX mobject 可以接受多个字符串作为参数。之后,您可以通过它们的索引(例如 tex[1]
)或选择 tex
代码的部分来引用各个部分。在这个例子中,我们使用 set_color_by_tex()
来设置
\bigstar
的颜色:
Example: LaTeXSubstrings ¶
from manim import *
class LaTeXSubstrings(Scene):
def construct(self):
tex = Tex('Hello', r'$\bigstar$', r'\LaTeX', font_size=144)
tex.set_color_by_tex('igsta', RED)
self.add(tex)
请注意,set_color_by_tex()
会着色包含 Tex 的整个子字符串,
而不仅仅是特定的符号或 Tex 表达式。请考虑以下示例:
Example: IncorrectLaTeXSubstringColoring ¶
from manim import *
class IncorrectLaTeXSubstringColoring(Scene):
def construct(self):
equation = MathTex(
r"e^x = x^0 + x^1 + \frac{1}{2} x^2 + \frac{1}{6} x^3 + \cdots + \frac{1}{n!} x^n + \cdots"
)
equation.set_color_by_tex("x", YELLOW)
self.add(equation)
正如您所看到的,这将整个等式着成了黄色,而不是预期的结果。为了仅将 x
着色为黄色,我们需要执行以下操作:
Example: CorrectLaTeXSubstringColoring ¶
from manim import *
class CorrectLaTeXSubstringColoring(Scene):
def construct(self):
equation = MathTex(
r"e^x = x^0 + x^1 + \frac{1}{2} x^2 + \frac{1}{6} x^3 + \cdots + \frac{1}{n!} x^n + \cdots",
substrings_to_isolate="x"
)
equation.set_color_by_tex("x", YELLOW)
self.add(equation)
通过将substrings_to_isolate
设置为
x
,我们自动将
MathTex
分解为子字符串,并将
x
组件分离为单独的子字符串。只有在这种情况下,
set_color_by_tex()
才能用于实现所需的结果。
请注意,Manim 还支持一种自定义语法,可以轻松将 TeX 字符串拆分为子字符串:只需用双括号括起要隔离的公式部分即可。
在字符串 MathTex(r"{{ a^2 }} + {{ b^2 }} = {{ c^2 }}")
,
中,渲染的
mobject 将包含子字符串 a^2
,
+
, b^2
, =
, 和 c^2
。这使得使用 TransformMatchingTex
在类似文本片段之间进行转换变得更加容易。
使用 index_labels 处理复杂字符串#
有时您可能正在处理非常复杂的 MathTex
,这使得难以处理其各个组件。这就是调试函数 index_labels()
非常有用的地方。
该方法显示 mobject 的子对象的索引,使您可以轻松找到要更改的 mobject 组件。
Example: IndexLabelsMathTex ¶
from manim import *
class IndexLabelsMathTex(Scene):
def construct(self):
text = MathTex(r"\binom{2n}{n+2}", font_size=96)
# index the first (and only) term of the MathTex mob
self.add(index_labels(text[0]))
text[0][1:3].set_color(YELLOW)
text[0][3:6].set_color(RED)
self.add(text)
LaTeX 数学字体 - 模板库#
在排版数学公式时更改 LaTeX 字体比普通文本更棘手。这需要更改用于编译 TeX 的模板。
Manim 提供了一系列 TexFontTemplates
,供您使用。这些模板都可以在数学模式下使用:
Example: LaTeXMathFonts ¶
from manim import *
class LaTeXMathFonts(Scene):
def construct(self):
tex = Tex(
r"$x^2 + y^2 = z^2$",
tex_template=TexFontTemplates.french_cursive,
font_size=144,
)
self.add(tex)
Manim 还有一个 TexTemplateLibrary
,
其中包含 3Blue1Brown 使用的 TeX 模板。其中一个示例是用于排版中文的 ctex 模板。
为此,您的系统必须安装 ctex LaTeX 包。此外,如果您只需要排版文本,可能根本不需要 Tex
,应该使用 Text
。
Example: LaTeXTemplateLibrary ¶
from manim import *
class LaTeXTemplateLibrary(Scene):
def construct(self):
tex = Tex('Hello 你好 \\LaTeX', tex_template=TexTemplateLibrary.ctex, font_size=144)
self.add(tex)
对齐公式(Aligning formulae)#
MathTex
mobject 是在 LaTeX align*
环境中排版的。这意味着在排版多行公式时,您可以使用 &
对齐字符:
Example: LaTeXAlignEnvironment ¶
from manim import *
class LaTeXAlignEnvironment(Scene):
def construct(self):
tex = MathTex(r'f(x) &= 3 + 2 + 1\\ &= 5 + 1 \\ &= 6', font_size=96)
self.add(tex)