如何在Python中高效存储2D矢量绘图以适配LaTeX文档
解决Matplotlib 2D矢量图体积过大的非降采样方案
针对你遇到的2D绘图存储为PDF/SVG时体积臃肿、Inkscape崩溃的问题,这里有几个不用降采样的实用解决思路:
1. 选择性光栅化绘图元素,保留文本矢量
Matplotlib允许你对绘图中的光栅密集型元素(比如pcolormesh生成的色块)进行光栅化,而标题、坐标轴标签、颜色条文本这些保留矢量格式。这样既保证文本可被LaTeX渲染,又大幅减小文件体积:
import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt mpl.rcParams.update({ "font.family": 'Times', "font.size": 12, "font.serif": [] }) x = np.linspace(-.5, .5, 1024) x, y = np.meshgrid(x, x) z = np.exp(-(x**2 + y**2)) plt.figure() plt.title('Gaussian plot: $z = \exp{-(x^2 + y^2)}$') # 对pcolormesh进行光栅化,保留矢量文本 pcm = plt.pcolormesh(x, y, z, rasterized=True) cbar = plt.colorbar(pcm) # 可选:如果颜色条色块也密集,同样可以光栅化 # cbar.solids.set_rasterized(True) plt.savefig('test_opt.pdf', bbox_inches='tight', format='pdf', dpi=300)
生成的PDF里,色块部分是高分辨率光栅图(300dpi足够满足印刷/文档需求),文本和坐标轴都是矢量,体积会大幅降低,Inkscape打开也不会崩溃。
2. 使用PGF后端直接生成LaTeX兼容格式
Matplotlib的PGF后端专门为LaTeX文档设计,它会输出绘图的结构信息为PGF代码,所有文本完全交由LaTeX处理,生成的文件体积小且兼容性拉满:
import numpy as np import matplotlib as mpl mpl.use('pgf') import matplotlib.pyplot as plt mpl.rcParams.update({ "font.family": 'Times', "font.size": 12, "font.serif": [], "pgf.rcfonts": False, # 禁用Matplotlib字体设置,改用LaTeX的字体配置 "pgf.preamble": [ r"\usepackage{amsmath}", r"\usepackage{fontspec}", r"\setmainfont{Times New Roman}" ] }) x = np.linspace(-.5, .5, 1024) x, y = np.meshgrid(x, x) z = np.exp(-(x**2 + y**2)) plt.figure() plt.title('Gaussian plot: $z = \exp{-(x^2 + y^2)}$') plt.pcolormesh(x, y, z) plt.colorbar() plt.savefig('test.pgf', bbox_inches='tight')
之后在LaTeX文档里直接用\input{test.pgf}导入即可,所有文本会和你的文档字体完全一致,文件体积远小于PDF/SVG。
3. 后处理压缩PDF文件
如果你已经生成了体积较大的PDF,可以用Ghostscript工具进行无损压缩(不会损失矢量质量),执行以下命令:
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/prepress -dNOPAUSE -dQUIET -dBATCH -sOutputFile=test_compressed.pdf test.pdf
这个命令会去除PDF中的冗余数据,大幅压缩体积,同时保留文本的可编辑性。
这些方法都不需要降采样,能很好地平衡绘图质量、文件体积和LaTeX兼容性。
内容的提问来源于stack exchange,提问作者Forrest Thumb
相关产品推荐
相关产品推荐

