Уменьшение размеров файлов PDF, созданных с помощью matplotlib, путем изменения встраивания шрифтов - PullRequest
0 голосов
/ 05 февраля 2020

Я использую matplotlib для создания PDF-фигур. Однако даже самые простые рисунки дают относительно большие файлы, MWE ниже дает файл почти 1 МБ. Мне стало известно, что большой размер файла связан с тем, что matplotlib полностью встраивает все используемые шрифты. Поскольку я собираюсь создать довольно много графиков и хотел бы уменьшить размеры файлов, мне интересно:

Основной вопрос:

Есть ли способ заставить matplotlib встроить шрифт subsets вместо полных шрифтов? Я также согласился бы вообще не включать шрифты.

Рассматриваемые до сих пор вещи:

  • Редактор векторной графики можно легко использовать для экспорта PDF, включая подмножества шрифтов (а также вообще не включая шрифты), но необходимость выполнять этот шаг для каждого файла (ревизии) представляется излишне утомительной.
  • Точно так же я читал о пост-обработке PDF-файлов (например, с использованием Ghostscript ), хотя усилия кажутся сопоставимыми.
  • Я попытался установить 'pdf.fonttype' = 3, который действительно производит файлы значительно меньшего размера. Тем не менее, я хотел бы сохранить изменяемый текст в редакторах векторной графики - что, похоже, не работает в этом случае (например, знаки минуса не будут сохранены как текст).

, так как Легко, хотя и трудоемко, создавать файлы со встроенными подмножествами, используя внешнее программное обеспечение, возможно ли каким-то образом добиться этого непосредственно в matplotlib? Любая помощь будет принята с благодарностью.

MWE

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

1 Ответ

0 голосов
/ 10 февраля 2020

Оставьте это здесь на тот случай, если кто-то еще будет искать что-то похожее: в конце концов, я решил выбрать Ghostscript. Из-за дополнительного шага это не совсем то, что я искал, но, по крайней мере, его можно автоматизировать:

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

И затем вызвать

filename = 'test.pdf'
plt.savefig(filename)
gs_opt(filename)

Это сохранит фигуру как test.pdf, используйте Ghostscript для создания временного оптимизированного test_tmp.pdf, удалите исходный файл и переименуйте оптимизированный файл в test.pdf.

По сравнению с экспортом файла с помощью векторного графического редактора, полученный PDF созданный Ghostscript все еще в несколько раз больше (обычно в 4-5 раз). Однако - это , уменьшающий размер файла до 1/5 - 1/10 от исходного файла. Это что-то.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...