为什么保存为 .eps 的 matplotlib 图的文件大小会爆炸?
Why does the filesize of a matplotlib plot saved as .eps with rasterization explode?
我有以下演示代码,我在其中创建了一个简单的散点图并将其另存为 png
、完全矢量化 eps
和部分光栅化 eps
。
对于大量点,我希望矢量化 eps
的文件大小比 png
大得多(至少在合理的 dpi 下),这确实是我观察到的。
当我栅格化散点图时,我希望文件大小回到 png
的大小,因为我实际上只是 "embedding" eps
中的 png,对吧?然而,光栅化版本完全膨胀了 ~20 倍:
png
:48K,完全矢量化 eps
:184K,光栅化 eps
:3.8M(在 Linux openSUSE,python 3.4.6
,matplotlib 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!
提前致谢!
我将在这里回答我自己的问题,但感谢@ImportanceOfBeingErnest 为我指出了正确的方法。
对该问题的简短回答是:我对 matplotlib(以及一般的光栅化)中的 rasterized
关键字的实际作用有错误的理解。
文件大小增加的原因很简单,就是任何被栅格化的内容都必须作为无压缩位图放入生成的 eps
中。根据请求的 dpi,这可能比我们在未光栅化情况下的矢量指令集占用更少 space,或者更多。
可以通过将问题演示代码中的 dpi 值更改为不同的值来对此进行测试。例如,在 dpi = 10
处,光栅化图像明显较小 - 尽管在这种情况下,绘制点的分辨率低得令人难以忍受。然而,在矩形网格的情况下,例如正如 pcolormesh
所产生的,实际上可以设置低 dpi 而不会丢失 pcolormesh
数据的 "resolution"。
为了完整起见,我添加了一个带有 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!)
最后,一些帮助我达成理解的相关问题:
- eps and transparency issue (where actually @Hugo's answer helped me most)
我有以下演示代码,我在其中创建了一个简单的散点图并将其另存为 png
、完全矢量化 eps
和部分光栅化 eps
。
对于大量点,我希望矢量化 eps
的文件大小比 png
大得多(至少在合理的 dpi 下),这确实是我观察到的。
当我栅格化散点图时,我希望文件大小回到 png
的大小,因为我实际上只是 "embedding" eps
中的 png,对吧?然而,光栅化版本完全膨胀了 ~20 倍:
png
:48K,完全矢量化 eps
:184K,光栅化 eps
:3.8M(在 Linux openSUSE,python 3.4.6
,matplotlib 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!
提前致谢!
我将在这里回答我自己的问题,但感谢@ImportanceOfBeingErnest 为我指出了正确的方法。
对该问题的简短回答是:我对 matplotlib(以及一般的光栅化)中的 rasterized
关键字的实际作用有错误的理解。
文件大小增加的原因很简单,就是任何被栅格化的内容都必须作为无压缩位图放入生成的 eps
中。根据请求的 dpi,这可能比我们在未光栅化情况下的矢量指令集占用更少 space,或者更多。
可以通过将问题演示代码中的 dpi 值更改为不同的值来对此进行测试。例如,在 dpi = 10
处,光栅化图像明显较小 - 尽管在这种情况下,绘制点的分辨率低得令人难以忍受。然而,在矩形网格的情况下,例如正如 pcolormesh
所产生的,实际上可以设置低 dpi 而不会丢失 pcolormesh
数据的 "resolution"。
为了完整起见,我添加了一个带有 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!)
最后,一些帮助我达成理解的相关问题:
- eps and transparency issue (where actually @Hugo's answer helped me most)