Python 中的实时 FFT 绘图 (MatPlotLib)
Real Time FFT Plotting In Python ( MatPlotLib)
我有一个通过我的麦克风输入的音频流,pyaudio 正在读取它,我正在对该数据执行 FFT 计算,我想要的是在 Y 轴上绘制 FFT 幅度数据,在 Y 轴上绘制 FFT 频率数据X 轴并让它更新(例如 20fps),基本上看起来像这样( https://www.youtube.com/watch?v=Tu8p2pywJAs&t=93s )但是左边是低频,右边是高频。我所拥有的代码是我所拥有的
我是 python 的新手,更不用说任何形状或形式的编码了,所以任何帮助都将不胜感激,但请尽量使用易于理解的术语,如果我要求详细说明,请尊重, 非常感谢所有给我时间的人!
import pyaudio
import numpy as np
import time
import matplotlib.animation as animation
import matplotlib.pyplot as plt
from matplotlib import style
pa = pyaudio.PyAudio()
callback_output = []
def callback(in_data, frame_count, time_info, flag):
audio_data = np.fromstring(in_data, dtype=np.int16)
callback_output.append(audio_data)
return None,pyaudio.paContinue
stream = pa.open(format=pyaudio.paInt16,
channels=1,
rate=44100,
output=False,
input=True,
stream_callback=callback)
stream.start_stream()
fig = plt.gcf()
fig.show()
fig.canvas.draw()
while stream.is_active():
fft_data = np.fft.fft(callback_output)
fft_freq = np.fft.fftfreq(len(fft_data))
plt.plot(fft_freq,fft_data)
plt.xlim(min(fft_freq),max(fft_freq))
fig.canvas.draw()
plt.pause(0.05)
fig.canvas.flush_events()
fig.clear()
stream.close()
pa.terminate()
我无法为您生成数据,但我写了一个循环更新 matplotlib 图的示例:
import matplotlib.pyplot as plt
import numpy as np
import time
plt.ion() # Stop matplotlib windows from blocking
# Setup figure, axis and initiate plot
fig, ax = plt.subplots()
xdata, ydata = [], []
ln, = ax.plot([], [], 'ro-')
while True:
time.sleep(0.5)
# Get the new data
xdata = np.arange(10)
ydata = np.random.random(10)
# Reset the data in the plot
ln.set_xdata(xdata)
ln.set_ydata(ydata)
# Rescale the axis so that the data can be seen in the plot
# if you know the bounds of your data you could just set this once
# so that the axis don't keep changing
ax.relim()
ax.autoscale_view()
# Update the window
fig.canvas.draw()
fig.canvas.flush_events()
您应该能够更改循环中分配 xdata 和 ydata 的行,以使其适用于您的数据。
如果你想获得左侧的低频,你可能想看看在 fftfreq 和 fftdata 上使用 np.fft.fftshift:https://docs.scipy.org/doc/numpy/reference/generated/numpy.fft.fftshift.html
请试试这个代码:
while stream.is_active():
fft_data = np.fft.rfft(callback_output) # rfft removes the mirrored part that fft generates
fft_freq = np.fft.rfftfreq(len(callback_output), d=1/44100) # rfftfreq needs the signal data, not the fft data
plt.plot(fft_freq, np.absolute(fft_data)) # fft_data is a complex number, so the magnitude is computed here
plt.xlim(np.amin(fft_freq), np.amax(fft_freq))
fig.canvas.draw()
plt.pause(0.05)
fig.canvas.flush_events()
fig.clear()
我有一个通过我的麦克风输入的音频流,pyaudio 正在读取它,我正在对该数据执行 FFT 计算,我想要的是在 Y 轴上绘制 FFT 幅度数据,在 Y 轴上绘制 FFT 频率数据X 轴并让它更新(例如 20fps),基本上看起来像这样( https://www.youtube.com/watch?v=Tu8p2pywJAs&t=93s )但是左边是低频,右边是高频。我所拥有的代码是我所拥有的
我是 python 的新手,更不用说任何形状或形式的编码了,所以任何帮助都将不胜感激,但请尽量使用易于理解的术语,如果我要求详细说明,请尊重, 非常感谢所有给我时间的人!
import pyaudio
import numpy as np
import time
import matplotlib.animation as animation
import matplotlib.pyplot as plt
from matplotlib import style
pa = pyaudio.PyAudio()
callback_output = []
def callback(in_data, frame_count, time_info, flag):
audio_data = np.fromstring(in_data, dtype=np.int16)
callback_output.append(audio_data)
return None,pyaudio.paContinue
stream = pa.open(format=pyaudio.paInt16,
channels=1,
rate=44100,
output=False,
input=True,
stream_callback=callback)
stream.start_stream()
fig = plt.gcf()
fig.show()
fig.canvas.draw()
while stream.is_active():
fft_data = np.fft.fft(callback_output)
fft_freq = np.fft.fftfreq(len(fft_data))
plt.plot(fft_freq,fft_data)
plt.xlim(min(fft_freq),max(fft_freq))
fig.canvas.draw()
plt.pause(0.05)
fig.canvas.flush_events()
fig.clear()
stream.close()
pa.terminate()
我无法为您生成数据,但我写了一个循环更新 matplotlib 图的示例:
import matplotlib.pyplot as plt
import numpy as np
import time
plt.ion() # Stop matplotlib windows from blocking
# Setup figure, axis and initiate plot
fig, ax = plt.subplots()
xdata, ydata = [], []
ln, = ax.plot([], [], 'ro-')
while True:
time.sleep(0.5)
# Get the new data
xdata = np.arange(10)
ydata = np.random.random(10)
# Reset the data in the plot
ln.set_xdata(xdata)
ln.set_ydata(ydata)
# Rescale the axis so that the data can be seen in the plot
# if you know the bounds of your data you could just set this once
# so that the axis don't keep changing
ax.relim()
ax.autoscale_view()
# Update the window
fig.canvas.draw()
fig.canvas.flush_events()
您应该能够更改循环中分配 xdata 和 ydata 的行,以使其适用于您的数据。
如果你想获得左侧的低频,你可能想看看在 fftfreq 和 fftdata 上使用 np.fft.fftshift:https://docs.scipy.org/doc/numpy/reference/generated/numpy.fft.fftshift.html
请试试这个代码:
while stream.is_active():
fft_data = np.fft.rfft(callback_output) # rfft removes the mirrored part that fft generates
fft_freq = np.fft.rfftfreq(len(callback_output), d=1/44100) # rfftfreq needs the signal data, not the fft data
plt.plot(fft_freq, np.absolute(fft_data)) # fft_data is a complex number, so the magnitude is computed here
plt.xlim(np.amin(fft_freq), np.amax(fft_freq))
fig.canvas.draw()
plt.pause(0.05)
fig.canvas.flush_events()
fig.clear()