Matplotlib等高线图作为后记

时间:2012-09-25 13:27:31

标签: python matplotlib postscript

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

4 个答案:

答案 0 :(得分:4)

您可以设置:

plt.gcf().set_rasterized(True)
pt.savefig之前的

答案 1 :(得分: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:filesize是5810 KByte&需要~5秒才能在Adobe Reader中渲染

fig_rasterized.pdf:filesize是60 KByte&直接在Adobe Reader中呈现

答案 2 :(得分:2)

不幸的是,我没有设法从this this回答来运行解决方案。但是,我找到了一个简单的1行解决方法。

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

ax.set_rasterization_zorder(Z)

以这种方式,zorder小于Z的所有对象都将被栅格化。

对我而言,看起来有点像:

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

以这种方式,轮廓采用栅格格式,但所有其他对象(线条,文本)都是矢量。对于我的数字,大小从大约4 Mb到大约400 kb。

答案 3 :(得分:1)

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

我将在这里总结一下这个想法。必须使用set_rasterized方法,sega_sai suggested。然而,正如我在评论中所解释的,不是将该方法应用于整个图,而是必须将该方法应用于构成等高线图的线。诀窍是首先为它们创建一个“容器”并对其进行栅格化,而不是栅格化每一行(这是我已经尝试过的并且给出了不好的结果)。这很好用。在我链接的讨论中,您可以找到执行此操作的代码。