Python:从matplotlib.pyplot.contour()中查找等高线

2024-06-02 05:12:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我在找(但不是画画!)某些数据的等高线:

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是一个线段数组,但是 无法找出如何提取这些段。

我的最终目标是创建一个KML文件,该文件在一个世界上绘制数据 地图,以及数据的等高线。

但是,因为我的一些数据点很接近 很遥远,我需要真正的多边形(线串)组成 轮廓,不仅仅是轮廓的光栅化图像。

我有点惊讶qhull没有这样做。

使用Mathematica的ListContourPlot,然后导出为SVG,但是 想用一些开源的东西。

我不能使用著名的CONREC算法,因为我的数据不在 网格(对于给定的x值,并不总是有多个y值,并且 反之亦然)。

解决方案不必使用python,但必须是开源的 在Linux上运行。


Tags: 文件数据importmatplotlibdir开源数组cn
3条回答

我建议使用scikit图像find_contours

它返回给定级别的轮廓列表。

matplotlib._cntr已从matplotlib中删除(请参见here)。

您可以通过循环集合和路径并使用^{}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._cntrC模块计算轮廓,而无需绘制任何内容:

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

enter image description here

轮廓数据似乎位于plt.contour()函数返回的QuadContourSet对象的.allsegs属性中。

.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。你得到:

等高线图

提取的曲线

相关问题 更多 >