3

我有一个二维数组,我想使用 matplotlib 从中生成等高线图。保存为 PNG(或其他光栅格式)时一切正常,但是为了将图形包含在论文中,我需要保存为 postscript 格式。
问题是,当我保存到 postscript 时,我得到的文件非常大(一些 MB)。看起来 Matplotlib 以矢量格式保存所有内容。虽然这对轴和标签有意义,但如果光栅化会降低,我希望等高线图本身以光栅格式(我知道可以嵌入在后记中)。有人知道怎么做吗?我正在使用 Agg 后端。

4

4 回答 4

4

您可以设置:

plt.gcf().set_rasterized(True)

在 plt.savefig 之前

于 2012-09-27T18:13:51.033 回答
4

这是一个最小的工作示例。我使用sega_sai的代码已经有一段时间了,没有任何问题。

from matplotlib.collections import Collection
from matplotlib.artist import allow_rasterization
import matplotlib.pyplot as plt

class ListCollection(Collection):
     def __init__(self, collections, **kwargs):
         Collection.__init__(self, **kwargs)
         self.set_collections(collections)
     def set_collections(self, collections):
         self._collections = collections
     def get_collections(self):
         return self._collections
     @allow_rasterization
     def draw(self, renderer):
         for _c in self._collections:
             _c.draw(renderer)

def insert_rasterized_contour_plot(c):
    collections = c.collections
    for _c in collections:
        _c.remove()
    cc = ListCollection(collections, rasterized=True)
    ax = plt.gca()
    ax.add_artist(cc)
    return cc

if __name__ == '__main__':
    import numpy as np
    x, y = np.meshgrid(*(np.linspace(-1,1,500),)*2)
    z = np.sin(20*x**2)*np.cos(30*y)
    c = plt.contourf(x,y,z,30)

    plt.savefig('fig_normal.pdf')

    insert_rasterized_contour_plot(c)
    plt.savefig('fig_rasterized.pdf')

在我的电脑上,这会导致:

fig_normal.pdf:文件大小为 5810 KByte,需要约 5 秒才能在 Adob​​e Reader 中呈现

fig_rasterized.pdf:文件大小为 60 KB,直接在 Adob​​e Reader 中呈现

于 2013-01-28T13:50:44.000 回答
3

不幸的是,我没有设法从这个这个答案运行解决方案。但是,我发现了一个简单的 1 行解决方法。

因此,可以为轴设置光栅化级别

ax.set_rasterization_zorder(Z)

这样,所有 zorder 小于 Z 的对象都将被光栅化。

对我来说,它看起来像这样:

plt.contourf(<all plotting properties>, zorder=-2)
ax.set_rasterization_zorder(-1)

以这种方式,轮廓是光栅格式,但所有其他对象(线条、文本)都是其顶部的矢量。对于我的图,大小从 ~4 Mb 到 ~400 kb。

于 2017-01-10T13:07:18.460 回答
1

好的,最后我找到了自己问题的答案。它需要在 matplotlib 邮件列表中进行艰难的挖掘,所以我在这里链接了相关线程,希望它对其他人也有帮助,并且可能更容易找到(顺便说一句,没有人回复那个可怜的人发送消息)。

我将在这里用文字总结这个想法。正如sega_sai 建议的那样,必须使用该set_rasterized方法。然而,正如我在评论中解释的那样,不是将该方法应用于整个图形,而是将该方法应用于构成等高线图的线条。诀窍是首先为它们创建一个“容器”并将其栅格化,而不是栅格化每一行(这是我已经尝试过的,但结果很糟糕)。这工作正常。在我链接的讨论中,您可以找到执行此操作的代码。

于 2012-10-09T16:27:02.257 回答