【问题标题】:Why does the filesize of a matplotlib plot saved as .eps with rasterization explode?为什么使用光栅化保存为 .eps 的 matplotlib 图的文件大小会爆炸?
【发布时间】:2018-07-31 10:41:02
【问题描述】:

我有以下演示代码,我在其中创建了一个简单的散点图并将其保存为png、完全矢量化eps 和部分光栅化eps

对于大量的点,我希望矢量化 eps 的文件大小比 png 大得多(至少在合理的 dpi 下),这确实是我观察到的。 当我栅格化散点图时,我希望文件大小回到png 的大小,因为我实际上只是将png“嵌入”到eps 中,对吧?然而,光栅化版本完全膨胀了约 20 倍:

png:48K,完全矢量化eps:184K,光栅化eps:3.8M(在Linux openSUSE上,python 3.4.6matplotlib 2.2.2

这是什么原因?我对栅格化情节完全错误时会发生什么的理解?当我将png 放入inkscape 并导出为eps 时,我得到一个文件(显然是光栅化的),其大小仅比原始png 稍大。

演示代码:

import matplotlib.pyplot as plt
import numpy as np

# Prepare some random data
N = 10000
x = np.random.rand(N)
y = np.random.rand(N)

dpi = 150

# Create a figure and plot some points
fig = plt.figure()
ax = fig_mesh.add_subplot(111)

scatter = ax.scatter(x, y, zorder=0.5)

# Save it as png or unrasterized eps
fig_mesh.savefig('mesh.png', dpi=dpi) # 184K
fig_mesh.savefig('mesh.eps') # 48 K

# Save it with rasterized points
ax_mesh.set_rasterization_zorder(1)
fig_mesh.savefig('mesh_rasterized.eps', dpi=dpi, rasterized=True) # 3.8M!

提前致谢!

【问题讨论】:

  • 我可以想象存储在eps文件中的光栅化图像不是压缩的png而是位图,因为eps通常需要无损。与 png 相比,位图通常非常大。因此,当将一些随机图像保存为 png 时,我得到了 100 kB 的文件大小,而将相同的图像保存为 bmp 它是 2 MB。
  • @ImportanceOfBeingErnest 事实上,在检查eps 后,我发现文件的大部分是由bmp 组成的。原来我对光栅化的理解是错误的:虽然我认为光栅化的部分会变成固定分辨率的类似 png 的图像,但它们仍然具有无限分辨率。只是在没有光栅化的情况下,我们会得到很多矢量指令来绘制矩形(这可能需要很长时间来渲染,具体取决于查看者),而通过光栅化,我们会得到一个巨大的位图,它可能会更快地渲染。现在回答我自己的问题是不是很有礼貌?
  • 我想礼貌的方式是先询问评论者是否愿意回答,但在这种情况下,您可以放心地假设如果我真的愿意,我会这样做,所以是的,请去提前回答,然后不要忘记在 2 天内接受该答案。
  • 感谢您的提示。我实际上想更礼貌地提出我的最后一个问题,包括一个内在的建议让你回答,但我的字符空间用完了,所以我想“去他妈的”并缩短了;)

标签: python matplotlib eps


【解决方案1】:

我将在这里回答我自己的问题,但感谢@ImportanceOfBeingErnest 为我指出了正确的方法。 对这个问题的简短回答是:我对 matplotlib 中的 rasterized 关键字(以及一般的光栅化)的实际作用有错误的理解。

对文件大小增加的解释仅仅是这样一个事实,即任何被光栅化的东西都必须作为无压缩位图放入生成的eps 中。根据请求的 dpi,这可能比我们在未光栅化情况下的向量指令集占用更少的空间,或者更多。 可以通过将问题的演示代码中的 dpi 值更改为不同的值来测试这一点。例如,在dpi = 10,光栅化图像明显更小 - 尽管在这种情况下,绘制点的分辨率低得无法忍受。但是,在矩形网格的情况下,例如正如pcolormesh 所产生的那样,实际上可以设置低dpi 而不会丢失pcolormesh 数据的“分辨率”。

为了完整起见,我添加了一个带有 pcolormesh 的示例,其中低 dpi 设置生成的光栅化 eps 小于矢量版本:

import matplotlib.pyplot as plt
import numpy as np

# Prepare some random data
n = 100
N = n*n
data = np.random.rand(N).reshape(n,n)

dpi = 50

# Create a figure and plot some points
fig = plt.figure()
ax = fig.add_subplot(111)

mesh = ax.pcolormesh(data, zorder=0.5)

# Save it as png or unrasterized eps
fig.savefig('mesh.png', dpi=dpi)
fig.savefig('mesh.eps')

# Save it with rasterized points
ax.set_rasterization_zorder(1)
fig.savefig('mesh_rasterized.eps', dpi=dpi, rasterized=True)

此外,在我的研究中,我发现了一个简单的“hack”,可以使用 epstopdf 和 pdftops 命令(在 linux 上测试)轻松减小 eps 的文件大小(似乎没有损失),我希望这对某些人有用:

$ epstopdf my.eps #Creates file my.pdf
$ pdftops -eps my.pdf # Creates smaller my.eps (overwriting the old one!)

最后,一些帮助我理解的相关问题:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-02
    • 1970-01-01
    相关资源
    最近更新 更多