如何使用 matplotlib FuncAnimation 显示 numpy 数组的滑动 windows
How to show sliding windows of a numpy array with matplotlib FuncAnimation
我正在开发一种用于检测信号峰值的简单算法。为了对我的算法进行故障排除(并展示它),我想在整个信号持续时间内观察信号和检测到的峰值(即 100Hz
= 20000
时间点的 20
分钟).
我认为最好的方法是创建一个带有 matplotlib.animation.FuncAnimation
的动画图,它将连续显示信号滑动 1 个时间点及其在一段时间内的叠加峰值 windows 5
秒(即 500
时间点)。信号存储在一维 numpy.ndarray
中,而峰信息存储在二维 numpy.ndarray
中,包含峰的 x
和 y
坐标。
这是情节的“静止画面”。
现在的问题是我无法完全理解使用 FuncAnimation 执行此操作的方式。
如果我的理解是正确的,我需要三个主要部分:init_func
参数,一个创建绘制绘图的空框的函数,func
参数,即函数实际上为每个帧创建图,以及在帮助中定义为 Source of data to pass func and each frame of the animation
.
的参数 frames
查看带有 FuncAnimation
的绘图示例,我只能找到其中要绘制的数据是在移动中创建的用例,例如 here, or here,其中要绘制的数据是 在frame
.
的基础上创建
我不明白的是如何使用已经存在的数据来实现这一点,但这些数据是在框架的基础上 切片 的。因此,我需要 frame
作为一种滑动 window,其中第一个 window 从 0
到 499
,第二个从 1
到 500
等等,直到 ndarray
中的时间点结束,以及关联的 func
将 select 点绘制在frames
的基础。我不知道如何实现这个。
我添加代码来创建一个真实的信号,简单地检测峰值并绘制我想要制作动画的 'static' 版本的绘图:
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] 是开始行,id1 是结束行,帧数是 10。这段代码有效,但是初始设置和数据集在散点图中不起作用,所以我在循环过程中直接绘制了散点图。
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()
可能不是您想要的,希望对您有所帮助,
import neurokit2 as nk
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from sklearn.preprocessing import MinMaxScaler
import numpy as np
from matplotlib.animation import FuncAnimation
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
# This function is called periodically from FuncAnimation
def animate(i, xs, ys):
xs = xs[i]
ys = ys[i]
# Draw x and y lists
ax.clear()
ax.plot(xs, ys)
if __name__=="__main__":
data = nk.ecg_simulate(duration = 50, sampling_rate = 100, noise = 0.05, random_state = 1)
scaler = MinMaxScaler()
scaled_arr = scaler.fit_transform(data.reshape(-1,1))
ys = scaled_arr.flatten()
ys = [ys[0:50*i] for i in range(1, int(len(ys)/50)+1)]
xs = [np.arange(0, len(ii)) for ii in ys ]
ani = animation.FuncAnimation(fig, animate, fargs=(xs, ys), interval=500)
ani.save('test.gif')
我正在开发一种用于检测信号峰值的简单算法。为了对我的算法进行故障排除(并展示它),我想在整个信号持续时间内观察信号和检测到的峰值(即 100Hz
= 20000
时间点的 20
分钟).
我认为最好的方法是创建一个带有 matplotlib.animation.FuncAnimation
的动画图,它将连续显示信号滑动 1 个时间点及其在一段时间内的叠加峰值 windows 5
秒(即 500
时间点)。信号存储在一维 numpy.ndarray
中,而峰信息存储在二维 numpy.ndarray
中,包含峰的 x
和 y
坐标。
这是情节的“静止画面”。
现在的问题是我无法完全理解使用 FuncAnimation 执行此操作的方式。
如果我的理解是正确的,我需要三个主要部分:init_func
参数,一个创建绘制绘图的空框的函数,func
参数,即函数实际上为每个帧创建图,以及在帮助中定义为 Source of data to pass func and each frame of the animation
.
frames
查看带有 FuncAnimation
的绘图示例,我只能找到其中要绘制的数据是在移动中创建的用例,例如 here, or here,其中要绘制的数据是 在frame
.
我不明白的是如何使用已经存在的数据来实现这一点,但这些数据是在框架的基础上 切片 的。因此,我需要 frame
作为一种滑动 window,其中第一个 window 从 0
到 499
,第二个从 1
到 500
等等,直到 ndarray
中的时间点结束,以及关联的 func
将 select 点绘制在frames
的基础。我不知道如何实现这个。
我添加代码来创建一个真实的信号,简单地检测峰值并绘制我想要制作动画的 'static' 版本的绘图:
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] 是开始行,id1 是结束行,帧数是 10。这段代码有效,但是初始设置和数据集在散点图中不起作用,所以我在循环过程中直接绘制了散点图。
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()
可能不是您想要的,希望对您有所帮助,
import neurokit2 as nk
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from sklearn.preprocessing import MinMaxScaler
import numpy as np
from matplotlib.animation import FuncAnimation
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
# This function is called periodically from FuncAnimation
def animate(i, xs, ys):
xs = xs[i]
ys = ys[i]
# Draw x and y lists
ax.clear()
ax.plot(xs, ys)
if __name__=="__main__":
data = nk.ecg_simulate(duration = 50, sampling_rate = 100, noise = 0.05, random_state = 1)
scaler = MinMaxScaler()
scaled_arr = scaler.fit_transform(data.reshape(-1,1))
ys = scaled_arr.flatten()
ys = [ys[0:50*i] for i in range(1, int(len(ys)/50)+1)]
xs = [np.arange(0, len(ii)) for ii in ys ]
ani = animation.FuncAnimation(fig, animate, fargs=(xs, ys), interval=500)
ani.save('test.gif')