【问题标题】:Python: select points that fall within two arbitrary curvesPython:选择落在两条任意曲线内的点
【发布时间】:2017-10-15 02:34:06
【问题描述】:

我想选择落在两条任意曲线内的点,每条曲线都由一个点数组定义。下面是一个例子。实际上,我所拥有的曲线不是基于函数形式,它们是数组。我怎样才能只选择落在红色和蓝色曲线内的点,然后说,给它们涂上不同的颜色?

import numpy as np
import matplotlib.pyplot as plt

# generate arrays from gaussian
x = np.linspace(0.5, 3.5, 120)
y = np.exp(-np.power(x - 2, 2.) / (2 * np.power(.8, 2.)))
yy = .5*np.exp(-np.power(x - 2, 2.) / (2 * np.power(.4, 2.)))

# generate random data points
data_x = 4*np.random.rand(1000)
data_y = np.random.rand(1000)

fig = plt.figure()
ax = plt.axes()
ax.scatter(data_x, data_y, c='k', s=.1)
ax.scatter(x,y, s=3)
ax.scatter(x,yy, c='r', s=3)
plt.show()

【问题讨论】:

  • 对这些曲线进行插值(scipy;插值类型需要一些模型决策;可能是单调的),然后是布尔逻辑(它已经是 mpl 的 fill_between API 的一部分 -> arg where)。理论评论:您将总是需要某种具有不完整曲线的先验假设/正则化;在这种情况下是插值的一部分。
  • 在您的实际数据中,两条曲线和数据的x值是否相同? ... (x0, x1, x2, x3, ...) 对于所有三个数据集是否相同?
  • 是的,我想我需要插值。你有你描述的代码吗?
  • 不,x数据不一样。
  • @sascha 所说的:使用 Numpy Polynomial 函数/类/方法之一(或 SciPy)为两条曲线创建多项式并将它们用作上下界:遍历数据;评估每个基准 x 值处的曲线;比较 y 值;保留/丢弃。

标签: python python-2.7 numpy matplotlib interpolation


【解决方案1】:

您可以使用numpy.interp 在定义曲线的数组的位置上插入点。

c1 = data_y > np.interp(data_x, x,yy)
c2 = data_y < np.interp(data_x, x,y)

然后将散点图的颜色设置为c=(c1&amp;c2) 并选择一个颜色图。

ax.scatter(data_x, data_y, c=(c1&c2), s=1, cmap="summer_r")

完整示例:

import numpy as np
import matplotlib.pyplot as plt

# generate arrays from gaussian
x = np.linspace(0.5, 3.5, 120)
y = np.exp(-np.power(x - 2, 2.) / (2 * np.power(.8, 2.)))
yy = .5*np.exp(-np.power(x - 2, 2.) / (2 * np.power(.4, 2.)))

# generate random data points
data_x = 4*np.random.rand(1000)
data_y = np.random.rand(1000)

c1 = data_y > np.interp(data_x, x,yy)
c2 = data_y < np.interp(data_x, x,y)

fig = plt.figure()
ax = plt.axes()
ax.scatter(data_x, data_y, c=(c1&c2), s=1, cmap="summer_r")
ax.scatter(x,y, s=3)
ax.scatter(x,yy, c='r', s=3)
plt.show()

【讨论】:

    【解决方案2】:

    这是我的尝试。它实现了 numpy 插值函数,np.interp(),如 cmets 中所述。

    import numpy as np
    import matplotlib.pyplot as plt
    
    # generate arrays from gaussian
    x = np.linspace(0, 5, 120)
    
    # 2 sets of y's for given x
    # these can be any reasonable array of numbers
    y = np.exp(-np.power(x - 2, 2.) / (2 * np.power(.8, 2.)))
    yy = .5*np.exp(-np.power(x - 2, 2.) / (2 * np.power(.4, 2.)))
    
    fig = plt.figure()
    fig.set_size_inches(9, 7)
    ax = plt.axes()
    
    # plot curves using interpolating data
    numpnts = 60
    xs = np.linspace(0, 4, numpnts)
    ys1 = np.interp(xs, x, y)
    ys2 = np.interp(xs, x, yy)
    
    #ax.scatter(xs,ys1, c='b', s=8)  # blue
    #ax.scatter(xs,ys2, c='r', s=8)  # red
    
    # for the reference curves
    # better use plot than scatter
    ax.plot(xs, ys1, 'b^-', xs, ys2, 'ro-', markersize=4, linewidth=0.3)  # blue
    
    # this function uses the interpolated data just created
    # and helps build color array for scatter plot
    def in_btw(x, y):
        uppr = np.interp(x, xs, ys1)
        lowr = np.interp(x, xs, ys2)
        tf1 = lowr < y
        tf2 = y < uppr
        colr = 'c'
        if tf1 and tf2:
            colr = 'pink'
        return colr
    
    # generate random data points
    data_x = 4*np.random.rand(1200)
    data_y = np.random.rand(1200)
    
    clrs = []
    for ix,ea in enumerate(data_x):
        #print (ea, in_btw(ea, data_y[ix]))
        ret = in_btw(ea, data_y[ix])
        clrs.append(ret)
    
    # scatter plot of the data points with distinct colors
    # color: pink if location is between the 2 curves, else, cyan
    ax.scatter(data_x, data_y, c=clrs, s=4)
    
    plt.show()
    

    生成的图像:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-24
      • 1970-01-01
      • 2019-12-10
      相关资源
      最近更新 更多