我希望通过一些基本过滤(带阻,带通)实时显示一个测量信号。
当我这样做的时候,我会得到一些jello effet(抱歉Gif质量不好)
即使它不是正在发生的事情,让我假装我用伪代码实现了这个算法:
signal = np.array(some_data)
plot = FuncAnimation(init_function, update_function)
for each frame:
- shift signal on the left # make space and discard oldest samples
- add new samples on the right
- filtered_signal = filter(signal) # using signal.butter and signal.filtfilt
- update_plot(filtered_signal) # FuncAnimation update function
我正在寻找摆脱这种不良影响的技巧。有什么想法吗?
编辑1
如果没有动画,则会附加20个连续滤波信号。
signal
(原始信号)filtered_signal
filtered_signal
编辑2
signal
是一个固定大小的缓冲区,包含N = 1000个样本filtered_signal
是从头开始为每个框架创建的编辑3 这是一个完整的工作示例:
源代码:
import matplotlib.pyplot as plt
import numpy as np
from scipy import signal
import matplotlib.animation as animation
import time
N = 1000
fs = 250
last_update = time.time()
sample_id = 0
def all_samples(length=10000):
# generate a dummy signal
st = 1.0 / fs
t = np.arange(length) * st
sig1 = 1*np.sin(2*np.pi * 2*t) + 2
sig2 = 0.25*np.sin(2*np.pi * 3*t) + 4
sig3 = 2*np.sin(2*np.pi * 4*t) + 5
return sig1 + sig2 + sig3
def band_pass(low_cut, high_cut, order=2):
# compute butterworth b, a coefficients
band = np.array([low_cut, high_cut])
Wn = band / (float(fs/2.0))
b, a = signal.butter(order, Wn, 'bandpass')
return b, a
def filter(raw_signal):
# apply filter
b, a = band_pass(0.5, 120)
return signal.filtfilt(b, a, raw_signal)
def init():
# init function for FuncAnimation blit=True
global axe_raw, line_raw
global axe_filt, line_filt
line_filt.set_visible(False)
line_raw.set_visible(False)
axe_raw.set_xlim(0, 1000)
axe_raw.set_ylim(5, 15)
axe_filt.set_xlim(0, 1000)
axe_filt.set_ylim(-5, 5)
return line_raw, line_filt,
def update(n):
global raw_signal, axe_raw, line_raw
global axe_filt, line_filt
global last_update, fs, sample_id
if n == 1:
line_raw.set_visible(True)
line_filt.set_visible(True)
# add new samples
now = time.time()
sample_count = int((now - last_update) * fs)
raw_signal = np.roll(raw_signal, -sample_count)
raw_signal[-sample_count:] = all_samples[sample_id:sample_id + sample_count]
last_update = now
sample_id += sample_count
# update plot (raw + filtered)
line_raw.set_ydata(raw_signal)
line_filt.set_ydata(filter(raw_signal))
return line_raw, line_filt
all_samples = all_samples()
raw_signal = np.zeros(N)
# matplotlib animation
figure = plt.figure()
axe_raw = figure.add_subplot(211)
axe_filt = figure.add_subplot(212)
line_raw, = axe_raw.plot(raw_signal)
line_filt, = axe_filt.plot(np.zeros(N))
anim = animation.FuncAnimation(figure,
update,
init_func=init,
interval=5,
blit=True)
plt.show()