塗りつぶしのみを取得するには、pyplot.contourfの輪郭線ストロークを隠す

地図の画像を作成するためのペットプロジェクトがあり、ここで地形標高の等高線図に道路やその他のものを描画します。マウンテンバイクのルートを計画することを意図しています(私は過去にいくつかのベクトル図を手作業で作成しました。

Currently, I download Digital Elevation Model, in GeoTIFF, from here: http://www.ecologia.ufrgs.br/labgeo/arquivos/downloads/dados/SRTM/geotiff/rs.rar

GDALとMatplotlib contourf 関数を使用してプロットを作成します。

from osgeo import gdal
import matplotlib
import matplotlib.pyplot as plt
from pylab import cm
import numpy

f = 'rs.tif'

elev = gdal.Open(f)

a = elev.GetRasterBand(1).ReadAsArray()

w = elev.RasterXSize
h = elev.RasterYSize
print w, h

altura  = (0.35, 0.42)
largura = (0.70, 0.82)

a = a[int(h*altura[0]):int(h*altura[1]),
      int(w*largura[0]):int(w*largura[1])]


cont = plt.contourf(a, origin='upper', cmap=cm.gist_earth, levels=numpy.arange(0,1000,20))
plt.title('Altitudes - max: %d m; min: %d m' % (numpy.amax(a), numpy.amin(a)))
plt.show()

それは与える:

enter image description here

問題は、等高線が「白」であり、後に道路や河川をプロットしたいので望ましくない視覚的汚染を発生させることです。

ですから、ここで提案されているような、パラメータ設定やハック(ソースコードの変更)を介して、これらの軽い行を contourf で作成する方法を変更しようとしています。

Matplotlibから等高線をフォーマットする方法

また、誰かが他のライブラリを使用してよりエレガントな方法でそのようなマップを生成する方法を知っていれば、私はこのヒントを非常に感謝しています!

読んでくれてありがとう。

15

4 答え

私は最終的にフィギュアの輪郭やラスタライズに複数の呼び出しを必要としない、この長年にわたる問題(現在はMatplotlib 2.0)の適切な解決策を見つけました。

この質問に示されている問題は、PNGのような低品質のラスターファイルではなく、PDFなどの保存された出版品質の図形形式でのみ表示されることに注意してください。

私の解決策は、カラーバーと同様の問題に関連するこのの回答に触発されました。同様の解決策は、以下のように等高線プロットも解くことが分かります。

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(123)
x, y = np.random.uniform(size=(100, 2)).T
z = np.exp(-x**2 - y**2)
levels = np.linspace(0, 1, 100)

cnt = plt.tricontourf(x, y, z, levels=levels, cmap="ocean")

# This is the fix for the white lines between contour levels
for c in cnt.collections:
    c.set_edgecolor("face")

plt.savefig("test.pdf")    

以下は修正前の等高線の例です

enter image description here

そして、以下は、上記の修正の後の同じ数字です

enter image description here

26
追加された
まあ、もちろん、これは今、受け入れられた答えです。それは、おそらく根本的な問題を解決するように思われます。あまりにも多くの時間を過ごしても投稿してくれてありがとう
追加された 著者 heltonbiker,
驚くばかり!私はこれを待っていましたが、私が好きな記事を次回はそれをチェックすることを忘れないように願っています;)
追加された 著者 Andras Deak,
私のために働かなかった。
追加された 著者 user124384,
本当にありがとう!これからはすべての contourf プロットでこれを使用します。それは唯一の2行のソリューションだと驚いた。
追加された 著者 Luke Davis,
それを更新してくれてありがとう@heltonbiker。このソリューションの利点は、ファイルサイズを増やさず、画質を低下させないことです。
追加された 著者 divenex,

heltonbiker、あなたの問題の解決策を見つけましたか?私はこの質問に誤って遭遇しました。私はしばらくの間同じ問題を抱えていました。私はゼニアの提案を試みたが、どちらも私のために働かない。実際の解決法ではないにもかかわらず、問題を解決するには解決策は簡単ですが、同じ contourf コマンドを繰り返してください。これで偽の輪郭が魔法のように消えてしまいます。

OPで述べたように、あまりにも間隔の近い輪郭塗りつぶし( contourf )を実行すると、擬似輪郭が現れます。非常に多くの間隔を設定することで、この動作を再現できます。例:

plt.contourf(plon,plat,ssh,np.arange(-1,1.001,0.001)) # 2001 intervals

これは出力として私たちを与える:

enter image description here

薄い疑似輪郭は、明らかに輪郭充填のネットカラーに影響します。

コマンドを2回実行すると、

plt.contourf(plon,plat,ssh,np.arange(-1,1.001,0.001)) # Not once,
plt.contourf(plon,plat,ssh,np.arange(-1,1.001,0.001)) # but twice!

私に与える:

enter image description here

今はるかに良い。 3つの連続した contourf コマンドで、最も優れたものがあります:

