-1

I am trying to plot the spectrogram of a signal along with the signal on the same plot as shown in figure:

enter image description here

The raw data is available here. But the signal and its spectrogram is not aligned. Why does this happen and how to align both of them in matplotlib?

Reproducible code

from __future__ import division
from matplotlib import ticker as mtick
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
import numpy as np

data = np.genfromtxt('spectrogram.dat', skiprows = 2, delimiter = ',')
pressure = data[:, 1] * 0.065
theta = data[:, 0]


with PdfPages('Spectorgram of cylinder pressure.pdf') as spectorgram_pressure:
    _spectorgram_pressure_vs_frequency_ = plt.figure(figsize=(5.15, 5.15))
    _spectorgram_pressure_vs_frequency_.clf()
    spectorgram_pressure_vs_frequency = plt.subplot(111)
    cax = plt.specgram(pressure * 100000, NFFT = 256, Fs = 50000, cmap=plt.cm.gist_heat, zorder = 1)
    spectorgram_pressure_vs_frequency.grid(False, which="major")
    spectorgram_pressure_vs_frequency.set_xlabel('Time (s)', labelpad=6)
    spectorgram_pressure_vs_frequency.set_ylabel('Frequency (Hz)', labelpad=6)
    y_min, y_max = spectorgram_pressure_vs_frequency.get_ylim()
    cbar = plt.colorbar(orientation='vertical', ax = spectorgram_pressure_vs_frequency, fraction = 0.046, pad = 0.2)
    cbar.set_label('Power spectral density (dB)', rotation=90)
    primary_ticks = len(spectorgram_pressure_vs_frequency.yaxis.get_major_ticks())
    pressure_vs_time = spectorgram_pressure_vs_frequency.twinx()
    pressure_vs_time.grid(False)
    pressure_vs_time.plot(theta / 1000, pressure, linewidth = 0.75, linestyle = '-', color = 'k', alpha = 0.7, zorder = 3)
    pressure_vs_time.set_ylabel('Cylinder pressure (bar)', labelpad=6)
    pressure_vs_time.yaxis.set_major_locator(mtick.LinearLocator(primary_ticks))
    # spectorgram_pressure_vs_frequency.set_xlim([0, max(cax[2])])
    spectorgram_pressure.savefig(bbox_inches='tight')
Tom Kurushingal
  • 6,086
  • 20
  • 54
  • 86

1 Answers1

1

I have never used this function before, but the documentation was very helpful. I intend no offense in saying this (and I may be wrong about you in particular), but there is an ever growing number of "data analysts" who implement functions without knowing what they do or even having a fundamental understanding of the theory behind them. Of course, we cannot know everything about everything, but we should at least make some effort to understand.

The problem in your usage is the NFFT setting, which controls how many data points go into each block of the fast-fourier transform (FFT). The NFFT number is partially controlled by the number of overlap values (noverlap, defaults to 256) that you set (you do not have this set in your code). Therefore, if you set NFFT < 256 you will get an error unless you also adjust the noverlap. Try something like this:

cax = plt.specgram(pressure * 100000, NFFT = 32, Fs = 50000, noverlap=4, cmap=plt.cm.gist_heat, zorder = 1)

You can play around with the NFFT and novrlap settings to achieve whatever is optimal for your goals. While doing this you will notice that as NFFT increases your FFT spectrogram will shift to the left, which mathematically makes sense

tnknepp
  • 5,888
  • 6
  • 43
  • 57