Я пытаюсь построить анимированный синусоидальный сигнал, как будто он проходит через окно рисунка.Поэтому я ожидаю, что 3-секундный синусоидальный сигнал проходит через 2-секундное окно в моей анимации.
Однако, глядя на всплывающую фигуру в режиме реального времени, на моей машине требуется вдвое больше времени на часах, используя следующий код, адаптированный из этого превосходного урока: 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()