我试图绘制一个动画正弦信号,好像它正穿过图形窗口一样。因此,我希望3秒正弦信号通过动画中的2秒窗口需要5秒。
但是,实时查看弹出图,使用下面的代码(改编自这个出色的教程:https://jakevdp.github.io/blog/2012/08/18/matplotlib-animation-tutorial/),机器上的时钟时间要花两倍的时间。
虽然在指定的帧频下录制的视频还是可以的。
我似乎看不出我在逻辑上做错了什么。这仅仅是性能问题吗?如果是这样,我应该如何在有约束的情况下优化代码,例如,如果可能的话,我希望不必降低采样率?目的是为绘制来自网络的实时数据做准备。
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
import sys
# Signal comes in from right to left.
SR = 44100 # sampling rate in Hz
DurSec = 3 # Signal duration in seconds
Freq = 440 # frequency in Hz
Amp = 1.0 # amplitude
WindowDurSec = 2 # figure window size in seconds
FPS = 30 # frame per second
msPerSec = 1000
frameDurMs = int(np.floor(1 / FPS * msPerSec)) # animation frame duration
passThruSec = WindowDurSec + DurSec # Playback stops at DurSec, but graph moves on until leaving window.
passThruFrames = int(round(FPS * passThruSec)) # number of frames of the entire animation.
sampPerFrame = int(frameDurMs/1000*SR) # frame size in samples
sampPerWindow = int(SR*WindowDurSec) # window size in samples
x = np.linspace(0, DurSec, int(SR*DurSec))
y = Amp * np.sin(2 * np.pi * Freq * x) # effective signal
# Add head and tail = 2 * windowSize
pad = np.zeros((sampPerWindow,), dtype=float)
Y = np.concatenate((pad, y, pad))
# Set up the figure
fig = plt.figure()
ax = plt.axes(xlim=(0, WindowDurSec), ylim=(-2*Amp, 2*Amp))
line, = ax.plot([], [], lw=2)
# initialization function: plot the background of each frame
def init():
line.set_data([], [])
return line,
# animation function. This is called sequentially
def animate(i):
x = np.linspace(0, WindowDurSec, sampPerWindow)
start = i*sampPerFrame
stop = start + sampPerWindow
step = 1
y = Y[start : stop : step]
line.set_data(x, y)
return line,
# call the animator.
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=passThruFrames, interval=frameDurMs, blit=True, repeat=False)
anim.save('sinewave_animation.mp4', fps=FPS, extra_args=['-vcodec', 'libx264'])
plt.show()