You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matplotlib生成的PDF更大且模糊,能否优化至R生成的水平?

问题:Matplotlib生成PDF质量及体积优化方案

用户分别用R和Matplotlib绘制相同数据的直方图并保存为PDF,代码如下:

R代码

set.seed(42)
x = c(rnorm(1000, 1, 1), rnorm(1000, 8, 3))
pdf("Rplot.pdf", width = 10, height = 3.33)
par(mar = c(4, 5, 0, 0), family = "serif")
hist(x, breaks = 100, border = NA, col = "gray", 
     xlab = "x", ylab = "Frequency", cex.lab = 2.75, cex.axis = 2,
     main = "", las = 1, xaxt = "n")
axis(side = 1, at = seq(-2.5, by = 2.5, len = 30), cex.axis = 2)
dev.off()

Matplotlib原始代码

import numpy as np
import matplotlib.pyplot as plt
np.random.seed(42)
x = np.concatenate((np.random.normal(1, 1, size = 1000),
   np.random.normal(8, 3, size = 1000)))
plt.close()
plt.rcParams["figure.figsize"] = (10, 3.33)
plt.rcParams["font.family"] = "Times New Roman"
plt.rcParams["axes.spines.bottom"] = True
plt.rcParams["axes.spines.left"] = True
plt.rcParams["axes.spines.top"] = False
plt.rcParams["axes.spines.right"] = False
tmp = plt.hist(x, bins = 100, color = 'lightgray')
plt.xlabel('x', fontsize = 30)
plt.ylabel('Frequency', fontsize = 30)
tmp = plt.xticks(fontsize = 25)
tmp = plt.yticks(fontsize = 25)
plt.tight_layout()
plt.savefig("pyPlot.pdf", bbox_inches='tight')

现象

生成的pyPlot.pdf(13KB)体积是Rplot.pdf(5KB)的2.6倍,且在Adobe Reader中显示更模糊;但保存为SVG格式时两者效果一致。用户希望用Matplotlib生成与R版本同等质量和体积的PDF,同时想了解R是否有额外优化。


解决方案

关键差异说明

R的PDF设备默认使用Type 1矢量字体,且对图形元素的矢量渲染做了精简;而Matplotlib默认使用Type 3字体(位图化矢量字体),且直方图绘制时可能生成冗余的矢量路径,导致文件体积大、显示模糊。

优化后的Matplotlib代码如下:

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(42)
x = np.concatenate((np.random.normal(1, 1, size=1000),
                    np.random.normal(8, 3, size=1000)))

plt.close()
# 核心优化:强制使用Type 1矢量字体,避免位图化模糊
plt.rcParams["pdf.fonttype"] = 42
plt.rcParams["ps.fonttype"] = 42
plt.rcParams["figure.figsize"] = (10, 3.33)
plt.rcParams["font.family"] = "serif"  # 和R的family="serif"保持一致
plt.rcParams["axes.spines.bottom"] = True
plt.rcParams["axes.spines.left"] = True
plt.rcParams["axes.spines.top"] = False
plt.rcParams["axes.spines.right"] = False

# 绘制直方图时关闭边缘,减少冗余矢量元素
n, bins, patches = plt.hist(x, bins=100, color='gray', edgecolor='none')

plt.xlabel('x', fontsize=30)
plt.ylabel('Frequency', fontsize=30)
# 对齐R的坐标轴刻度逻辑
plt.xticks(ticks=np.arange(-2.5, 70, 2.5), fontsize=25)
plt.yticks(fontsize=25)
plt.tight_layout()

# 优化保存参数,压缩文件体积同时保证精度
plt.savefig("pyPlot_optimized.pdf", bbox_inches='tight', dpi=600, 
            facecolor='white', edgecolor='none')
plt.close()

优化点详解

  1. 字体设置:pdf.fonttype=42和ps.fonttype=42强制使用Type 1矢量字体,彻底解决模糊问题并显著缩小文件体积。
  2. 图形精简:直方图设置edgecolor='none'(对应R的border=NA),避免生成大量冗余的边缘路径。
  3. 样式对齐:统一字体家族、坐标轴刻度逻辑,保证和R生成的图形样式一致。
  4. 保存优化:dpi=600保证矢量渲染精度,配合默认的PDF压缩机制进一步缩小体积。

效果验证

优化后的PDF体积会接近R生成的版本,显示清晰度完全一致,SVG格式效果也不受影响。

内容的提问来源于stack exchange,提问作者user2961927

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 11:52:35