web-dev-qa-db-ja.com

matplotlib-等高線からデータを抽出する

等間隔の2Dデータ(画像のようなデータ)の単一の輪郭からデータを取得したいと思います。

同様の質問で見つかった例に基づいて: 等高線プロット(matplotlib)によってプロットされる線の(x、y)値を取得するにはどうすればよいですか?

_>>> import matplotlib.pyplot as plt
>>> x = [1,2,3,4]
>>> y = [1,2,3,4]
>>> m = [[15,14,13,12],[14,12,10,8],[13,10,7,4],[12,8,4,0]]
>>> cs = plt.contour(x,y,m, [9.5])
>>> cs.collections[0].get_paths()
_

cs.collections[0].get_paths()へのこの呼び出しの結果は次のとおりです。

_[Path([[ 4.          1.625     ]
 [ 3.25        2.        ]
 [ 3.          2.16666667]
 [ 2.16666667  3.        ]
 [ 2.          3.25      ]
 [ 1.625       4.        ]], None)]
_

プロットに基づいて、この結果は理にかなっており、等高線の(y、x)ペアのコレクションのように見えます。

この戻り値を手動でループし、座標を抽出し、行の配列を組み立てる以外に、_matplotlib.path_オブジェクトからデータを取得するより良い方法はありますか? _matplotlib.path_からデータを抽出するときに注意すべき落とし穴はありますか?

または、matplotlibまたはそれ以上に、numpy/scipy内に同様のことを行う代替手段がありますか?理想的なことは、線を記述する(x、y)ペアの高解像度ベクトルを取得することです。これは、一般に私のデータセットは上記の例のように小さくも単純でもないので、さらなる分析に使用できます。

47
dtlussier

特定のパスについて、次のようなポイントを取得できます。

p = cs.collections[0].get_paths()[0]
v = p.vertices
x = v[:,0]
y = v[:,1]
45
so12311

from: http://matplotlib.org/api/path_api.html#module-matplotlib.path

Pathオブジェクトのユーザーは、頂点やコード配列に直接アクセスしないでください。代わりに、頂点/コードのペアを取得するためにiter_segments()を使用する必要があります。多くのPathオブジェクトは最適化としてコードをまったく保存しないが、iter_segments()によって提供されるデフォルトのコードを持っているため、これは重要です。

そうでなければ、あなたの質問が何であるかは本当にわかりません。 [Zip]は、座標を操作するときに便利な組み込み関数です。 1

9
Permafacture

私は同様の問題に直面しており、つまずいた このmatplotlibリストの議論

基本的に、プロットを取り除き、基礎となる関数を直接呼び出すことができます。これは非常に便利ではありませんが、可能です。解決策は、おそらく基礎となるコードでいくつかの補間が行われているため、ピクセル精度ではありません。

import matplotlib.pyplot as plt
import matplotlib._cntr as cntr
import scipy as sp

data = sp.zeros((6,6))
data[2:4,2:4] = 1

plt.imshow(data,interpolation='none')
level=0.5
X,Y = sp.meshgrid(sp.arange(data.shape[0]),sp.arange(data.shape[1]))
c = cntr.Cntr(X, Y, data.T)
nlist = c.trace(level, level, 0)
segs = nlist[:len(nlist)//2]
for seg in segs:
    plt.plot(seg[:,0],seg[:,1],color='white')

plt.show()
4
grg rsr

すべてのパスの頂点は、単に以下を介してfloat64のnumpy配列として返されます。

cs.allsegs[i][j]  # for element j, in level i

より詳細:

コレクションを調べてパスと頂点を抽出することは、最も簡単なことでも最速のことでもありません。返されたContourオブジェクトには、実際にcs.allsegsを介してセグメントの属性があり、形状[レベル] [要素] [vertex_coord]のネストされたリストを返します。

num_levels = len(cs.allsegs)
num_element = len(cs.allsegs[0])  # in level 0
num_vertices = len(cs.allsegs[0][0])  # of element 0, in level 0
num_coord = len(cs.allsegs[0][0][0])  # of vertex 0, in element 0, in level 0

リファレンスを参照してください: https://matplotlib.org/3.1.1/api/contour_api.html

0
RCCG