Continuously updating audio waveform display using Python

While matplotlib works well for displaying static graphs and charts, sometimes we may need to display a continuous (live) waveform on a graph. This requires repeatedly retrieving and displaying samples of incoming data (an audio stream, for example). An interesting way to display such a continuously varying waveform is to use the ‘Animation’ classes built into matplotlib.

In this example, we utilize matplotlib’s FuncAnimation class that can take a user defined function (‘animate’) which, in turn, provides samples of data to display on the output trace. We utilize the audio stream from the PC’s default audio input device to retrieve audio data samples in ‘animate’. This results in a continuous trace of the audio stream.


import numpy as np
import pyaudio
from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
plt.style.use('bmh')

SAMPLESIZE = 4096 # number of data points to read at a time
SAMPLERATE = 44100 # time resolution of the recording device (Hz)

p = pyaudio.PyAudio() # instantiate PyAudio
stream=p.open(format=pyaudio.paInt16,channels=1,rate=SAMPLERATE,input=True,
              frames_per_buffer=SAMPLESIZE) # use default input device to open audio stream

# set up plotting
fig = plt.figure()
ax = plt.axes(xlim=(0, SAMPLESIZE-1), ylim=(-9999, 9999))
line, = ax.plot([], [], lw=1)

# x axis data points
x = np.linspace(0, SAMPLESIZE-1, SAMPLESIZE)

# methods for animation
def init():
    line.set_data([], [])
    return line,
def animate(i):
    y = np.frombuffer(stream.read(SAMPLESIZE), dtype=np.int16)
    line.set_data(x, y)
    return line,

FuncAnimation(fig, animate, init_func=init, frames=200, interval=20, blit=True)

plt.show()

# stop and close the audio stream
stream.stop_stream()
stream.close()
p.terminate()

Leave a Reply

Your email address will not be published. Required fields are marked *