56

我想从均匀分布的二维数据(类似图像的数据)的单个轮廓中获取数据。

基于在类似问题中找到的示例:如何获取等值线图 (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对象中获取数据吗?从 a 中提取数据时是否需要注意陷阱matplotlib.path

或者,是否有替代方案matplotlib或更好numpy/scipy做类似的事情?理想的做法是获得描述该线的 (x,y) 对的高分辨率矢量,可用于进一步分析,因为通常我的数据集并不像上面的示例那样小或简单。

4

4 回答 4

60

对于给定的路径,您可以获得如下点:

p = cs.collections[0].get_paths()[0]
v = p.vertices
x = v[:,0]
y = v[:,1]
于 2011-04-14T16:31:40.050 回答
10

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

Path 对象的用户不应直接访问顶点和代码数组。相反,他们应该使用 iter_segments() 来获取顶点/代码对。这很重要,因为许多 Path 对象,作为一种优化,根本不存储代码,而是通过 iter_segments() 为它们提供了一个默认代码。

否则,我不确定你的问题是什么。[Zip] 在处理坐标时有时是一个有用的内置函数。1

于 2013-02-04T05:17:10.957 回答
4

我面临着类似的问题,偶然发现了这个 matplotlib list discussion

基本上,可以去掉绘图,直接调用底层函数,不是超级方便,但可以。该解决方案也不是像素精确的,因为底层代码中可能正在进行一些插值。

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()
于 2015-05-20T13:11:20.503 回答
3

所有路径的顶点可以简单地通过以下方式返回为 float64 的 numpy 数组:

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

其中cs在原始问题中定义为:

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])

更详细:

遍历集合并提取路径和顶点并不是最直接或最快的事情。返回的 Contour 对象实际上具有线段的属性 via cs.allsegs,它返回形状 [level][element][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

于 2019-08-26T10:08:07.277 回答