How can I plot a spectrogram plotting time vs instantaneous frequency vs amplitude from an exported output signal?

I have a text file with time(1st column) and voltage amplitude (2nd column). How do I plot a spectrogram plotting time vs instantaneous frequency vs amplitude? Could you please help me plot it? I will really appreciate it.
I have attached the text file and a picture of the time domain representation of the signal.

5 Comments

Hi Syed,
You asked the question in your post, “How do I plot a spectrogram plotting time vs instantaneous frequency vs amplitude?”
It’s pretty simple, load the data from the text file into the variable data. Extract your time and voltage amplitude from the data loaded. Then, calculate the instantaneous frequency using the Hilbert transform to get the analytic signal and then unwrapping the phase. Afterwards, use the spectrogram function to generate a spectrogram plot. Hopefully, following these steps, you should be able to figure out to plot it based on your preferences.
For more information on spectrogram function and examples, please refer to https://www.mathworks.com/help/signal/ref/spectrogram.html https://www.mathworks.com/help/signal/examples.html?category=transforms&s_tid=CRUX_topnav
% Load data from the text file
data = load('Oscillatory.txt'); % Assuming the text file has two columns: time and amplitude
% Extract time and amplitude
time = data(:, 1);
amplitude = data(:, 2);
% Convert time to nanoseconds
time_ns = time * 1e9;
% Compute the analytic signal using the Hilbert transform
analytic_signal = hilbert(amplitude);
% Compute the instantaneous phase
inst_phase = unwrap(angle(analytic_signal));
% Compute the instantaneous frequency in Hz
inst_freq = diff(inst_phase) ./ diff(time);
% Convert instantaneous frequency to GHz
inst_freq_GHz = inst_freq * 1e-9;
time_inst_freq_ns = time_ns(1:end-1); % time vector for instantaneous frequency in ns
% Sampling frequency
fs = 1 / (time(2) - time(1)); % in Hz
% Generate the spectrogram plot
figure;
% Plot amplitude vs time (ns)
subplot(3, 1, 1);
plot(time_ns, amplitude);
title('Amplitude vs Time');
xlabel('Time (ns)');
ylabel('Amplitude');
xlim([0 max(time_ns)]);
% Plot instantaneous frequency vs time (ns)
subplot(3, 1, 2);
plot(time_inst_freq_ns, inst_freq_GHz);
title('Instantaneous Frequency vs Time');
xlabel('Time (ns)');
ylabel('Frequency (GHz)');
xlim([0 max(time_inst_freq_ns)]);
% Generate the spectrogram
subplot(3, 1, 3);
spectrogram(amplitude, 256, 250, 256, fs, 'yaxis'); % Adjust parameters as needed
title('Spectrogram');
xlabel('Time (ns)');
ylabel('Frequency (GHz)');
% Adjust the color scale for better visualization
colormap jet;
colorbar;
xlim([0 max(time_ns)]);
I am getting negative frequuency in the instantaneous frequency plot. Why is that and how to fix that? Also, I am not gettiing an accurate spectrogram and I am not sure what the color is representing, supposed to be amplitude. Could you please help me fix it? Thanks.

Hi Syed,

You asked, “ I am getting negative frequuency in the instantaneous frequency plot. Why is that and how to fix that? Also, I am not gettiing an accurate spectrogram and I am not sure what the color is representing, supposed to be amplitude. Could you please help me fix it?”

I made modifications to your code, please see updated code along with your questions answered.

% Load data from the text file using textscan

fileID = fopen('Oscillatory.txt', 'r');

data = textscan(fileID, '%f %f', 'HeaderLines', 1); % Assuming the first line is a header

fclose(fileID);

% Access the loaded data

time = data{1};

amplitude = data{2};

% Calculate instantaneous frequency

instantaneous_frequency = diff(unwrap(angle(hilbert(amplitude))) / (2 * pi)) / (time(2) - time(1));

% Plot amplitude vs time

subplot(3, 1, 1);

plot(time, amplitude);

xlabel('Time (ns)');

ylabel('Amplitude');

title('Amplitude vs Time');

% Plot instantaneous frequency vs time

subplot(3, 1, 2);

plot(time(2:end), instantaneous_frequency);

xlabel('Time (ns)');

