How to plot Spectrogram using STFT in python?
17,284
Solution 1
what you can do is use this
first method:
import scipy.io.wavfile as wav
import scipy.signal as signal
from matplotlib import pyplot as plt
sample_rate, samples = wav.read(filename)
f, t, Zxx = signal.stft(samples, fs=sample_rate)
plt.pcolormesh(t, f, np.abs(Zxx), cmap=cmap)
or the second method:
plt.specgram(samples, cmap=cmap, Fs=sample_rate)
I found the second one have a better visualization effect. Not sure how to make the first one look as good as the second one though.
Solution 2
import os
import librosa
import librosa.display
import IPython.display as ipd
import numpy as np
import matplotlib.pyplot as plt
filename = '<yourfile name/ location>'
x, sr = librosa.load(filename)
import librosa.display #explicitly import librosa.display
X = librosa.stft(x) #perform short-term fourier transfrom
Xdb = librosa.amplitude_to_db(abs(X)) #convert an amplitude spectrogram to dB-scaled spectrogram.
plt.figure(figsize=(15, 5)) #initialize the fig size
librosa.display.specshow(Xdb, sr=sr, x_axis='time', y_axis='hz')
plt.colorbar()```
Author by
Jay Krishna
Updated on June 04, 2022Comments
-
Jay Krishna about 2 years
I calculated STFT of uint8 I/Q data and stored it in a numpy matrix where each row stores STFT of one window as shown in sudo code below.
#k= length of window #fs= Sampling frequency #n= Number of STFT calculated #matrix= Initially empty numpy array for i in range(0,n): t=data[start:end,:] #start & end calculated with each iteration t=t.flatten() t=t-127.5 array = np.empty(t.shape[0]//2, dtype=np.complex128) array.real = t[::2] array.imag = t[1::2] transform=(np.fft.fft(temp_array)) line = 2*abs(transform)/k #Inserting row into numpy array if(i==0): matrix = np.hstack((matrix, line)) else: matrix = np.vstack((matrix, line))
Now how can I plot frequency vs time Spectrogram ?
-
user2027202827 about 7 yearshave you looked into matplotlib?
-
Jay Krishna about 7 yearsYes I did both into matplotlib as well as scipy but both were not working fine with complex numpy array
-
MB-F about 7 yearsWhy complex arrays? Taking the absolute value of the FFT should result in real values that can be easily plotted with matplotlib's
imshow
. Just take care not to initializematrix
with complex data type. -
Jay Krishna about 7 years@kazemakase You mean using imshow with extent after taking absolute i.e ax.imshow(np.absolute(matrix),extent=[0,100,0,1]) ? I am assuming frequency will be on Y-axis.
-
MB-F about 7 years@JayKrishna yes, that should work as expected. Stil... it looks like you only put absolute values into
line
and thus inmatrix
anyway so it is surprising that you have complex values inmatrix
. -
Ahmed Fasih about 7 yearsSee the example at the bottom of docs.scipy.org/doc/scipy/reference/generated/…
-
Tom Wyllie almost 5 yearsPossible duplicate of How to convert a .wav file to a spectrogram in python3
-
-
Chase Roberts almost 5 yearscmap is undefined.
-
jcoppens over 4 years(second) cmap must be eplaced with the name of a colormap. In the Gallery on matplotlib.org is a drawing with all available colormaps, their names. and how to use them.
-
jcoppens over 4 yearsOops. Gallery is not on the front page anymore. It's under examples now. Check this: matplotlib.org/gallery/color/…
-
alienflow over 3 yearsTo achieve on the first the looks of second just do np.log() of np.abs(Zxx)