通过 pgf 后端使用 XeLaTeX/LuaLaTeX 进行文本渲染#

使用 pgf 后端,Matplotlib 可以将图形导出为 pgf 绘图命令,这些命令可以使用 pdflatex、xelatex 或 lualatex 处理。XeLaTeX 和 LuaLaTeX 具有完整的 Unicode 支持,可以使用操作系统中安装的任何字体,利用 OpenType、AAT 和 Graphite 的高级排版功能。由 plt.savefig('figure.pgf') 创建的 Pgf 图片可以作为原始命令嵌入 LaTeX 文档中。图形也可以直接编译并保存为 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 中。

rcParams 控制 pgf 后端的行为

参数

文档

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)

字体规范#

The fonts used for obtaining the size of text elements or when compiling figures to PDF are usually defined in the rcParams. You can also use the LaTeX default Computer Modern fonts by clearing the lists for rcParams["font.serif"] (default: ['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"] (default: ['DejaVu Sans', 'Bitstream Vera Sans', 'Computer Modern Sans Serif', 'Lucida Grande', 'Verdana', 'Geneva', 'Lucid', 'Arial', 'Helvetica', 'Avant Garde', 'sans-serif']) or rcParams["font.monospace"] (default: ['DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Computer Modern Typewriter', 'Andale Mono', 'Nimbus Mono L', 'Courier New', 'Courier', 'Fixed', 'Terminal', 'monospace']). Please note that the glyph coverage of these fonts is very limited. If you want to keep the Computer Modern font face but require extended Unicode support, consider installing the Computer Modern Unicode fonts CMU Serif, CMU Sans Serif, etc.

当保存为 .pgf 时,Matplotlib 用于图形布局的字体配置将包含在文本文件头中。

"""
=========
PGF fonts
=========
"""

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$")

fig.tight_layout(pad=.5)

自定义序言#

可以通过在序言中添加自己的命令来实现完全自定义。使用 rcParams["pgf.preamble"](默认值:'')如果您想配置数学字体,例如使用 unicode-math,或加载其他包。此外,如果您想自己进行字体配置,而不是使用 rc 参数中指定的字体,请确保禁用 rcParams["pgf.rcfonts"](默认值:True)。

"""
============
PGF preamble
============
"""

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$"])

fig.tight_layout(pad=.5)

选择 TeX 系统#

Matplotlib 要使用的 TeX 系统由 rcParams["pgf.texsystem"](默认值:'xelatex')选择。可能的值是 'xelatex'(默认值)、'lualatex''pdflatex'。请注意,当选择 pdflatex 时,必须在序言中配置字体和 Unicode 处理。

"""
=============
PGF texsystem
=============
"""

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$")

fig.tight_layout(pad=.5)

故障排除#

  • 请注意,某些 Linux 发行版和 MiKTeX 安装中找到的 TeX 包已过时。请确保更新您的软件包目录并升级或安装最新的 TeX 发行版。

  • 在 Windows 上,PATH 环境变量可能需要修改以包含包含 latex、dvipng 和 ghostscript 可执行文件的目录。有关详细信息,请参阅 环境变量在 Windows 中设置环境变量

  • 有时,保存为 png 图像的图形中的字体渲染非常糟糕。当 pdftocairo 工具不可用且 ghostscript 用于 pdf 到 png 转换时,就会发生这种情况。

  • 确保您尝试执行的操作在 LaTeX 文档中是可能的,您的 LaTeX 语法有效,并且在必要时使用原始字符串以避免意外的转义序列。

  • rcParams["pgf.preamble"](默认值:'')提供了很大的灵活性,但也存在很多导致问题的方式。当遇到问题时,请尝试最小化或禁用自定义序言。

  • 配置unicode-math环境可能有点棘手。例如,TeXLive 发行版提供了一组通常不会在系统范围内安装的数学字体。XeTeX 与 LuaLatex 不同,它无法通过名称找到这些字体,这就是为什么您可能需要指定\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包。

  • 如果您仍然需要帮助,请参阅 获取帮助

由 Sphinx-Gallery 生成的图库