# Why does Matlab spectrogram look stripy when windowed input is zero-padded?

I am working on a little project, and stumpled upon something I cannot understand yet. I am learning cognitive science, and don't have DSP knowledge background, only learning from what I find on the internet. I have got an 46380x1 double array, which contains my signal. I would like to draw a nice spectrogram out of it like this:

%%signal = %%too long to put here, 46380x1 double array
winsize = ceil(length(signal)/10); %% =4639
win = rectwin(winsize);
shift = ceil(length(signal)/150); %% =310
nfft = winsize;
srate = 78;

spectrogram(signal, win, winsize-shift, nfft, srate, 'yaxis');
ylim([0.015 2]);


It works fine, and shows this:

But if I would like to zero pad the windowed signal (Matlab docs say, increasing nfft will do that), the output gets these stripes in it, and no matter what factor I scale "winsize" by, It will always show some kind of distortion in the spectrogram. For example I set nfft=round(1.5*winsize) before making the spectrogram, and the its output changed to this:

Why is this happening? I know I cannot increase the amount of information in the signal by zero padding, but it might be more readable to the human eye if not so pixelated, that's why I am trying to apply zero padding here. Can you please help, what I should try to achieve this without getting those lines?

Anyway, there is a huge magnitude output component of the spectrogram, throughout the whole time axis, at the very close-to-zero frequency, if I view the trajectory starting from 0hz. view(-135,65); ylim([0 2]); Why is that?

As already said by @ZR Han, the strong 0 Hz content or DC (direct current) indicates a potential offset with strong energy in the signal. Elsewhere, the first spectrogram does not show a lot for variations, as if the signal were very stationary. Another quite stationary content is the steady frequency around 0.22 Hz.

Hence, if a significant part of the energy of your signal dwells in a "sine plus offset", a zero padding may produce a quantity of artifacts. The graph below displays them for the FFT, and of course you will find the Fourier peaks and ripples as lines in your spectrogram.

So if the constant frequency around 0.22 Hz is a nuisance, a suggested pre-processing is:

• remove the average globally,
• remove the latter constant frequency with a notch filter,
• then inside a frame
• remove the local average (median/mean) from the frame (in case of localized trend changes or outliers)
• tapper the frame with a window that gently goes to zero

Then the padded spectrogram should exhibit other interesting non-stationary features.

Since I don't have your original data, I'm going to give the answer from my intuition. Try Hann window function and 50% overlap and see what happens.

I have tried a human voice signal as input and whether zero-padding is applied doesn't change the results.

% signal = ...
winsize = 512;
win = hann(winsize, 'periodic'); % use hann window instead of rectangular window
shift = winsize/2; % 50% overlap
nfft = winsize;
% nfft=round(1.5*winsize);
srate = 48e3;
figure;
spectrogram(signal, win, winsize-shift, nfft, srate, 'yaxis');


Here are the results:

Forgive me for the Chinese xlabel and ylabel, they are respectively "Time (s)" and "Frequency (kHz)", and the colorbar label stands for "Power/Frequency (dB/Hz)". I don't see any visible difference between the two figures.

In addition, you can use a smaller FFT size. Generally, using such a long FFT size means that you need an extremely high frequency resolution.

$$\Delta f = \frac{f_s}{\mathrm{NFFT}}$$

where $$\Delta f$$ is the frequency resolution, which is 0.0168 Hz when $$f_s$$ = 78 Hz and NFFT = 4639. While a super high frequency resolution means a super low time resulution with the fact that $$\Delta T = 1/ \Delta f$$. In your case you only have 10 time sample results.

For the second question, 0 Hz means the direct current (DC) component. Maybe you should add some information about what kind of signal are you analysing.