matplotlib を使用して等高線図を作成したい 2D 配列があります。PNG (または他のラスター形式) として保存すると、すべて問題なく動作しますが、紙に図を含めるには、Postscript 形式で保存する必要があります。
問題は、ポストスクリプトに保存すると、取得するファイルがかなり大きい (数 MB) ことです。Matplotlib はすべてをベクトル形式で保存しているようです。これは軸とラベルには意味がありますが、ラスター化すると劣化しますが、等高線図自体をラスター形式にしたいと思います(ポストスクリプト内に埋め込むことができることがわかっています)。誰もそれを行う方法を知っていますか? Agg バックエンドを使用しています。
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')
私のPCでは、これにより次の結果が得られます。
fig_normal.pdf: ファイルサイズは 5810 KByte で、Adobe Reader でのレンダリングには約 5 秒かかります
fig_rasterized.pdf: ファイルサイズは 60 KB で、Adobe Reader で直接レンダリングされます
以下を設定できます。
plt.gcf().set_rasterized(True)
plt.savefig の前に
残念ながら、この回答またはこの回答からソリューションを実行できませんでした。ただし、簡単な1行の回避策を見つけました。
したがって、軸のラスター化レベルを設定することが可能です
ax.set_rasterization_zorder(Z)
このようにして、zorder が Z より小さいすべてのオブジェクトがラスタライズされます。
私にとっては、どういうわけかそのように見えました:
plt.contourf(<all plotting properties>, zorder=-2)
ax.set_rasterization_zorder(-1)
このように、輪郭はラスター形式ですが、他のすべてのオブジェクト (線、テキスト) はその上のベクトルです。私の図では、サイズが ~4 Mb から ~400 kb になりました。
OK、最後に私は自分の質問に対する答えを見つけました。matplotlib メーリング リストを掘り下げるのは大変だったので、関連するスレッドをここにリンクします。メッセージを送信しました)。
ここでその考えを言葉で要約します。sega_sai が提案set_rasterized
したように、メソッドを使用する必要があります。ただし、コメントで説明したように、図全体にメソッドを適用するのではなく、等高線図を構成する線にメソッドを適用する必要があります。トリックは、最初にそれらすべての「コンテナ」を作成し、個々の行をラスタライズするのではなく、それをラスタライズすることです(これは私がすでに試したもので、悪い結果が得られました)。これはうまくいきます。リンクしたディスカッションでは、それを行うためのコードを見つけることができます。