Spectrogram of a single tone complex signal has two dark lines?

I am trying to plot the spectrogram of a complex signal I generated. I have written code to generate this signal and plot the spectrogram. It works. However I see that there are two dark lines present within the spectrogram. I'm curious to know the reason for the existence of these. I have also noticed that by varying the NFFT, the dark lines tend wobble around.

I paste my code below:

import matplotlib.pyplot as plt
import numpy as np
import scipy.signal as signal

def plot_spectrogram(data,NFFT,Fs,ex ):
plt.specgram(data, NFFT=NFFT, Fs=Fs)
plt.title("Spectrogram of data")
plt.ylim(-Fs/2, Fs/2)
plt.show()
plt.close()

if ex:
exit()

###  Parameters
F_offset = 250000
Fs = 1140000

###  Generate a digital complex exponential with phase -F_offset/Fs
fc1 = np.exp(-1.0j*2.0*np.pi* F_offset/Fs*np.arange(len(x1)) )
plot_spectrogram(fc1, 512, Fs,ex=True)

• your code is missing where you define the x1 :) – Marcus Müller May 24 '19 at 7:13

Since this is a constant spectrogram, you could just as well have just averaged the |FFT|² and plotted that! (The most colorful way of visualizing things isn't always the optimal one; your signal doesn't change over time, so you don't need the time axis of the spectrogram at all.)

Quite possibly, in that "easier" representation, you would have spotted this:

Your spectrogram does FFTs of length 512. That's not a multiple of the period of your discrete complex sinusoid.

Therefore you'll see leakage. (You already know that effect!)

However, to reduce that resolution-reducing leakage effect, specgram applies a Hanning window by default to your 512-sample chunks that you FFT.

That hanning window leads to zeros:

plt.plot(20*np.log10(np.abs(np.fft.fft(fc1[:512]*np.hanning(512)))))


And there you go!

• Really appreciate your effort Marcus as always. – Denis May 27 '19 at 3:01