Plotting with matplotlib specgram?

11,100

Here a quick and dirty synthetic example of three tones an octave apart each, which works fine. Please read up on the sampling theorem to understand the idea of a spectrogram. It's actually best to first learn how to plot spectra (vertical slices of the spectrogram) by just playing with FFTs.

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

time1 = np.arange(0,5,0.0001)
time = np.arange(0,15,0.0001)
data1=np.sin(2*np.pi*300*time1)
data2=np.sin(2*np.pi*600*time1)
data3=np.sin(2*np.pi*900*time1)
data=np.append(data1,data2 )
data=np.append(data,data3)
print len(time)
print len(data)

NFFT = 200     # the length of the windowing segments
Fs = 500  # the sampling rate

# plot signal and spectrogram

ax1 = plt.subplot(211)
plt.plot(time,data)   # for this one has to either undersample or zoom in 
plt.xlim([0,15])
plt.subplot(212 )  # don't share the axis
Pxx, freqs, bins, im = plt.specgram(data, NFFT=NFFT,   Fs=Fs,noverlap=100, cmap=plt.cm.gist_heat)
plt.show() 

The top x-axis is in seconds.I zoomed in at the transition of 300 Hz to 600 Hz at 5 seconds for clarity. The bottom axis is not in seconds, which is why I took out the sharing of the axes. That can be fixed (detail). enter image description here

Share:
11,100
Dadep
Author by

Dadep

neurosciences

Updated on June 04, 2022

Comments

  • Dadep
    Dadep about 2 years

    I'm trying to plot a signal and the spectrogram of the signal with matplotlib, but... i get the spectrogram only for the first value (samples) of my signal (like 60 of the 30000...).

    It's a very long file, that's why I would like to plot only the first 30000 sample.

    here is the code :

    import matplotlib.pyplot as plt
    import numpy as np
    import pandas as pd
    
    Data=pd.read_csv('MySignal.txt', 
        skiprows=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19], 
        header=0)
    print(Data.head())
    DataI=Data['Sig'].tolist()
    print(len(Data.index))
    DataI=DataI[0:30000]
    
    NFFT = 200     # the length of the windowing segments
    Fs = 500  # the sampling rate
    
    # plot signal and spectrogram
    
    t=range(len(DataI))
    ax1 = plt.subplot(211)
    plt.plot(t, DataI)
    plt.subplot(212, sharex=ax1)
    Pxx, freqs, bins, im = plt.specgram(DataI, NFFT=NFFT, 
                            Fs=Fs,noverlap=100, cmap=plt.cm.gist_heat)
    plt.show() 
    

    I don't understand well how plt.specgram work, so i don't understand where is the problem...

    Thanks a lot !

    • roadrunner66
      roadrunner66 over 8 years
      It would help if you gave an executable example, e.g. with some synthetic data. Just something simple like an upchirp or a few sines with different frequencies. That would also be the best way to troubleshoot since you separate your (possibly undersampled) data from your analysis.
    • roadrunner66
      roadrunner66 over 8 years
      Very likely there is a sampling rate problem, since you generate your time as [0,1,2,3...] which is likely seconds, but you use a sampling rate of 500. So try dividing t by 1000 or so.
    • Dadep
      Dadep over 8 years
      Thanks a lot for your help, but I couldn't test it... now appear a MemoryError (seems to stop line 7, "header 0")... I do not understand why...
  • Dadep
    Dadep over 8 years
    Thanks a lot for your help,