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

The sizes of saved vector outputs (PDF, EPS) are too large when using mplcairo as the Matplotlib backend

正如标题所说,我使用 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: 
    """
    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 v.s.1.2MB).当图中有更多行 (Artists) 时,这个问题会更糟。文件大小差异太大

作者已修复库(参见 this issue)。这个问题应该相应地关闭。