enter image description here

私はもはや細い等高線を見ることができません!残念ながら、これは、配列のサイズと等高線間隔の数に応じて、スクリプトの速度を大幅に低下させる可能性があります。より多くの等高線間隔が使用されれば、擬似輪郭はより顕著になる。通常は、50〜100の等高線間隔を使用し、 contourf を2回実行するのが最も良い方法です。

私が使用しているmatplotlibのバージョンが最新ではないことに注意してください。この問題は、バージョン 1.1.0 で解決されている可能性があります。それがあれば、私に知らせてください。

Python 2.7.1 |EPD 7.0-2 (32-bit)| (r271:86832, Nov 29 2010, 13:52:51)
In [1]: matplotlib.__version__
Out[1]: '1.0.1'
5
追加された
古い質問に興味をお持ちいただきありがとうございます!私は問題がエイリアシングエフェクトに関連していると確信しています。ピクセルはボーダーで「色付き」ではありません。これは、半透明(または半無色)のピクセルを再塗りつぶして「塗りつぶす」傾向があり、色をつける傾向があるため、ソリューションと非常によく似ています。私は今、この提案を試すことはできませんが、確かに私は時が来るときに(私のプロットは、パフォーマンスの問題を抱えているほど密ではありません)。ありがとう!!
追加された 著者 heltonbiker,
(そして、ubuntu関連のディストリビューションの最新バージョンはまだmatplotlib 0.9を使っています...)
追加された 著者 heltonbiker,
EPDを支払う必要があるようですか?もしそうなら、私はそうではない古い自由ないとこに固執すると思う:o(
追加された 著者 heltonbiker,
Pythonパッケージをインストールするために easy_install pip を使い始めることで、古いパッケージの問題を解決しました。これ以上のシナプス(Linuxでは)、もうSourceForgeのコンパイルされたバイナリ(Windows上で)はありません。
追加された 著者 heltonbiker,
いいね、+1。 matplotlibバージョン1.1.0に関しては、それは本当に簡単なインストールです。少なくとも私のバイナリではかなり古いLucidには全く問題ありません。
追加された 著者 ev-br,
@heltonbikerごめんなさい。 EPDには無料のバージョンがあります: enthought.com/products/epd_free.php 、またはフルバージョン学術利用のために無料で: enthought.com/products/edudownload.php
追加された 著者 milancurcic,
@heltonbikerです。私はFedora、RHEL、CentOSでEnthought Python Distributionを使用していますので、強くお勧めします。 matplotlib 1.1.0には、他の多くの科学指向のモジュールがあります。どうやら、私は最新のEPDバージョンを使用していません:)。 enthought.com/products/epd.php (私はEnthoughtに関連していません)
追加された 著者 milancurcic,

Try adding the kw argrument to plt.contourf(...) call: either lw=0 or ls=None. http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.contourf

3
追加された
うわー!今それは驚くべきことでした!今すぐ宿題をする時間、結果が出たら直ちにフィードバックを返します。どうもありがとう!!!
追加された 著者 heltonbiker,
あまりにも早く...引用した例でプロット範囲を広げ、より多くの等高線を得ました。隣の色があまりにも似ているとき、特に濃い青色のときに起こるようです。私はこれがサブピクセルアンチエイリアスのバグだと思うので、手作業で画像にメジアンフィルタを適用しなければならないようです。とにかく、あなたの助けをありがとう!
追加された 著者 heltonbiker,
私はすでにそれをした、役に立たない...:o(
追加された 著者 heltonbiker,
新しい答え、少なくとも症状の原因ではない場合は、問題を解決するようだ。
追加された 著者 heltonbiker,
私はあなたが言ったようにして、前と同じようなことを試したことを思い出しましたが、残念ながらそれはうまくいきませんでした。私はこれらのライトストロークラインが実際に不適切なアンチエイリアスによるレンダリングの問題かもしれないと考えていますが、どのようにして知ることができますか?
追加された 著者 heltonbiker,
正直なところ、私は本当に知りません:-(少し驚きましたが、この例では、 matplotlib.sourceforge.net/examples/pylab_examples/… という行はありません。私があなただったら、この例から始めて、これらの行がどこに現れ始めるかを見てみましょう。
追加された 著者 ev-br,
画像をフィルタリングする前に、 kwarg のエイリアスを contourf に設定してみてください。
追加された 著者 ev-br,

The posted solution did not work for me with alpha set to <1, but I found the answer in this solution: Matplotlib Contourf Plots Unwanted Outlines when Alpha < 1

引数 antialiased = True を追加すると、私の問題が解決されました。

2
追加された
これはMatplotlib 2.2で私にとっては役に立たない
追加された 著者 divenex,
あなたがしたことを複製できるように、最低限の作業コードと入手した数字を含めることができますか?
追加された 著者 divenex,
私はMatplotlib 2.2にアップグレードしましたが、それはまだ私のために働いています。
追加された 著者 Catherine Nelson,