等間隔の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)ペアの高解像度ベクトルを取得することです。これは、一般に私のデータセットは上記の例のように小さくも単純でもないので、さらなる分析に使用できます。
特定のパスについて、次のようなポイントを取得できます。
p = cs.collections[0].get_paths()[0]
v = p.vertices
x = v[:,0]
y = v[:,1]
from: http://matplotlib.org/api/path_api.html#module-matplotlib.path
Pathオブジェクトのユーザーは、頂点やコード配列に直接アクセスしないでください。代わりに、頂点/コードのペアを取得するためにiter_segments()を使用する必要があります。多くのPathオブジェクトは最適化としてコードをまったく保存しないが、iter_segments()によって提供されるデフォルトのコードを持っているため、これは重要です。
そうでなければ、あなたの質問が何であるかは本当にわかりません。 [Zip]は、座標を操作するときに便利な組み込み関数です。 1
私は同様の問題に直面しており、つまずいた この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()
すべてのパスの頂点は、単に以下を介して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