Python:从 matplotlib.pyplot.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)

我知道 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 算法,因为我的数据不在网格上(给定的 x 值并不总是有多个 y 值,反之亦然)。

该解决方案不一定是 python,但必须是开源的并且可以在 Linux 上运行。

原文由 Barry Carter 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 787
2 个回答

您可以通过遍历集合和路径并使用 --- 的 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

编辑:

也可以使用未记录的 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()

在此处输入图像描述

原文由 ali_m 发布,翻译遵循 CC BY-SA 3.0 许可协议

我建议使用 scikit-image find_contours

它返回给定级别的等高线列表。

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

原文由 Michele 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题