1

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 ?

Jay Krishna
  • 23
  • 1
  • 1
  • 5
  • have you looked into matplotlib? – user2027202827 Mar 30 '17 at 06:30
  • Yes I did both into matplotlib as well as scipy but both were not working fine with complex numpy array – Jay Krishna Mar 30 '17 at 06:33
  • Why complex arrays? Taking the absolute value of the FFT should result in real values that can be easily plotted with matplotlib's [`imshow`](http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.imshow). Just take care *not* to initialize `matrix` with complex data type. – MB-F Mar 30 '17 at 07:11
  • @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. – Jay Krishna Mar 30 '17 at 07:23
  • @JayKrishna yes, that should work as expected. Stil... it looks like you only put absolute values into `line` and thus in `matrix` anyway so it is surprising that you have complex values in `matrix`. – MB-F Mar 30 '17 at 07:29
  • See the example at the bottom of https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.spectrogram.html – Ahmed Fasih Mar 30 '17 at 11:12
  • Possible duplicate of [How to convert a .wav file to a spectrogram in python3](https://stackoverflow.com/questions/44787437/how-to-convert-a-wav-file-to-a-spectrogram-in-python3) – Tom Wyllie Aug 11 '19 at 18:46

2 Answers2

7

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.

díyuanlu
  • 85
  • 1
  • 4
  • cmap is undefined. – Chase Roberts Sep 08 '19 at 15:43
  • 1
    (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 Oct 23 '19 at 04:23
  • Oops. Gallery is not on the front page anymore. It's under examples now. Check this: https://matplotlib.org/gallery/color/colormap_reference.html#sphx-glr-gallery-color-colormap-reference-py – jcoppens Oct 23 '19 at 04:28
  • To achieve on the first the looks of second just do np.log() of np.abs(Zxx) – alienflow Oct 13 '20 at 21:48
1
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()```
wuerfelfreak
  • 2,363
  • 1
  • 14
  • 29