Наблюдаемая продолжительность анимации Matplotlib удвоилась по сравнению с теорией - PullRequest
0 голосов
/ 06 декабря 2018

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