Plotting 2D Hilbert Spectrum in MATLAB - matlab

I want to create a 2d plot of hilbert spectrum. What i want is a time vs frequency plot, where the amplitude of the signal is represented by color changes in the plot.
What i have done is this, but I need it to look like this.
Thank you in advance
EDIT:
I have the values of amplitude and instantaneous frequency over time, that i have produced using Hilbert Huang Transform.
Let's say we only use the first IMF, and we have 100 samples. Then what we have is:
instantaneous_frequency = [f1 f2 f3 ... f100]
instantaneous_amplitude = [a1 a2 a3 ... a100]
time = [t1 t2 t3 ... t100]
What i need is a way to plot them like the second image, without using the spectrogram function, since it uses STFT and I have already applied HHT.
The code for producing the first plot is:
Time_Window = 1:101;
signal= rand(1,101);
hilb = hilbert(signal);
inst_amp = abs(hilb);
inst_th = angle(hilb);
inst_freq = diff(a_inst_th)/(1/256)/(2*pi); %instantaneous frequency
%inst_freq = remove_outliers(inst_freq,Time_Window(1:end-1));
inst_freq(end+1) = inst_freq(end); % This is done due to diff()
plot(Time_Window*4,inst_freq,'k.','MarkerSize',5)

There is already a MATLAB function to produce a spectrogram, which looks a lot like what you want. See if that solves your problem.

Related

Fourier transform of normal density function

