首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >通过更改字体嵌入来减少使用matplotlib创建的PDF的文件大小

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

Stack Overflow用户
提问于 2020-02-05 12:37:36
回答 2查看 1.9K关注 0票数 2

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

主要问题:

是否有办法使matplotlib嵌入字体子集而不是完整的字体?我也会很好,不包括字体在所有。

到目前为止考虑的问题:

  • 矢量图形编辑器可以很容易地用于导出包含字体子集的PDF (以及根本不包括字体),但是必须对每个文件(修订)执行这一步骤似乎是不必要的乏味。
  • 类似地,我读过关于PDF-文件的后处理(例如使用Ghostscript)的文章,尽管这方面的努力似乎是相当的。
  • 我试着设置'pdf.fonttype'= 3,这确实会产生更小的文件。但是,我希望在向量图形编辑器中保持文本可修改--在这种情况下,这种方法似乎不起作用(例如,减号将不会保存为文本)。

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

MWE

代码语言:javascript
运行
复制
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')

环境: matplotlib 3.1.1

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-02-10 07:07:10

把这个留在这里,以防其他人在寻找类似的东西:毕竟,我决定选择Ghostscript。由于额外的步骤,这并不完全是我想要的,但至少它可以自动化:

代码语言:javascript
运行
复制
import subprocess
def gs_opt(filename):
    filenameTmp = filename.split('.')[-2]+'_tmp.pdf'
    gs = ['gswin64',
          '-sDEVICE=pdfwrite',
          '-dEmbedAllFonts=false',
          '-dSubsetFonts=true',             # Create font subsets (default)
          '-dPDFSETTINGS=/prepress',        # Image resolution
          '-dDetectDuplicateImages=true',   # Embeds images used multiple times only once
          '-dCompressFonts=true',           # Compress fonts in the output (default)
          '-dNOPAUSE',                      # No pause after each image
          '-dQUIET',                        # Suppress output
          '-dBATCH',                        # Automatically exit
          '-sOutputFile='+filenameTmp,      # Save to temporary output
          filename]                         # Input file

    subprocess.run(gs)                                      # Create temporary file
    subprocess.run(['del', filename],shell=True)            # Delete input file
    subprocess.run(['ren',filenameTmp,filename],shell=True) # Rename temporary to input file

然后打电话

代码语言:javascript
运行
复制
filename = 'test.pdf'
plt.savefig(filename)
gs_opt(filename)

这将将图形保存为test.pdf,使用Ghostscript创建临时优化的test_tmp.pdf,删除初始文件并将优化文件重命名为test.pdf。

与使用矢量图形编辑器导出文件相比,Ghostscript生成的PDF仍然要大几倍(通常是4-5倍)。但是,它正在将文件大小减少到初始文件的1/5至1/10之间。这是件事。

票数 1
EN

Stack Overflow用户

发布于 2020-12-18 23:02:50

PGF后端有助于显着地减少PDF文件的大小。只需将mpl.use('pgf')添加到代码中即可。在我的环境中,这一修正导致了以下情况:

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

但是,对于实际数字,执行时间通常会随着文件大小的增加而减少。

PDF大小的减少是由于嵌入了字体子集。

代码语言:javascript
运行
复制
$ 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
代码语言:javascript
运行
复制
$ 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

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

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60076026

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档