Построение временной последовательность в реальном времени
Всем привет. Нужна ваша срочная помощь. Как сделать так, чтобы график чертился в реальном времени. Те брал 1 значение из массива и заносил их на график, а потом брал следующую "точку". На данный момент он строит сразу все целиком. Заранее спасибо за помощь.
import numpy
import matplotlib.pyplot as plt
from scipy.io import wavfile
from scipy.fftpack import fft
#Указываем путь до аудио файла
myAudio = "C:\\Users\\denga\\Desktop\\gh\\22.wav"
#Чтение файла и получение частоты дискретизации и звукового объект
samplingFreq, mySound = wavfile.read(myAudio)
#Проверяем является ли wave-файл 16-битным или 32-битным. (24 бит не поддерживается)
mySoundDataType = mySound.dtype
#Мы можем преобразовать наш звуковой массив в значения с плавающей запятой в диапазоне от -1 до 1 следующим образом
mySound = mySound / (2.**15)
#Проверим точки отсчета и звуковой канал для двух каналов или для моноканала
mySoundShape = mySound.shape
samplePoints = float(mySound.shape[0])
#Получим продолжительность звукового файла
signalDuration = mySound.shape[0] / samplingFreq
#Если два канала, то выберем только один кана
mySoundOneChannel = mySound[:,0]
#Построение графика тона
#Мы можем представить звук, построив значения давления по оси времени.
#Создание массива выборочных точек в одном измерении
timeArray = numpy.arange(0, samplePoints, 1)
timeArray = timeArray / samplingFreq
# Масштабируем до миллисекунд
timeArray = timeArray * 1000
#Построим график тона
plt.plot(timeArray, mySoundOneChannel)
plt.xlabel('Время (ms)')
plt.ylabel('Амплитуда')
plt.show()
#График частотного содержания
#Мы можем получить частоту из амплитуды и времени с помощью БПФ, быстрого алгоритма преобразования Фурье
#Получим длину моего массива звуковых объектов
mySoundLength = len(mySound)
#Возьмем преобразование Фурье для данной точки отсчета
fftArray = fft(mySoundOneChannel)
numUniquePoints = int(numpy.ceil((mySoundLength + 1) / 2.0))
fftArray = fftArray[0:numUniquePoints]
#БПФ содержит как величину, так и фазу и задается комплексными числами в формате действительных + мнимых частей (a + ib).
#Принимая абсолютное значение, мы получаем только действительную часть.
fftArray = abs(fftArray)
#Масштабируйте массив fft по длине точек выборки, чтобы величина не зависела отдлина сигнала или его частота дискретизации
fftArray = fftArray / float(mySoundLength)
#БПФ имеет как положительную, так и отрицательную информацию. Площадь возводим в квадрат, чтобы получить только положительные значения
fftArray = fftArray **2
if mySoundLength % 2 > 0: #у нас есть нечетное число точек в FFT
fftArray[1:len(fftArray)] = fftArray[1:len(fftArray)] * 2
else: #У нас есть чётное количество точек в БПФ
fftArray[1:len(fftArray) -1] = fftArray[1:len(fftArray) -1] * 2
freqArray = numpy.arange(0, numUniquePoints, 1.0) * (samplingFreq / mySoundLength)
#Постройка спектра частоты
plt.plot(freqArray/1000, 10 * numpy.log10 (fftArray))
plt.xlabel('Частота (Khz)')
plt.ylabel('Мощность (dB)')
plt.show()
Ответы (1 шт):
Автор решения: mkkik
→ Ссылка
Вот пример, как можно отобразить процесс в "реальном времени" при помощи FuncAnimation:
import wave
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
# https://file-examples-com.github.io/uploads/2017/11/file_example_WAV_1MG.wav
file = 'file_example_WAV_1MG.wav'
data = wave.open(file, 'r')
if data.getsampwidth() != np.int16().nbytes:
raise TypeError("required 16-bit PCM")
nchannels = data.getnchannels()
nframes = data.getnframes()
fig, ax = plt.subplots(nchannels, 1)
samples = np.frombuffer(data.readframes(nframes), dtype=np.int16)
# выбран некоторый временной отрезок в 5000 отсчетов
samples = samples.reshape(-1, nchannels).T[:, 120000:125000]
samples_cnt = samples.shape[1]
xdata = []
ch1, ch2 = [ax.plot(xdata, [])[0] for ax in fig.axes]
def init():
iinfo = np.iinfo(samples.dtype)
plt.setp(ax, xlim=(0, samples_cnt), ylim=(iinfo.min, iinfo.max))
return ch1, ch2
def update(i):
xdata.append(i - 1)
ch1.set_data(xdata, samples[0, :i])
ch2.set_data(xdata, samples[1, :i])
return ch1, ch2
ani = FuncAnimation(fig, update, frames=range(1, samples_cnt), blit=True,
init_func=init, interval=1, repeat=False)
plt.show()
P.S. Данный подход ограничен в производительности (низкий FPS), но может быть использован для демонстрационных задач.