I am using the following MATLAB code to perform a Fourier transformation of a normal density function:
N=100;
j=0:(N-1);
a=-5;
b=5;
dx = (b-a)/N;
x = a+j*dx;
dt = 2*pi/(N*dx);
f1 = -N/2*dt;
f2 = N/2*dt;
t= f1+ j*dt;
GX = normpdf(x,0,1);
fft_GX = real(fft(GX))';
However, I do not get the expected bell shaped curve when I try to plot fft_GX.
The Fourier transformation of a normal density has the form of e^(-t^2/2). Can someone please help as to what I am doing incorrect?
Trying using abs instead of real.
Another helpful function to recenter the frequency domain is fftshift. Otherwise you will see the plot from 0 to 2*pi I believe, instead of the more recognizable view from -pi to pi.
fft_GX = abs(fftshift((fft(GX))');
plot(fft_GX);
You may need to do some further normalization based on the number of samples you have, but it looks more like the expected bell curve than what you were seeing originally.

Shifting in FFT

Input image
Listing-1
i = imread('Untitled.png');
i = rgb2gray(i);
F = fft2(i);
%%%F = fftshift(F);
F = abs(F);
F = log(F+1);
F = mat2gray(F);
imshow(F);
Output
.
Listing-2
i = imread('Untitled.png');
i = rgb2gray(i);
F = fft2(i);
F = fftshift(F);
F = abs(F);
F = log(F+1);
F = mat2gray(F);
imshow(F);
Output
Seeing the the above two outputs, can you answer the following questions,
Why does the FFT of an image produce such an spectrum where zero frequencies are at the corner of the image?
Why is that a problem (or, is that)?
Why does the shifting operation fixes that phenomenon?
Here are some answers:
Why does the FFT of an image produce such an spectrum where zero
frequencies are at the corner of the image?
The fft is a fast implementation of the Discrete Fourier Transform (DFT). In 1-D, the DFT is defined as X[m] = \sum_n x[n] exp(j 2 pi (m-1)(n-1)/N). Therefore, clearly, the first element of the transform corresponds to the frequency zero. This is similar in 2-D, where the first row/column carries the zero frequency.
Why is that a problem (or, is that)?
It isn't, not at all. It works as intended. It is maybe only a "problem" that we are more used to seeing the zero frequency in the middle since spectrum has some symmetries so we like to look at it in [-Nyquist,Nyquist] instead of [0,2*Nyquist]. Though technically this is no different since it is anyways periodic.
Why does the shifting operation fixes that phenomenon?
Since shifting the zero frequency to the middle produces images that are somewhat visually more pleasing, a function to do this job has been made available. It is only intended to be used for display. The documentation of fftshift shows in detail how it works, also in 2-D.

Filtering signal noise using Fourier Transforms and MATLAB

So, I've been given three different MATLAB (I'm using MATLAB R2014b) files with signals containing noise. I simply just plotted the values I was given for the first part. For example, the plot of the first signal looks like the one below.
Then, I did the Fourier Transform of the signal and plotted those values as well to determine where the noise and signal occur in the frequency spectrum. To show this, I added the plot image of the first signal below.
Finally, I am supposed to create a filter using the basic MATLAB commands and filter the noise out of the plot of the signal and then do the Fourier Transform of the signal again and plot the results. The filter portion will look something like this...
b = fir1(n,w,'type');
freqz(b,1,512);
in = filter(b,1,in);
Where n is the order of the filter, w is the cutoff frequency (cutoff frequency divided by half the sampling rate), and 'type' is something to the effect of low/high/stop/etc... So, my question is how do I figure out what the n, w, and type values of the filter I am creating are supposed to be?! Thanks in advance for any help!
I believe your high frequency components are noise, but it actually depends on your data.
See this example,
Fs = 2000;
L = 200;
t = (0 : L - 1)/Fs;
data = chirp(t,20,.05,50) + chirp(t,500,.1,700);
subplot(411)
plot(t,data,'LineWidth',2);
title('Original Data')
N = 2^nextpow2(L);
y = fft(data,N)/L;
f = Fs/2 * linspace(0,1,N/2+1);
subplot(412)
plot(f,abs(y(1:N/2+1)))
title('Spectrum of Original Data')
b = fir1(40,2*[1 200]/Fs);
newd = filter(b,1,data);
subplot(413)
plot(t,newd)
title('Filtered Data')
newy = fft(newd,N)/L;
subplot(414)
plot(f,abs(newy(1:N/2+1)))
title('Spectrum of Filtered Data')
You can use b = fir1(40,2*[200 800]/Fs); for high-pass filter.
If the second plot is correct, in the x-axis, I can assume:
A. The sampling frequency is 2000 Hz.
B. The "noise" is in the low frequencies. It seems also from the original signal, that you need to filter the low-frequency baseline.
If so, you need highpass filter, so 'type'='high'.
The order is depend in the sharpness that you want to the filter. from the plots it seems that you can use 'n'=12 or 20.
The cutoff frequency suppose to be about 0.1 if the peak in the low frequencies is indeed the noise that you want to filter, and if the 1000Hz x-axis is indeed the Nyquist frequency.

How to programatically find the magnitude and frequency for a given phase in a bode plot?

If I have a Plant let's say
Gp(s) = 1/(s+1)
I can find the Phase Margin
Using MATLAB commands
Gp = tf([1],[1 1]);
[G P] = margin(Gp);
My question is what if I want to know the phase over frequency in a specific Gain Over Frequency. How do I find it without looking to bode plot?
Usually I find it by the command bode(Gp) and move the mouse over the specific gain that I want to know the phase margin on it.
For my previous example The Gain Over Frequency is 0.363 at -20 Phase Over Frequency.
How do I write it as a command not looking in the bode diagram?
Thanks in advance
It seems you misunderstood what Gain Over Frequency and phase margin actually means, and it is not the place to explain it. What I assume you actually want, is a way to evaluate a bode-plot without clicking at it. E.g. you want to know magnitude and frequency at the point of -20 phase.
Let's have a look at these three cases:
Case 1: you know the frequency and you're searching for magnitude and phase
The easiest case:
w = 0.363; % specify given frequency
[mag,phase] = bode(Gp,w) % output of according magnitude and phase
returns:
mag =
0.9400
phase =
-19.9509
Case 2: you want to know magnitude and frequency for a certain phase
p = -20;
[mag,phase,wout] = bode(Gp);
mag_p = interp1( squeeze(phase), squeeze(mag), p)
w_p = interp1( squeeze(phase), wout, p)
returns:
mag_p =
0.9394
w_p =
0.3642
Case 3: you want to know phase and frequency for a certain magnitude
m = 0.9394;
[mag,phase,wout] = bode(Gp);
phase_m = interp1( squeeze(mag), squeeze(phase), m)
w_m = interp1( squeeze(mag), wout, m)
returns:
phase_m =
-19.9998
w_m =
0.3642
The squeeze command is necessary, because bode output a 1x1x... matrix for phase and magnitude, however. You also may use different interpolation methods of interp1.

Triangular wave graphed instead of Sin wave in matlab

I am designing composite sin wave such as
input=sin(2*pi*Fm_1*t) + sin(2*pi*Fm_2*t);
where Fm_1, and Fm_2 are given by the user and
t=0:Ts:2*Tm;
where
Ts=1/Fs;
Tm=1/(maxof(Fm_1,Fm_2) (NOT A FUNCTION, just to explain)
and Fm_1 = 5and Fm_2 = 10 and Fs = 30
and plot using plot(t,input);
Now for some reason, the output is correct but instead of being a sine wave, it's a triangular wave (straight lines). Other than that, the output is correct.
EDIT:
I just found out that because I plotted two graphs on the same scale, an error in the second graph screwed up the first.
Now the problem is filtering the input using this :
output = filtfilt(B,A,input);
Why does this give me nothing when I plot it (I also tried using filter)?
As mentioned in the comments above, the problem is that you're using a way too low sampling frequency to plot a detailed graph. You can see this using the function below:
function myplot(Fm_1, Fm_2, Fs)
Ts = 1/Fs;
Tm = 1/max(Fm_1,Fm_2);
t = 0:Ts:2*Tm;
input = sin(2*pi*Fm_1*t) + sin(2*pi*Fm_2*t);
plot(t, input);
end
As you noticed, for Fs = 30 you get a plot like this:
Increasing to Fs = 100, the situation improves:
And for Fs = 1000 the plot is what you'd probably expect in the first place:
Note that for all the above I've used the values Fm_1 = 5 and Fm_2 = 10 that you provided.