ylabel('Instantaneous Frequency');

title('Instantaneous Frequency vs Time');

% Plot spectrogram

subplot(3, 1, 3);

spectrogram(amplitude, 128, 120, 128, 1/(time(2)-time(1)), 'yaxis');

title('Spectrogram: Time vs Instantaneous Frequency vs Amplitude');

% Adjust subplot spacing

sgtitle('Plots of Amplitude vs Time, Instantaneous Frequency vs Time, and Spectrogram');

Please see attached snippet code along with plot.

To begin with, the above code snippet loads data from your attached text file named 'data.txt' into two arrays: time and amplitude. The time array stores the time values, while the amplitude array stores the corresponding amplitude values.Next, the code calculates the instantaneous frequency using the Hilbert transform. The hilbert function computes the analytic signal of the amplitude array, and unwrap and angle functions extract the phase information. By taking the difference of the unwrapped phase divided by 2π and the time difference, the instantaneous frequency is obtained.After the calculations, the code proceeds to plot the data in three subplots. The first subplot displays the amplitude vs. time, the second subplot shows the instantaneous frequency vs. time, and the third subplot visualizes the spectrogram.In the amplitude vs. time plot, the x-axis represents time in nanoseconds, and the y-axis represents the amplitude. This plot provides insights into how the amplitude changes over time.The instantaneous frequency vs. time plot illustrates how the frequency changes over time. The x-axis represents time in nanoseconds, while the y-axis represents the instantaneous frequency. This plot helps in understanding the frequency dynamics of the signal.Lastly, the spectrogram plot visualizes the time-frequency content of the signal. It uses a spectrogram function with specific parameters to generate a spectrogram plot with time on the x-axis, instantaneous frequency on the y-axis, and amplitude represented by color intensity. Feel free to customize the code snippet based on your preferences. Please let me know if you have any further questions.

Hello Umar,
Thank you so much for your help!
Could you please tell me how to determine the value of the parameters of spectrogram function? Also, does the spectrogram function transform the amplitude to power/frequency? Is there a way to plot just the amplitude?
Also, could you please tell me why we are getting negative instantaneous frequency and how to fix that? Thanks.
Hi Syed,
No problem, glad to help you out. Please see my response to your posted questions.
Question: Could you please tell me how to determine the value of the parameters of spectrogram function? Also, does the spectrogram function transform the amplitude to power/frequency?
To answer this question, you have to understand how this function works, please refer to
https://www.mathworks.com/help/signal/ref/spectrogram.html
Now to address your query about, “does the spectrogram function transform the amplitude to power/frequency? “
Please bear in mind that this function computes the power spectral density (PSD) of the signal. This means that the amplitude values are transformed into power values, representing the distribution of power across different frequencies over time.
Question: Is there a way to plot just the amplitude?
If you wish to plot just the amplitude values without converting them to power, you can modify the spectrogram calculation slightly. Instead of using the spectrogram function directly, you can compute the Short-Time Fourier Transform (STFT) manually and plot the magnitude of the resulting spectrogram. For more information on STFT, please refer to
https://www.mathworks.com/help/signal/ref/spectrogram.html#mw_c6dfa97d-9a98-4238-a6bd-d58825fb47e0
Question: could you please tell me why we are getting negative instantaneous frequency and how to fix that?
So, I did some experimentation with code to find solution by using unwrapping of the phase and then realized how to overcome this issue. I had to adjust the calculation of instantaneous frequency to ensure that only positive values are obtained. The negative values in the plot were likely due to the unwrapping of the phase and subsequent calculation of the instantaneous frequency. Here is the snippet code to help this issue.
% Calculate instantaneous phase
instantaneous_phase = unwrap(angle(hilbert(amplitude)));
% Adjust phase to prevent negative frequencies
positive_phase = mod(instantaneous_phase, 2*pi);
% Calculate corrected instantaneous frequency
instantaneous_frequency = diff(positive_phase) / (2 * pi) / (time(2) - time(1));
% Ensure positive values for instantaneous frequency
instantaneous_frequency(instantaneous_frequency < 0) = 0;
I hope all your questions are answered.

Sign in to comment.

Answers (0)

Asked:

on 21 Jul 2024

Edited:

on 22 Jul 2024

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!