通过 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 支持需要一个包含 TikZ/PGF 包的最新 LaTeX 安装(例如 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"] (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']) 或 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']) 的列表来使用LaTeX默认的Computer Modern字体。请注意,这些字体的字形覆盖范围非常有限。如果你想保留Computer Modern字体外观但需要扩展的Unicode支持,可以考虑安装 Computer Modern Unicode 字体 CMU SerifCMU 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"] (default: '')。此外,如果你想自己进行字体配置,而不是使用rc参数中指定的字体,请确保禁用 rcParams["pgf.rcfonts"] (default: 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.org}")
ax.legend(["unicode math: $λ=∑_i^∞ μ_i^2$"])

选择 TeX 系统#

Matplotlib 使用的 TeX 系统由 rcParams["pgf.texsystem"] (default: '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"] (default: '') 提供了很大的灵活性,但也提供了很多可能导致问题的方式。遇到问题时,尝试最小化或禁用自定义预设。

  • 配置 unicode-math 环境可能有点棘手。例如,TeXLive 发行版提供了一套通常不会系统范围安装的数学字体。与 LuaLaTeX 不同,XeLaTeX 无法通过名称找到这些字体,这就是为什么你可能需要指定 \setmathfont{xits-math.otf} 而不是 \setmathfont{XITS Math},或者将字体提供给你的操作系统。更多详情请参见此 tex.stackexchange.com 问题

  • 如果 Matplotlib 使用的字体配置与您的 LaTeX 文档中的字体设置不同,导入图形中的文本元素对齐可能会出现问题。如果您不确定 Matplotlib 用于布局的字体,请检查您的 .pgf 文件的头部。

  • 矢量图像,因此 .pgf 文件,如果图中有大量对象,可能会变得臃肿。对于图像处理或非常大的散点图,这种情况可能会发生。在极端情况下,这可能会导致 TeX 内存不足:“TeX capacity exceeded, sorry”。您可以配置 latex 以增加可用内存量来生成 .pdf 图像,如 tex.stackexchange.com 中所讨论的。另一种方法是使用 rasterized=True 关键字或 .set_rasterized(True) 根据 此示例 对导致问题的图形部分进行“光栅化”。

  • 各种数学字体只有在加载了相应的字体包后才会被编译和渲染。具体来说,当对希腊字母使用 \mathbf{} 时,默认的计算机现代字体可能不包含这些字母,在这种情况下字母不会被渲染。在这种场景下,应加载 lmodern 包。

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

由 Sphinx-Gallery 生成的图库