2017-10-15 158 views
1

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

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() 

enter image description here

+1

插值那些曲线(SciPy的;需要的那种内插的一些模型决定;可能是一些单调),然后布尔逻辑(这是部分mpl的fill_between API已经 - > arg where)。理论上的评论:你总是会需要某种先验假设/正则化,而不完全像这样的cuves;在这种情况下是插值的一部分。 – sascha

+0

在您的实际数据中,两条曲线和数据的x值是否相同? ...(x0,x1,x2,x3,...)对于所有三个数据集是相同的? – wwii

+0

是的,我想我需要内插。你有你描述的代码吗? – user2483176

回答

0

这里是我的尝试。它实现了numpy插值函数,如注释中提到的np.interp()

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() 

所得图像:

enter image description here

2

您可以使用numpy.interp上定义曲线阵列的位置内插的点。

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

然后设置散射作为c=(c1&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() 

enter image description here