2015-11-05 29 views
9

誰かが知っていますか?Matplotlibで、半透明の色で見栄えの良い等高線図を作成するにはどうすればいいですか? contourf()は、半透明の色でカラーマップを渡された場合、それが満たされた領域の間に小さなギャップを生成します。Matplotlib:透明な色で塗りつぶされた等高線図

small gaps between areas

docsによると、これはバグではありません(」contourf()は、[...]ありませんポリゴンの端を描く ")。エッジを描画するには、「contour()への呼び出しで線の輪郭を追加する」ことをお勧めします。しかし、エッジがあまりにも不透明になるように、そのどちらかが良い見ていない:

edges are too opaque

をあなたはcontour()linewidth引数で遊ぶことができますが、それはあまり役に立ちません。何か案は?

import matplotlib 
import numpy as np 
from matplotlib.figure import Figure 
from matplotlib.backends.backend_agg import FigureCanvasAgg 

# generate some data 
shape = (100, 100) 
x_rng = np.linspace(-1, 1, shape[1]) 
y_rng = np.linspace(-1, 1, shape[0]) 
x, y = np.meshgrid(x_rng, y_rng) 
z = np.sqrt(x**2 + y**2) 

# create figure 
width_inch, height_inch = 5, 5 # results in 500x500px with dpi=100 
fig = Figure() 
fig.set_size_inches((width_inch, height_inch)) 
FigureCanvasAgg(fig) 
ax = fig.add_axes([0., 0., 1., 1.]) 
ax.set_axis_off() 

# define some colors with alpha < 1 
alpha = 0.9 
colors = [ 
    (0.1, 0.1, 0.5, alpha), # dark blue 
    (0.0, 0.7, 0.3, alpha), # green 
    (0.9, 0.2, 0.7, alpha), # pink 
    (0.0, 0.0, 0.0, alpha), # black 
    (0.1, 0.7, 0.7, alpha), # light blue 
] 
cmap = matplotlib.colors.ListedColormap(colors) 
levels = np.array(np.linspace(0, z.max(), len(colors))) 
norm = matplotlib.colors.BoundaryNorm(levels, ncolors=cmap.N) 

# contourf plot produces small gaps between filled areas 
cnt = ax.contourf(x, y, z, levels, cmap=cmap, norm=norm, 
        antialiased=True, linecolor='none') 

# this fills the gaps, but it makes them too opaque 
# ax.contour(x, y, z, levels, cmap=cmap, norm=norm, 
#   antialiased=True) 

# the same is true for this trick: 
# for c in cnt.collections: 
#  c.set_edgecolor("face") 

filename = "/tmp/contourf.png" 
fig.savefig(filename, dpi=100, transparent=True, format="png") 

PS:同じプロットは、SVGのバックエンドとよさそうだ。ここ

は、問題を(私はオブジェクト指向のAPIを使用しますが、結果はpyplotと同じである)を再生コードです。

PPS:これはあなたの問題を解決するかどうか、やや主観的である「格好良い」と

ax.pcolormesh(x, y, z, cmap=cmap, norm=norm, 
       edgecolor="face", antialiased=True) 

enter image description here

+0

備考: '' antialiased = True''は効果があるようです(ただし、無効にしても良い結果は得られません)。 – weatherfrog

答えて

1

私は、知らないが、唯一の方法へ:pcolormesh()は、同様の問題がありますそのレベルに拡大するとSVG、EPSなどのベクトル形式(あなたが指摘するように)を使用することになる場合、アンチエイリアシングの問題やギザギザのエッジを持たない画像を取得します。

SVG(スケーラブルベクタグラフィックス)

enter image description here

あなたはアンチエイリアスをオフにした場合は、エッジのボケと「不透明性」を取り除くことができますが、ギザギザのエッジを取得します大きなズームレベルでサークルに表示されます。あなたは、300dpiのを言うためにDPIを増やしてみてください、とTIFFとして保存することもできますに沿って、あなたのイメージをブレンドする予定です

TIFF、300dpiの、アンチエイリアス= Falseの

enter image description here

アンチエイリアシング透明なピンクとグリーンを混在させると色が濃くなり、透明性が同じであっても、より不透明に見える印象を与えるかもしれません。

私は/にあなたのコードの次のセクションをコメントアウト異なる見える結果を得たが、結果は良く見ていると言うにはあまりにも主観的である:

:輪郭ではなくにEdgeColorを設定

ax.contour(x, y, z, levels, cmap=cmap, norm=norm, 
      antialiased=True) 

# the same is true for this trick: 
# for c in cnt.collections: 
#  c.set_edgecolor("face") 

輪郭を設定しますが、エッジの色を設定しないでください:

# ax.contour(x, y, z, levels, cmap=cmap, norm=norm, 
#   antialiased=True) 

# the same is true for this trick: 
for c in cnt.collections: 
    c.set_edgecolor("face") 

をしかし、それは彼らが良く見えるかどうかの解釈次第です。私が見つけた別のものは、自分の画像ビューアには独自のアンチエイリアス機能が組み込まれているということでしたので、比較しようとするときにこれをオフにしたいかもしれません。

+0

これを選んでいただきありがとうございます。私は、RGBカラーをRGBAカラーの「プレースホルダ」として使用し、後処理ステップで透明度を適用することで、透明性なしでプロットすることで問題を解決しました。 私はあなたの答えをupvotedしましたが、それは実際に元の質問を解決しないのでそれを受け入れていません。 – weatherfrog

関連する問題