我正在尝试为某些数据找到(但不是绘制!)轮廓线:
from pprint import pprint
import matplotlib.pyplot
z = [[0.350087, 0.0590954, 0.002165], [0.144522, 0.885409, 0.378515],
[0.027956, 0.777996, 0.602663], [0.138367, 0.182499, 0.460879],
[0.357434, 0.297271, 0.587715]]
cn = matplotlib.pyplot.contour(z)
我知道cn
包含我想要的等高线,但我似乎无法得到
给他们。我尝试了几件事:
print dir(cn)
pprint(cn.collections[0])
print dir(cn.collections[0])
pprint(cn.collections[0].figure)
print dir(cn.collections[0].figure)
无济于事。我知道cn
是ContourSet
,cn.collections
是一个数组
LineCollection
的。{我认为LineCollection
是一个线段数组,但是我
无法弄清楚如何提取这些细分。
我的最终目标是创建一个用于绘制世界数据的KML文件 地图,以及该数据的轮廓。
但是,由于我的一些数据点和其他数据点很接近 很远,我需要组成的实际多边形(线串) 轮廓,而不仅仅是轮廓的光栅化图像。
我有些惊讶qhull
没有这样的事情。
使用Mathematica的ListContourPlot
,然后导出为SVG,但是我
想要使用开源的东西。
我无法使用众所周知的CONREC算法,因为我的数据不在 mesh(对于给定的x值,并不总是有多个y值,并且 反之亦然)。
解决方案不需要python,但必须是开源的 并且可以在Linux上运行。
答案 0 :(得分:22)
您可以通过循环使用集合和路径并使用matplotlib.path.Path
的iter_segments()
方法来获取顶点。
这是一个函数,它将顶点作为一组嵌套的轮廓线,轮廓截面和x,y顶点数组返回:
import numpy as np
def get_contour_verts(cn):
contours = []
# for each contour line
for cc in cn.collections:
paths = []
# for each separate section of the contour line
for pp in cc.get_paths():
xy = []
# for each segment of that section
for vv in pp.iter_segments():
xy.append(vv[0])
paths.append(np.vstack(xy))
contours.append(paths)
return contours
也可以使用未记录的matplotlib._cntr
C模块计算轮廓而无需绘制任何内容:
from matplotlib import pyplot as plt
from matplotlib import _cntr as cntr
z = np.array([[0.350087, 0.0590954, 0.002165],
[0.144522, 0.885409, 0.378515],
[0.027956, 0.777996, 0.602663],
[0.138367, 0.182499, 0.460879],
[0.357434, 0.297271, 0.587715]])
x, y = np.mgrid[:z.shape[0], :z.shape[1]]
c = cntr.Cntr(x, y, z)
# trace a contour at z == 0.5
res = c.trace(0.5)
# result is a list of arrays of vertices and path codes
# (see docs for matplotlib.path.Path)
nseg = len(res) // 2
segments, codes = res[:nseg], res[nseg:]
fig, ax = plt.subplots(1, 1)
img = ax.imshow(z.T, origin='lower')
plt.colorbar(img)
ax.hold(True)
p = plt.Polygon(segments[0], fill=False, color='w')
ax.add_artist(p)
plt.show()
答案 1 :(得分:2)
轮廓数据似乎位于.allsegs
函数返回的QuadContourSet
对象的plt.contour()
属性中。
.allseg
属性是所有级别的列表(可以在调用plt.contour(X,Y,Z,V)
时指定。对于每个级别,您将获得numpy nx2数组的列表。
plt.figure()
plt.contour(X, Y, Z, [0], colors='r')
plt.figure()
for ii, seg in enumerate(C.allsegs[0]):
plt.plot(seg[:,0], seg[:,1], '.-', label=ii)
plt.legend(fontsize=9, loc='best')
在上面的示例中,只给出了一个级别,因此len(C.allsegs)
= 1。你得到:
等高线图
提取的曲线
答案 2 :(得分:2)
答案 3 :(得分:0)
所有路径的顶点都可以通过以下方式以float64的numpy数组形式返回:
cn.allsegs[i][j] # for element j, in level i
更详细:
遍历集合并提取路径和顶点并不是最直接或最快的操作。返回的Contour对象实际上通过cs.allsegs
拥有线段的属性,该属性返回嵌套的[level] [element] [vertex_coord]形状的列表:
num_levels = len(cn.allsegs)
num_element = len(cn.allsegs[0]) # in level 0
num_vertices = len(cn.allsegs[0][0]) # of element 0, in level 0
num_coord = len(cn.allsegs[0][0][0]) # of vertex 0, in element 0, in level 0