2017-10-15 160 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