【问题标题】:How to extract points from a graph?如何从图中提取点?
【发布时间】:2012-04-08 16:48:37
【问题描述】:

我有一个问题。

我使用 Matplotlib 绘制了一个图表,如下所示:

from matplotlib import pyplot
import numpy
from scipy.interpolate import spline

widths = numpy.array([0, 30, 60, 90, 120, 150, 180])
heights = numpy.array([26, 38.5, 59.5, 82.5, 120.5, 182.5, 319.5])

xnew = numpy.linspace(widths.min(),widths.max(),300)
heights_smooth = spline(widths,heights,xnew)

pyplot.plot(xnew,heights_smooth)
pyplot.show()

现在我想使用宽度值作为参数来查询高度值。我似乎无法找到如何做到这一点。请帮忙!提前致谢!

【问题讨论】:

    标签: python numpy scipy matplotlib


    【解决方案1】:

    plot() 返回一个有用的对象:[<matplotlib.lines.Line2D object at 0x38c9910>]
    从中我们可以得到 x 轴和 y 轴的值:

    import matplotlib.pyplot as plt, numpy as np
    ...
    line2d = plt.plot(xnew,heights_smooth)
    xvalues = line2d[0].get_xdata()
    yvalues = line2d[0].get_ydata()
    

    然后我们可以得到其中一个宽度值的索引:

    idx = np.where(xvalues==xvalues[-2]) # this is 179.3979933110368
    # idx is a tuple of array(s) containing index where value was found
    # in this case -> (array([298]),)
    

    以及对应的高度:

    yvalues[idx]
    # -> array([ 315.53469])
    

    检查我们可以使用get_xydata():

    >>> xy = line2d[0].get_xydata()
    >>> xy[-2]
    array([ 179.39799331,  315.53469   ])
    

    【讨论】:

    • 感谢您的回复!我只需要对其进行一点小调整:idx=(numpy.abs(xvalues-<known_xvalue>)).argmin()。在此之后,yvalues[idx] 给了我我想要的东西。 :)
    【解决方案2】:

    您可以将数组转换为列表:

    >>> heights[list(widths).index(30)]
    38.5
    

    对于插值结果:

    s = xnew[56] 
    print s, heights_smooth[list(xnew).index(s)]
    33.7123745819, 40.9547542163
    

    由于xnew 是一个有序列表,您可以使用bisect module 为查询的宽度找到最接近的宽度值,然后以类似的方式找到相应的高度:

    ....
    import bisect
    pyplot.plot(xnew,heights_smooth)
    #33.1222 is a queried value which does not exist in xnew.
    index_of_nearest_width = bisect.bisect_left(xnew, 33.1222) 
    width_val = xnew[index_of_closest_width]
    print width_val, heights_smooth[list(xnew).index(width_val)]
    #prints the nearest width to 33.1222 then the corresponding height.
    33.7123745819 40.9547542163
    

    【讨论】:

      【解决方案3】:

      如果您愿意使用不同的样条函数,这里还有一个选择:

      from matplotlib import pyplot
      import numpy
      from scipy import interpolate
      
      widths = numpy.array([0, 30, 60, 90, 120, 150, 180])
      heights = numpy.array([26, 38.5, 59.5, 82.5, 120.5, 182.5, 319.5])
      
      xnew = numpy.linspace(widths.min(),widths.max(),300)
      heights_smooth = interpolate.splrep(widths,heights) #Use splrep instead of spline
      
      #Select desired width values
      width_vals = [0, 80.5, 38.98743]   
      
      #splev returns the value of your spline evaluated at the width values.    
      heights = interpolate.splev(width_vals, heights_smooth)
      

      然后

      In[]:  heights
      Out[]: array([ 26.        ,  74.1721985 ,  44.47929453])
      

      或者在某个点进行评估:

      w = 167.2
      heights = interpolate.splev(w, heights_smooth)
      height = heights.item()
      
      In[]:  height
      Out[]: 247.8396196684303
      

      .item() 函数是必要的,因为splev 返回一个array()

      【讨论】:

        猜你喜欢
        • 2015-01-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-09
        相关资源
        最近更新 更多