2012-09-25 126 views
3

我有一個二維數組,我想從中使用matplotlib生成一個輪廓圖。一切工作正常保存爲PNG(或其他光柵格式),但包括在一張紙我需要保存到postscript格式的數字。
問題是,當我保存到postscript時,我得到的文件相當大(有些MB)。它看起來像Matplotlib保存矢量格式的一切。雖然這對於軸和標籤是有意義的,但是如果光柵化會降級,我希望以柵格格式(我知道可以嵌入到postscript中)繪製輪廓。 有人知道該怎麼做嗎?我正在使用Agg後端。Matplotlib輪廓圖爲postscript

+0

你能給我們一個提示或看看你的代碼? – khan

回答

1

OK,最後我找到了答案,以我自己的問題。它需要在matplotlib郵件列表中進行一次困難的挖掘,所以我將here the relevant thread鏈接起來,希望它對別人也有幫助,並且可能更容易找到(順便說一句,沒有人回覆發送消息的可憐的人)。

我會在這裏總結一下這個想法。必須使用set_rasterized方法,如sega_sai suggested。然而,正如我在我的評論中解釋的,不是將該方法應用於整個圖形,而是必須將該方法應用於構成等高線圖的線條。訣竅是首先爲它們創建一個「容器」並對其進行光柵化處理,而不是柵格化每條單獨的行(這是我已經嘗試過的並給出不好的結果)。這工作正常。在討論我鏈接你可以找到它的代碼。

+3

如果您可以提供MWE(最小工作示例),那麼對於希望在未來解決您的問題的任何人來說,這個答案將會提高10倍! – Hooked

4

您可以設置:

plt.gcf().set_rasterized(True) 

plt.savefig前

+1

我不知道這個命令......但是,這具有柵格化所有圖形的效果(這已經是某種東西了)。我真正想要的只是柵格化等高線圖本身,而將文本(例如標籤)保留爲矢量格式。 – Spock

+0

@Spock:如果這個答案對你有幫助,你應該'upvote'它... –

+0

@Kurt:謝謝,完成! – Spock

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千字節&需求〜5秒,在Adobe Reader中呈現

fig_rasterized.pdf:文件大小是60千字節&呈現直接在Adobe Reader

2

不幸的是,我沒有設法從thisthis答案運行解決方案。但是,我發現了一個簡單的1行解決方法。

所以,有可能設置軸

ax.set_rasterization_zorder(Z) 

光柵化水平,這樣的方式,所有的對象與ZORDER小大於Z時會被光柵化。

對我來說,它在某種程度上看起來像:

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

以這樣的方式輪廓光柵格式,但所有其他對象(線條,文字)是在它之上的載體。對於我的數字來說,大小從〜4 Mb到〜400 kb。