通过更改字体嵌入来减小使用 matplotlib 创建的 PDF 的文件大小

Xen*_*non 2 python pdf fonts matplotlib font-embedding

我正在使用 matplotlib 生成 PDF 图形。然而,即使是最简单的数字也会产生相对较大的文件,下面的 MWE 会产生几乎 1 MB 的文件。我意识到文件大小较大是由于 matplotlib 完全嵌入了所有使用的字体。由于我要生成相当多的图并希望减小文件大小,所以我想知道:

主要问题:

有没有办法让 matplotlib 嵌入字体子集而不是完整的字体?我也可以完全不包含字体。

到目前为止考虑的事情:

  • 矢量图形编辑器可轻松用于导出包含字体子集(以及根本不包含字体)的 PDF,但必须对每个文件(修订版)执行此步骤显得不必要的乏味。
  • 同样,我读过有关 PDF 文件后处理的内容(例如使用 Ghostscript),尽管工作量似乎相当。
  • 我尝试设置 'pdf.fonttype'= 3,这确实会产生相当小的文件。但是,我想在矢量图形编辑器中保持文本可修改 - 这在这种情况下似乎不起作用(例如减号不会保存为文本)。

由于使用外部软件生成带有嵌入子集的文件很容易,尽管是劳动密集型的,是否有可能直接在 matplotlib 中实现这一点?任何帮助将不胜感激。

微量元素

import matplotlib.pyplot as plt #Setup
import matplotlib as mpl
mpl.rcParams['pdf.fonttype'] = 42
mpl.rcParams['mathtext.fontset'] = 'dejavuserif'
mpl.rc('font',family='Arial',size=12)

fig,ax=plt.subplots(figsize=(2,2)) #Create a figure containing some text
ax.semilogy(1,1,'s',label='Text\n$M_\mathrm{ath}$')
ax.legend()
fig.tight_layout()
fig.savefig('test.pdf')
Run Code Online (Sandbox Code Playgroud)

环境:matplotlib 3.1.1

ole*_*rog 6

PGF后端有助于显着减小 PDF 文件大小。只需添加mpl.use('pgf')到您的代码中即可。在我的环境中,此修改导致以下结果:

  • 文件大小从 817K 减小到 21K(小了 40 倍!)。
  • 执行时间从1s增加到3s。

然而,对于真实的图形,执行时间通常会随着文件大小的增加而减少。

PDF 大小的减小归因于嵌入字体子集。

$ pdffonts pdf_backend.pdf
name                         type              emb sub uni prob object ID
---------------------------- ----------------- --- --- --- ---- ---------
ArialMT                      CID TrueType      yes no  yes          14  0
DejaVuSerif-Italic           CID TrueType      yes no  yes          23  0
DejaVuSerif                  CID TrueType      yes no  yes          32  0
Run Code Online (Sandbox Code Playgroud)
$ pdffonts pgf_backend.pdf
name                         type              emb sub uni prob object ID
---------------------------- ----------------- --- --- --- ---- ---------
KECVVY+ArialMT               CID TrueType      yes yes yes           7  0
EFAAMX+CMR12                 Type 1C           yes yes yes           8  0
EHYQVR+CMSY8                 Type 1C           yes yes yes           9  0
UVNOSL+CMR8                  Type 1C           yes yes yes          10  0
FDPQQI+CMMI12                Type 1C           yes yes yes          11  0
DGIYWD+DejaVuSerif           CID TrueType      yes yes yes          13  0
Run Code Online (Sandbox Code Playgroud)

另一种选择是生成 EPS 文件(使用 PostScript 后端)并将其转换为 PDF 格式,例如通过epstopdf(使用 GhostScript 解释器)。这样PDF文件就减少到9K了。但值得注意的是,PS后端不支持透明。