1

in the below code i am trying to get the spectrogram of the non-stationary signalx after running the code, i expected to see some thing like the posted inage "image_2" , frequency vs time representation. but the resut of the posted code is image_1.

can any one please guide me to get the correct spectrogram?

Code

% Time specifications:
Fs = 8000;                       % samples per second
 dt = 1/Fs;                       % seconds per sample
  StopTime = 1;                    % seconds
  t = (0:dt:StopTime-dt);             % seconds
 t1 = (0:dt:.25);
 t2 = (.25:dt:.50);
 t3 = (.5:dt:.75);
 t4 = (.75:dt:1);

 %get a full-length example of each signal component
 x1 = (10)*sin(2*pi*100*t);
 x2 = (10)*sin(2*pi*200*t);
 x3 = (10)*sin(2*pi*300*t);
 x4 = (10)*sin(2*pi*400*t);

  %construct a composite signal
  x = zeros(size(t));
  I = find((t >= t1(1)) & (t <= t1(end)));
  x(I) = x1(I);
  I = find((t >= t2(1)) & (t <= t2(end)));
  x(I) = x2(I);
  I = find((t >= t3(1)) & (t <= t3(end)));
  x(I) = x3(I);
  I = find((t >= t4(1)) & (t <= t4(end)));
  x(I) = x4(I);

  NFFT = 2 ^ nextpow2(length(t));     % Next power of 2 from length of y
   Y    = fft(x, NFFT);
   f    = Fs / 2 * linspace(0, 1, NFFT/2 + 1);
   figure;
   plot(f(1:200), 2 * abs( Y( 1:200) ) );

   T = 0:.001:1;
   spectrogram(x,10,9);
   ylabel('Frequency');
    axis(get(gcf,'children'), [0, 1, 1, 100]);

result of the posted code: Spectrogram_Image_1: enter image description here

what i am trying to get: Image_2: enter image description here

Update_1, image Code:

%now call the spectrogram
spectrogram(x, window, noverlap, Nfft, Fs);
ylabel('Frequency');
axis(get(gcf,'children'), [0, 1]);

enter image description here

rmaik
  • 1,076
  • 3
  • 15
  • 48

1 Answers1

1

First, as with the first time that you asked this question, have you plotted your data in the time-domain (ie, plot(t, x)) and zoomed in on the transitions to ensure that your signal is what you think it is? Does it have the four different periods with distinct frequencies as you intend?

Assuming that it does, I'm pretty sure that your problem is that your spectrogram call is not doing what you want. I think that you are only getting an NFFT of 10, which means that your bins are 800 Hz wide, which is insufficient for resolving your frequencies that are only 100 Hz apart.

In my opinion, you should specify more parameters so that you know what it is doing. You'd specify an Nfft that would give the frequency resolution that you need. Something with more resolution than 100 Hz (let's try 25 Hz), but not requiring so many points that it is longer than the duration where you have stable frequencies (so, less than 0.25 sec, which means less than 2000 points).

To see how to specify the length of the FFT, I looked at the documentation: http://www.mathworks.com/help/signal/ref/spectrogram.html

Based on the docs I'd try the five parameter version: spectrogram(x,window,noverlap,nfft,fs)

For you code, where Fs and x are as you have already defined them, the spectrogram call would look like:

%define FFT parameters
des_df_Hz = 25;  %desired frequency resolution for the display, Hz
Nfft = round(FS / des_df_Hz);  %general rule for FFT resolution
Nfft = 2*Nfft;  %double the bins to account for spreading due to windowing
Nfft = 2*round(0.5*Nfft);  %make Nfft an even number
window = Nfft;  %make your window the same length as your FFT
noverlap = round(0.95);  %overlap a lot to make the plot pretty

%now call the spectrogram
spectrogram(x, window, noverlap, Nfft, Fs,'yaxis');
chipaudette
  • 1,655
  • 10
  • 13
  • than you for the answer, it seems correct, but the axes nedd to be adjusted. would you please tell me how to correctly adjust the axes? i want the horizonatla axes is the time and the vertical axes is the frequency, bith with appropriate sampling "pins". please see the update_1 section posted above – rmaik Jan 04 '15 at 10:30
  • In the Matlab spectrogram documentation (http://www.mathworks.com/help/signal/ref/spectrogram.html), its example shows the frequency on the vertical axis as you desire. It says to add the arguement `'yaxis'` to the function call. I have edited my code above. I've also increased the overlap to make the spectrogram look smoother. – chipaudette Jan 04 '15 at 13:24
  • Also, you'll want to remove your `axis` command, which will truncate the y-axis (soon to be the "frequency" axis) to range only from zero to on Hertz. That is too now. Once you make the edit to the `spectrogram` call, you'll want to replace your `axis` command with something simpler like `ylim([0 1000]);`. – chipaudette Jan 04 '15 at 13:28
  • thank you, i will inform correctness of the answer once i try it +1 – rmaik Jan 07 '15 at 10:24