web-dev-qa-db-ja.com

.ps / .epsとして保存するとMatplotlibが透明性を失わせる

.ps/.eps拡張子で保存しようとすると、いくつかのプロットに透明な楕円体を保存しようとすると問題が発生します。

これは.pngとして保存されたプロットです: png

.ps/.epsとして保存することを選択した場合、次のようになります。 ps

これを回避する方法は、ImageMagickを使用して元のpngをpsに変換することでした。唯一の問題は、png形式の画像が約90kであり、変換後に4Mのすぐ下になることです。私はこれらの画像をたくさん持っているので、これは良くありません、そして、私のラテックス文書をコンパイルするのに時間がかかりすぎるでしょう。誰にもこれに対する解決策がありますか?

38
astromax

問題は、epsがネイティブで透明度をサポートしていないことです。

いくつかのオプションがあります:

  1. 画像をラスタライズしてepsファイルに埋め込む(@Mollyが示唆する)か、pdfにエクスポートして外部ツール(gsなど)で変換する(通常はラスタライズにも依存)

  2. 透明度を「模倣」し、特定の背景に透明な色を表示します。

これについて議論しました 確かにmatplotlibメーリングリストで一度 で、ラスタライズすることを提案しました。これは、ピクセル化された図形または巨大な図形を取得するため、実行不可能です。そして、例えば出版物に入れたとき、彼らはあまりうまくスケールしません。

私は個人的に2番目のアプローチを使用しますが、理想的ではありませんが、それで十分だと思いました。小さな pythonスクリプト からアルゴリズムを実装する this SO post を作成して、透明度を指定して色のソリッドRGB表現を取得しました

[〜#〜] edit [〜#〜]

プロットの特定のケースでは、zorderキーワードを使用して、プロットされるパーツを並べてみてください。青い楕円にzorder=10、緑にzorder=11、およびhexbinsにzorder=12を使用してみてください。

このように、青はすべての下、緑の楕円、そして最後にヘックスビンになります。また、プロットは単色でも読みやすいはずです。 pngにある青と緑の色合いが気に入ったら、mimic_alpha.pyを試してみてください。

EDIT 2

あなたがhaveを使用することを100%確信している場合、私の心に浮かぶいくつかの回避策があります(そしてそれは間違いなくあなたよりもいです)プロット):

  1. 六角形の上に楕円の境界線を描くだけです。
  2. 各六角形の中心と振幅を取得し(おそらくすべてのゼロビンを破棄し)、 散布図 を作成します。hexbinと同じカラーマップを使用し、マーカーのサイズと形状を自由に調整します。その上に楕円の境界線を再描画することができます
25

別の選択肢は、それらをpdfに保存することです

savefig('myfigure.pdf')

それがpdflatexで機能します。それがsvgではなくepsを使用する必要がある理由である場合。

14
P.R.

同じ問題がありました。ラスタライズを回避するには、画像をpdfとして保存し、ターミナルで(少なくともunixishシステムで)実行できます。

pdftops -eps my.pdf my.eps

これは、出力として.epsファイルを提供します。

8
Poshpaws

Epsファイルの透明度を維持するために、保存する前にFigureをラスタライズできます。

ax.set_rasterized(True)
plt.savefig('rasterized_fig.eps')
7
Molly

私はこれを次の方法で解決しました:1)図領域を定義するときにset_rasterization_zorder(1)を追加します。

fxsize=16
fysize=8
f = figure(num=None, figsize=(fxsize, fysize), dpi=180, facecolor='w',
edgecolor='k')
plt.subplots_adjust(
left    = (18/25.4)/fxsize, 
bottom  = (13/25.4)/fysize, 
right   = 1 - (8/25.4)/fxsize, 
top     = 1 - (8/25.4)/fysize)
subplots_adjust(hspace=0,wspace=0.1)
#f.suptitle('An overall title', size=20)
gs0 = gridspec.GridSpec(1, 2)

gs11 = gridspec.GridSpecFromSubplotSpec(1, 1, subplot_spec=gs0[0])

ax110 = plt.Subplot(f, gs11[0,0])
f.add_subplot(ax110)

ax110.set_rasterization_zorder(1)

2)プロットの各alpha = anynumberでzorder = 0:

ax110.scatter(xs1,ys1  , marker='o', color='gray'  , s=1.5,zorder=0,alpha=0.3)#, label=label_bg)

3)最終的に保存時のラスタライズ= True:

P.savefig(str(PLOTFILENAME)+'.eps', rasterized=True)

transparentsavefigキーワードを使用すると、透明な背景にalpha <1のRGBAカラーがalpha = 1のRGBカラーと同じようにレンダリングされるため、これは期待どおりに機能しない場合があります。

2
Hugo

上記のように、最良かつ最も簡単な選択は(解像度を緩めたくない場合)、図をラスタライズすることです

f = plt.figure()
f.set_rasterized(True)

ax = f.add_subplot(111)

ax.set_rasterized(True)
f.savefig('figure_name.eps',rasterized=True,dpi=300)

この方法では、dpiオプションでサイズを管理することもできます。実際、以下のzorderを使用して、ラスタライズを適用することもできます。

ax.set_rasterization_zorder(0)

注:plt.subplotおよびplt.subplot2grid関数を使用する場合、f.set_rasterized(True)を維持することが重要です。そうでない場合、ラベルと目盛り領域は.epsファイルに表示されません

1
Luis DG

私の解決策は、プロットを.epsとしてエクスポートし、たとえばInkscapeにロードしてから、プロットのグループ化を解除し、透明度を設定するオブジェクトを選択し、[塗りつぶしとストローク]タブで塗りつぶしの不透明度を編集することです。

後で微調整する場合は、ファイルを.svgとして保存するか、パブリケーション用に画像をエクスポートできます。

0
B.Kocis