使用mplcairo作为Matplotlib后端时,保存的矢量输出(PDF、EPS)的大小过大



正如标题所说,我使用mplcairo作为Matploblit后端。但是,与使用默认Matplotlib后端的文件相比,保存的文件太大。我想缩小文件大小。

这个问题也发布在GitHub上:https://github.com/matplotlib/mplcairo/issues/37

版本信息

>>> import mplcairo
>>> mplcairo.get_versions()
{'python': '3.9.5 (default, Jun  4 2021, 12:28:51) n[GCC 7.5.0]', 'mplcairo': '0.4', 'matplotlib': '3.5.1', 'cairo': '1.16.0', 'freetype': '2.10.1', 'pybind11': '2.6.2', 'raqm': None, 'hb': None}

问题说明

mplcairo后端

代码:

from pathlib import Path
import numpy as np
import matplotlib
print("matplotlib.__version__:", matplotlib.__version__)
print('Default backend:', matplotlib.get_backend())
matplotlib.use("module://mplcairo.base")
# matplotlib.use("cairo")
print('Backend is now:', matplotlib.get_backend())
import matplotlib.pyplot as plt
matplotlib.rcParams['pdf.fonttype'] = 42
matplotlib.rcParams['ps.fonttype'] = 42

def format_size(num, suffix="B"):
"""Reference: https://stackoverflow.com/a/1094933
"""
for unit in ["", "K", "M", "G", "T", "P", "E", "Z"]:
if abs(num) < 1024.0:
return f"{num:3.1f}{unit}{suffix}"
num /= 1024.0
return f"{num:.1f}Y{suffix}"

# Plot and save figures
fig, ax = plt.subplots(figsize=(8,6), dpi=300)
for i in range(5):
ax.plot(range(100000), np.random.rand(100000), linewidth=2.0)
fig.savefig('./mplcairo_file_size_test.pdf', format='pdf', bbox_inches='tight')
fig.savefig('./mplcairo_file_size_test.eps', format='eps', bbox_inches='tight')
fig.savefig('./mplcairo_file_size_test.png', format='png', bbox_inches='tight')
print("Figures saved!")

# Display the sizes
pathlist = [ Path("./mplcairo_file_size_test.pdf"), Path("./mplcairo_file_size_test.eps"), Path("./mplcairo_file_size_test.png") ]
for path in sorted(pathlist):
print("{:s}: {:s}".format(path.name, format_size(path.stat().st_size)))

输出:

matplotlib.__version__: 3.5.1
Default backend: module://matplotlib_inline.backend_inline
Backend is now: module://mplcairo.base
Figures saved!
mplcairo_file_size_test.eps: 8.4MB
mplcairo_file_size_test.pdf: 8.4MB
mplcairo_file_size_test.png: 63.2KB

默认后端

代码与mplcairo代码相同,只是matplotlib.use行被注释掉,以便使用默认的后端。

输出:

matplotlib.__version__: 3.5.1
Default backend: module://matplotlib_inline.backend_inline
Backend is now: module://matplotlib_inline.backend_inline
Figures saved!
mplcairo_file_size_test.eps: 1.2MB
mplcairo_file_size_test.pdf: 535.4KB
mplcairo_file_size_test.png: 76.8KB

观察

mplcairo生成的矢量文件(PDF、EPS(比默认后端生成的矢量大得多(8.4MB vs.s.1.2MB(。当图中有更多行(Artists(时,这个问题会更严重。文件大小的差异太大。

作者已经修复了库(请参阅本期(。这个问题应该相应地结束。

最新更新