我正在開發一種用於檢測信號峰值的簡單算法。為了對我的算法進行故障排除(並展示它),我想在整個信號持續時間內(即=時間點的20
分鐘)觀察信號和檢測到的峰值。100Hz
20000
我認為最好的方法是創建一個動畫圖,matplotlib.animation.FuncAnimation
它會連續顯示信號滑動 1 個時間點及其在5
幾秒的時間窗口(即500
時間點)內的疊加峰值。信號存儲在 1D 中,numpy.ndarray
而峰值信息存儲在numpy.ndarray
包含峰值x
和y
坐標的2D中。
這是情節如何的“靜止框架”。
現在的問題是我不能用 FuncAnimation 來解決這個問題。
If my understanding is correct I need three main pieces: the init_func
parameter, a function that create the empty frame upon which the plot is drawn, the func
parameter, that is the function that actually create the plot for each frame, and the parameter frames
which is defined in the help as Source of data to pass func and each frame of the animation
.
Looking at examples of plots with FuncAnimation
, I can only find use-cases in which the data to plot are create on the go, like here, or here, where the data to plot are created on the basis of the frame
.
What I do not understand is how to implement this with data that are already there, but that are sliced on the basis of the frame. I would thus need the frame
to work as a sort of sliding window, in which the first window goes from 0
to 499
, the second from 1
to 500
and so on until the end of the time-points in the ndarray
, and an associated func
that will select the points to plot on the basis of those frames
. I do not know how to implement this.
I add the code to create a realistic signal, to simply detect the peaks and to plot the 'static' version of the plot I would like to animate:
import neurokit2 as nk
from sklearn.preprocessing import MinMaxScaler
import matplotlib.pyplot as plt
from scipy.signal import find_peaks
#create realistic data
data = nk.ecg_simulate(duration = 50, sampling_rate = 100, noise = 0.05,\
random_state = 1)
#scale data
scaler = MinMaxScaler()
scaled_arr = scaler.fit_transform(data.reshape(-1,1))
#find peaks
peak = find_peaks(scaled_arr.squeeze(), height = .66,\
distance = 60, prominence = .5)
#plot
plt.plot(scaled_arr[0:500])
plt.scatter(peak[0][peak[0] < 500],\
peak[1]['peak_heights'][peak[0] < 500],\
color = 'red')
我已經使用您提供的數據創建了一個動畫;我已經為 5000 個數據以 500 個增量提取數據並更新了圖表。為了便於提取數據,我創建了一個 500 行的索引,其中 id[0] 是開始行,id 1是結束行,幀數為 10。這段代碼有效,但初始行settings 和 dataset 在散點圖中不起作用,所以我在循環過程中直接繪製了散點圖。
import neurokit2 as nk
from sklearn.preprocessing import MinMaxScaler
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from scipy.signal import find_peaks
import numpy as np
#create realistic data
data = nk.ecg_simulate(duration = 50, sampling_rate = 100, noise = 0.05, random_state = 1)
#scale data
scaler = MinMaxScaler()
scaled_arr = scaler.fit_transform(data.reshape(-1,1))
#find peaks
peak = find_peaks(scaled_arr.squeeze(), height = .66, distance = 60, prominence = .5)
ymin, ymax = min(scaled_arr), max(scaled_arr)
fig = plt.figure()
ax = fig.add_subplot(111)
line, = ax.plot([],[], lw=2)
scat = ax.scatter([], [], s=20, facecolor='red')
idx = [(s,e) for s,e in zip(np.arange(0,len(scaled_arr), 1), np.arange(499,len(scaled_arr)+1, 1))]
def init():
line.set_data([], [])
return line,
def animate(i):
id = idx[i]
#print(id[0], id[1])
line.set_data(np.arange(id[0], id[1]), scaled_arr[id[0]:id[1]])
x = peak[0][(peak[0] > id[0]) & (peak[0] < id[1])]
y = peak[1]['peak_heights'][(peak[0] > id[0]) & (peak[0] < id[1])]
#scat.set_offsets(x, y)
ax.scatter(x, y, s=20, c='red')
ax.set_xlim(id[0], id[1])
ax.set_ylim(ymin, ymax)
return line,scat
anim = FuncAnimation(fig, animate, init_func=init, frames=50, interval=50, blit=True)
plt.show()
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句