Python:从matplotlib.pyplot.contour()中查找轮廓线

bar*_*ter 19 python numpy spatial matplotlib contour

我试图为某些数据找到(但不是绘制!)轮廓线:

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) 
Run Code Online (Sandbox Code Playgroud)

我知道cn包含我想要的轮廓线,但我似乎无法找到它们.我尝试了几件事:

print dir(cn) 
pprint(cn.collections[0]) 
print dir(cn.collections[0]) 
pprint(cn.collections[0].figure) 
print dir(cn.collections[0].figure) 
Run Code Online (Sandbox Code Playgroud)

无济于事.我知道cn是一个ContourSet,并且cn.collections是一个LineCollections 数组.我认为a LineCollection是一系列线段,但我无法弄清楚如何提取这些段.

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

但是,由于我的一些数据点很接近,而其他数据点很远,我需要构成轮廓的实际多边形(线串),而不仅仅是轮廓的光栅化图像.

我有点惊讶qhull不做这样的事情.

使用Mathematica ListContourPlot然后导出为SVG工作,但我想使用开源的东西.

我不能使用众所周知的CONREC算法,因为我的数据不在网格上(对于给定的x值,并不总是有多个y值,反之亦然).

该解决方案不需要python,但必须是Linux上的开源和可运行的.

ali*_*i_m 23

您可以通过循环集合和路径并使用iter_segments()方法来获取顶点matplotlib.path.Path.

这是一个函数,它将顶点作为一组嵌套的轮廓线,轮廓截面和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
Run Code Online (Sandbox Code Playgroud)

编辑:

也可以在不使用未记录的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()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • ``matplotlib._cntr`` 不再可用(自 matplotlib 2.2 起)推荐的解决方案是使用 http://scikit-image.org/docs/dev/auto_examples/edges/plot_contours.html (3认同)

Mic*_*ele 5

我建议使用 scikit-image find_contours

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

matplotlib._cntr自 v2.2 起已从 matplotlib 中删除(请参见此处)。