我目前正在尝试识别我创建的随机生成的绘图中的峰值。
我的代码如下:
x_range = np.arange(0,100,0.5) #my x values
for i in len(ys): #ys is my range of y values on the chart
for j in range(start,len(ys)): #Brute forcing peak detection
temp.append(ys[j])
check = int(classtest.isPeak(temp)[0])
if check == 1:
xval = temp.index(max(temp)) #getting the index
xlist = x_range.tolist()
plt.plot(xlist[xval],max(temp),"ro")
start = start + 1
temp = []
然而,当绘制图表上的值时,它似乎绘制了正确的y位置,而不是x。这是一个正在发生的事情的例子:
我真的不确定是什么导致了这个问题,我希望得到一些帮助。
由于
答案 0 :(得分:3)
请注意temp
随着start
的增加而越来越短。
因此,与xval
中的最大值对应的索引temp
本身并不是x_range
的正确索引。相反,您必须将xval
增加start
才能在x_range
中找到相应的索引:
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(2016)
N = 100
ys = (np.random.random(N)-0.5).cumsum()
xs = np.linspace(0, 100, len(ys))
plt.plot(xs, ys)
start = 0
temp = []
for i in range(len(ys)): #ys is my range of y values on the chart
for j in range(start,len(ys)): #Brute forcing peak detection
temp.append(ys[j])
xval = temp.index(max(temp)) #getting the index
plt.plot(xs[xval+start], max(temp),"ro")
start = start + 1
temp = []
plt.show()
虽然确实设法将红点放在图表上的点上,但你可以
看到算法是在图上的每个点放置一个点,而不仅仅是在本地
最大值。部分问题是当temp
只包含一个点时,它就是
当然是最大的双循环确保每个点都得到
考虑到,所以在某些时候temp
仅包含图上的每个点作为a
单点。
需要不同的算法。可以将本地最大值识别为任何 比邻居大的点:
ys[i-1] <= ys[i] >= ys[i+1]
因此,您可以使用:
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(2016)
N = 100
ys = (np.random.random(N)-0.5).cumsum()
xs = np.linspace(0, 100, len(ys))
plt.plot(xs, ys)
idx = []
for i in range(1, len(ys)-1):
if ys[i-1] <= ys[i] >= ys[i+1]:
idx.append(i)
plt.plot(xs[idx], ys[idx], 'ro')
plt.show()
请注意,scipy.signal.argrelextrema
或scipy.signal.argrelmax
也可用于查找本地最大值:
from scipy import signal
idx = signal.argrelextrema(ys, np.greater)
plt.plot(xs[idx], ys[idx], 'ro')
产生相同的结果。