注意
转到末尾下载完整的示例代码。
通过 pgf
后端使用 XeLaTeX/LuaLaTeX 进行文本渲染#
使用 pgf
后端,Matplotlib 可以将图形导出为 pgf 绘图命令,这些命令可以使用 pdflatex、xelatex 或 lualatex 进行处理。XeLaTeX 和 LuaLaTeX 具有完整的 Unicode 支持,并且可以使用操作系统中安装的任何字体,从而利用 OpenType、AAT 和 Graphite 的高级排版功能。通过 plt.savefig('figure.pgf')
创建的 Pgf 图片可以作为原始命令嵌入到 LaTeX 文档中。通过切换后端,也可以将图形直接编译并保存为 PDF,使用 plt.savefig('figure.pdf')
matplotlib.use('pgf')
或者显式请求使用 pgf
后端
plt.savefig('figure.pdf', backend='pgf')
或者注册它来处理 pdf 输出
from matplotlib.backends.backend_pgf import FigureCanvasPgf
matplotlib.backend_bases.register_backend('pdf', FigureCanvasPgf)
最后一种方法允许您继续使用常规的交互式后端,并从图形用户界面保存 xelatex、lualatex 或 pdflatex 编译的 PDF 文件。请注意,在这种情况下,交互式显示仍然会使用标准的交互式后端(例如 QtAgg),并且特别地使用 latex 来编译相关的文本片段。
Matplotlib 的 pgf 支持需要最新的 LaTeX 安装,其中包括 TikZ/PGF 包(例如 TeXLive),最好安装了 XeLaTeX 或 LuaLaTeX。如果您的系统上存在 pdftocairo 或 ghostscript,则也可以选择将图形保存为 PNG 图像。所有应用程序的可执行文件必须位于您的 PATH
中。
控制 pgf 后端行为的 rcParams
参数 |
文档 |
---|---|
pgf.preamble |
包含在 LaTeX 前导码中的行 |
pgf.rcfonts |
使用 fontspec 包从 rc 参数设置字体 |
pgf.texsystem |
可以是“xelatex”(默认)、“lualatex”或“pdflatex” |
注意
TeX 定义了一组特殊字符,例如
# $ % & ~ _ ^ \ { }
一般来说,这些字符必须正确转义。为方便起见,一些字符(_、^、%)在数学环境之外会自动转义。其他字符不会被转义,因为它们通常在实际的 TeX 表达式中需要。但是,可以通过自定义前导码配置 TeX 将它们视为“正常”字符(在 TeX 中称为“catcode 12”),例如
plt.rcParams["pgf.preamble"] = (
r"\AtBeginDocument{\catcode`\&=12\catcode`\#=12}")
多页 PDF 文件#
pgf 后端还支持使用 PdfPages
的多页 pdf 文件
from matplotlib.backends.backend_pgf import PdfPages
import matplotlib.pyplot as plt
with PdfPages('multipage.pdf', metadata={'author': 'Me'}) as pdf:
fig1, ax1 = plt.subplots()
ax1.plot([1, 5, 3])
pdf.savefig(fig1)
fig2, ax2 = plt.subplots()
ax2.plot([1, 5, 3])
pdf.savefig(fig2)
字体规范#
用于获取文本元素大小或将图形编译为 PDF 时使用的字体通常在 rcParams
中定义。您还可以通过清除 rcParams["font.serif"]
(默认值: ['DejaVu Serif', 'Bitstream Vera Serif', 'Computer Modern Roman', 'New Century Schoolbook', 'Century Schoolbook L', 'Utopia', 'ITC Bookman', 'Bookman', 'Nimbus Roman No9 L', 'Times New Roman', 'Times', 'Palatino', 'Charter', 'serif']
), rcParams["font.sans-serif"]
(默认值: ['DejaVu Sans', 'Bitstream Vera Sans', 'Computer Modern Sans Serif', 'Lucida Grande', 'Verdana', 'Geneva', 'Lucid', 'Arial', 'Helvetica', 'Avant Garde', 'sans-serif']
) 或 rcParams["font.monospace"]
(默认值: ['DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Computer Modern Typewriter', 'Andale Mono', 'Nimbus Mono L', 'Courier New', 'Courier', 'Fixed', 'Terminal', 'monospace']
) 的列表来使用 LaTeX 默认的 Computer Modern 字体。请注意,这些字体的字形覆盖范围非常有限。如果您想保留 Computer Modern 字体,但需要扩展的 Unicode 支持,请考虑安装 Computer Modern Unicode 字体 CMU Serif、CMU Sans Serif 等。
当保存为 .pgf
时,Matplotlib 用于图形布局的字体配置会包含在文本文件的头部。
import matplotlib.pyplot as plt
plt.rcParams.update({
"font.family": "serif",
# Use LaTeX default serif font.
"font.serif": [],
# Use specific cursive fonts.
"font.cursive": ["Comic Neue", "Comic Sans MS"],
})
fig, ax = plt.subplots(figsize=(4.5, 2.5))
ax.plot(range(5))
ax.text(0.5, 3., "serif")
ax.text(0.5, 2., "monospace", family="monospace")
ax.text(2.5, 2., "sans-serif", family="DejaVu Sans") # Use specific sans font.
ax.text(2.5, 1., "comic", family="cursive")
ax.set_xlabel("µ is not $\\mu$")
自定义前导码#
通过将您自己的命令添加到前导码中可以实现完全自定义。如果您想配置数学字体(例如使用 unicode-math
)或加载其他包,请使用 rcParams["pgf.preamble"]
(默认值: ''
)。此外,如果您想自己进行字体配置,而不是使用 rc 参数中指定的字体,请确保禁用 rcParams["pgf.rcfonts"]
(默认值: True
)。
import matplotlib as mpl
mpl.use("pgf")
import matplotlib.pyplot as plt
plt.rcParams.update({
"font.family": "serif", # use serif/main font for text elements
"text.usetex": True, # use inline math for ticks
"pgf.rcfonts": False, # don't setup fonts from rc parameters
"pgf.preamble": "\n".join([
r"\usepackage{url}", # load additional packages
r"\usepackage{unicode-math}", # unicode math setup
r"\setmainfont{DejaVu Serif}", # serif font via preamble
])
})
fig, ax = plt.subplots(figsize=(4.5, 2.5))
ax.plot(range(5))
ax.set_xlabel("unicode text: я, ψ, €, ü")
ax.set_ylabel(r"\url{https://matplotlib.net.cn}")
ax.legend(["unicode math: $λ=∑_i^∞ μ_i^2$"])
选择 TeX 系统#
Matplotlib 要使用的 TeX 系统由 rcParams["pgf.texsystem"]
(默认值: 'xelatex'
) 选择。可能的值为 'xelatex'
(默认), 'lualatex'
和 'pdflatex'
。请注意,当选择 pdflatex 时,必须在前导码中配置字体和 Unicode 处理。
import matplotlib.pyplot as plt
plt.rcParams.update({
"pgf.texsystem": "pdflatex",
"pgf.preamble": "\n".join([
r"\usepackage[utf8x]{inputenc}",
r"\usepackage[T1]{fontenc}",
r"\usepackage{cmbright}",
]),
})
fig, ax = plt.subplots(figsize=(4.5, 2.5))
ax.plot(range(5))
ax.text(0.5, 3., "serif", family="serif")
ax.text(0.5, 2., "monospace", family="monospace")
ax.text(2.5, 2., "sans-serif", family="sans-serif")
ax.set_xlabel(r"µ is not $\mu$")
故障排除#
在 Windows 上,可能需要修改
PATH
环境变量,以包含包含 latex、dvipng 和 ghostscript 可执行文件的目录。有关详细信息,请参见 环境变量 和 在 Windows 中设置环境变量。有时,保存为 png 图像的图形中的字体渲染效果非常差。当 pdftocairo 工具不可用并且 ghostscript 用于 pdf 到 png 的转换时,会发生这种情况。
确保您尝试执行的操作在 LaTeX 文档中是可行的,您的 LaTeX 语法有效,并且如果需要,您正在使用原始字符串以避免意外的转义序列。
rcParams["pgf.preamble"]
(默认值:''
) 提供了很大的灵活性,同时也带来了很多可能导致问题的因素。当遇到问题时,请尝试最小化或禁用自定义序言。配置
unicode-math
环境可能会有些棘手。例如,TeXLive 发行版提供了一组通常未在系统范围内安装的数学字体。与 LuaLaTeX 不同,XeLaTeX 无法通过它们的名称找到这些字体,这就是为什么您可能需要指定\setmathfont{xits-math.otf}
而不是\setmathfont{XITS Math}
,或者使字体可用于您的操作系统。有关更多详细信息,请参阅此 tex.stackexchange.com 问题。如果 Matplotlib 使用的字体配置与您的 LaTeX 文档中的字体设置不同,则导入的图形中文本元素的对齐方式可能会出现偏差。如果您不确定 Matplotlib 用于布局的字体,请检查您的
.pgf
文件的头部。如果图形中有很多对象,矢量图像和
.pgf
文件可能会变得臃肿。图像处理或非常大的散点图可能会出现这种情况。在极端情况下,这可能导致 TeX 内存不足:“TeX 容量超出,抱歉”。您可以配置 latex 以增加可用于生成.pdf
图像的内存量,如 tex.stackexchange.com 上所讨论的那样。另一种方法是使用rasterized=True
关键字或.set_rasterized(True)
来“栅格化”导致问题的图形部分,如 此示例 所示。只有在加载相应的字体包后,才会编译和渲染各种数学字体。具体而言,在希腊字母上使用
\mathbf{}
时,默认的计算机现代字体可能不包含它们,在这种情况下,字母不会被渲染。在这种情况下,应加载lmodern
包。如果您仍然需要帮助,请参阅 获取帮助。