【问题标题】:matplotlib - extracting data from contour linesmatplotlib - 从等高线中提取数据
【发布时间】:2011-08-05 16:21:33
【问题描述】:

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

基于在类似问题中找到的示例:How can I get the (x,y) values of the line that is ploted by a contour plot (matplotlib)?

>>> 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 对象中获取数据吗?从matplotlib.path 提取数据时是否需要注意一些陷阱?

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

【问题讨论】:

    标签: python numpy matplotlib scipy contour


    【解决方案1】:

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

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

    更详细:

    遍历集合并提取路径和顶点并不是最直接或最快的事情。返回的 Contour 对象实际上通过 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

    【讨论】:

      【解决方案2】:

      我遇到了类似的问题,偶然发现了this 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()
      

      【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

        对于给定的路径,你可以得到这样的点:

        p = cs.collections[0].get_paths()[0]
        v = p.vertices
        x = v[:,0]
        y = v[:,1]
        

        【讨论】:

        • 这真的很有用,谢谢!您知道在等高线曲线上获取/插值等距点的任何方法吗? (这种方式返回的点不等间距)
        猜你喜欢
        • 1970-01-01
        • 2022-08-19
        • 1970-01-01
        • 2017-07-12
        • 2012-07-18
        • 1970-01-01
        • 1970-01-01
        • 2011-12-24
        相关资源
        最近更新 更多