spectrogram x-axis match with data

조회 수: 2 (최근 30일)
Jorge Luis
Jorge Luis 2025년 1월 22일
댓글: Mathieu NOE 2025년 1월 24일
Hello, I am plotting a spectrogram from an earthquake signal, but the time length of the signal (~250 seconds) does not match the time length displayed in the spectrogram (~100 seconds). Could you help me understand why this discrepancy occurs and how to fix it? Thank you!
  댓글 수: 2
Mathieu NOE
Mathieu NOE 2025년 1월 22일
that is quite strange , but I cannot tell the reason as you don't show the code
to be sure to have same x axis display you can use xlim (with same values) on both subplots
Jorge Luis
Jorge Luis 2025년 1월 22일
Thank you. I describe the code here:
load fildat.mat % loading signal
Tp=10.1938; % Pwave arrival
Ts=18.5094; % Swave arrival
T_end_coda=165.55; % end Coda wave
component=’NS’;
% Parameters for the spectrogram
windowLength = 100; %Length of each segment (adjust as needed)
overlap = 80; %Overlap between segments (adjust as needed)
nfft = 100; %Number of FFT points
% fildat: is the signal
fs=200; % sample frequency
time = (0:length(fildat)-1) / fs; % Time vector in seconds
[thresh_spec,Traf, traf] = spectrogram(abs(fildat),windowLength,overlap,nfft,fs,'yaxis');
thresh_spec1 = abs(thresh_spec); % Magnitude of the spectrogram
% Convert power to decibels
P_dB = 10*log10(thresh_spec1);
fil=[0.20 0.35 0.58];
a1=[0.10 0.38 0.93];
a2=[0.91 0.1 0.1];
a3=[0.17 0.61 0.10];
a4=[0.97 0.38 0.93];
a5=[0.99 0.73 0.43];
fsz=17;
color_text=[0.09 0.27 0.68];
lg_loca='northeast';
lg_size=9;
line_width=3;
fh=figure;
% Create a tiled layout
tiledlayout(2, 1, 'TileSpacing', 'compact', 'Padding', 'compact');
% First subplot (row 1, column 1)
nexttile;
plot(time,fildat,'Color',fil,'LineWidth',1,'DisplayName',join([string(component),' - Acc Time Series'])); % Earthquake waveform
xlabel('Time (s)');
ylabel('Acc (m/s^2)');
title({name1},{[component,' - Acceleration Time Series']},'FontSize',fsz+2,'color',color_text,'FontWeight', 'bold');
xlim([0, max(time)]);
grid on;
% Mark important time points (adjust these values to match your data)
hold on;
xline(time(1), '--','LineWidth',line_width,'Color',a1,'DisplayName', 'T_{initial}'); % Initial time
xline(Tp, '--','LineWidth',line_width,'Color',a2,'DisplayName', 'T_{P-arrival}'); % Hypothetical P-wave arrival
xline(Ts, '--','LineWidth',line_width,'Color',a3,'DisplayName', 'T_{S-arrival}'); % Hypothetical S-wave arrival
xline(T_end_coda, '--','LineWidth',line_width,'Color',a4,'DisplayName', 'T_{coda-end}'); % End of coda
xline(time(end), '--','LineWidth',line_width,'Color',a5,'DisplayName', 'T_{end}'); % End of the signal 'Z_{TOR}=50km
legend('Location',lg_loca,'color',[0.97 0.96 0.96],'TextColor', [0 0.35 0.74],'EdgeColor',[0 0.35 0.74],'FontSize',lg_size,'LineWidth',1, 'NumColumns', 1)
grid on
set(gca, 'FontName', 'Times New Roman', 'FontSize', fsz-3, 'FontWeight', 'bold', ...
'XColor', color_text, 'YColor', color_text, 'XTickLabelRotation', 0, ...
'LineWidth', 0.25, 'GridColor', [0.5, 0.5, 0.5], 'GridAlpha', 0.5);
% Plot the spectrogram
nexttile; % Bottom plot for spectrogram
imagesc(Traf, traf, P_dB); % Display spectrogram
axis xy; % Flip Y-axis
xlabel('Time (s)');
ylabel('Frequency (Hz)');
title({name2},{[component,' - Spectrogram']},'FontSize',fsz+2,'color',color_text,'FontWeight', 'bold');
colormap(jet); % Set colormap
colorbar; % Display color scale
set(gca, 'FontName', 'Times New Roman', 'FontSize', fsz-3, 'FontWeight', 'bold', ...
'XColor', color_text, 'YColor', color_text, 'XTickLabelRotation', 0, ...
'LineWidth', 0.25, 'GridColor', [0.5, 0.5, 0.5], 'GridAlpha', 0.5);
%clim([100, -100]); % Adjust dynamic range for better visualization
% Match x-axis of the spectrogram to the waveform time axis
%xlim([0, max(time)]); % Set x-axis limits to match the time vector
fh.WindowState = 'maximized';

댓글을 달려면 로그인하십시오.

채택된 답변

Mathieu NOE
Mathieu NOE 2025년 1월 24일
hello again
so the problem was simply that you inverted time and frequency vectors when calling imagesc !
I guess the mistake is due to the fact that when computing the spectrogram data, you named the frequency vector Traf and the time vector traf , so that can be misleading.
I opted to change Traf into Fraf which sounds more like a frequency vector and not a time vector.
other minor modifications :
you can remove this line : axis xy; % Flip Y-axis as a few lines latter you are doing :
set(gca, 'FontName', 'Times New Roman', 'FontSize', fsz-3, 'FontWeight', 'bold', ..
so simply add : ,'Ydir','normal', and you're done with y axis flip
now I think your code is working fine
name1 = 'Test'; % just for the demo here
name2 = 'Test'; % just for the demo here
load fildat.mat % loading signal
Tp=10.1938; % Pwave arrival
Ts=18.5094; % Swave arrival
T_end_coda=165.55; % end Coda wave
component='NS';
% Parameters for the spectrogram
windowLength = 100; %Length of each segment (adjust as needed)
overlap = 80; %Overlap between segments (adjust as needed)
nfft = 100; %Number of FFT points
% fildat: is the signal
fs=200; % sample frequency
time = (0:length(fildat)-1) / fs; % Time vector in seconds
[thresh_spec,Fraf, traf] = spectrogram(abs(fildat),windowLength,overlap,nfft,fs,'yaxis');
% [S,F,T] = SPECTROGRAM(...) returns a vector of frequencies, F, and a
% vector of times, T, at which the spectrogram is computed
thresh_spec1 = abs(thresh_spec); % Magnitude of the spectrogram
% Convert power to decibels
P_dB = 10*log10(thresh_spec1);
fil=[0.20 0.35 0.58];
a1=[0.10 0.38 0.93];
a2=[0.91 0.1 0.1];
a3=[0.17 0.61 0.10];
a4=[0.97 0.38 0.93];
a5=[0.99 0.73 0.43];
fsz=17;
color_text=[0.09 0.27 0.68];
lg_loca='northeast';
lg_size=9;
line_width=3;
fh=figure;
% Create a tiled layout
tiledlayout(2, 1, 'TileSpacing', 'compact', 'Padding', 'compact');
% First subplot (row 1, column 1)
nexttile;
plot(time,fildat,'Color',fil,'LineWidth',1,'DisplayName',join([string(component),' - Acc Time Series'])); % Earthquake waveform
xlabel('Time (s)');
ylabel('Acc (m/s^2)');
title({name1},{[component,' - Acceleration Time Series']},'FontSize',fsz+2,'color',color_text,'FontWeight', 'bold');
xlim([0, max(time)]);
grid on;
% Mark important time points (adjust these values to match your data)
hold on;
xline(time(1), '--','LineWidth',line_width,'Color',a1,'DisplayName', 'T_{initial}'); % Initial time
xline(Tp, '--','LineWidth',line_width,'Color',a2,'DisplayName', 'T_{P-arrival}'); % Hypothetical P-wave arrival
xline(Ts, '--','LineWidth',line_width,'Color',a3,'DisplayName', 'T_{S-arrival}'); % Hypothetical S-wave arrival
xline(T_end_coda, '--','LineWidth',line_width,'Color',a4,'DisplayName', 'T_{coda-end}'); % End of coda
xline(time(end), '--','LineWidth',line_width,'Color',a5,'DisplayName', 'T_{end}'); % End of the signal 'Z_{TOR}=50km
legend('Location',lg_loca,'color',[0.97 0.96 0.96],'TextColor', [0 0.35 0.74],'EdgeColor',[0 0.35 0.74],'FontSize',lg_size,'LineWidth',1, 'NumColumns', 1)
grid on
set(gca, 'FontName', 'Times New Roman', 'FontSize', fsz-3, 'FontWeight', 'bold', ...
'XColor', color_text, 'YColor', color_text, 'XTickLabelRotation', 0, ...
'LineWidth', 0.25, 'GridColor', [0.5, 0.5, 0.5], 'GridAlpha', 0.5);
% Plot the spectrogram
nexttile; % Bottom plot for spectrogram
imagesc(traf, Fraf, P_dB); % Display spectrogram
xlabel('Time (s)');
ylabel('Frequency (Hz)');
title({name2},{[component,' - Spectrogram']},'FontSize',fsz+2,'color',color_text,'FontWeight', 'bold');
colormap(jet); % Set colormap
colorbar; % Display color scale
set(gca,'Ydir','normal', 'FontName', 'Times New Roman', 'FontSize', fsz-3, 'FontWeight', 'bold', ...
'XColor', color_text, 'YColor', color_text, 'XTickLabelRotation', 0, ...
'LineWidth', 0.25, 'GridColor', [0.5, 0.5, 0.5], 'GridAlpha', 0.5);
%clim([100, -100]); % Adjust dynamic range for better visualization
% Match x-axis of the spectrogram to the waveform time axis
xlim([0, max(time)]); % Set x-axis limits to match the time vector
fh.WindowState = 'maximized';
  댓글 수: 2
Jorge Luis
Jorge Luis 2025년 1월 24일
Thank you very much.
Mathieu NOE
Mathieu NOE 2025년 1월 24일
as always, my pleasure !

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Mathieu NOE
Mathieu NOE 2025년 1월 22일
this can also helps you :
%%Method 1: equate axis sizes for all axes after adding colorbar
% Size of axes without a colorbar will be set to the size of axes with a colorbar.
% Create Demo
ax = gobjects(2,3);
for i = 1:5
ax(i) = subplot(3,2,i);
imagesc(ax(i),rand(100,1000))
colorbar(ax(i))
end
ax(end) = subplot(3,2,6);
plot(ax(end), 1:1000,(1:1000).*rand(1,1000)*2)
% Set the width and height of all axes to the min width & height
allAxPos = vertcat(ax.Position);
allAxPos(:,3:4) = min(allAxPos(:,3:4)).*ones(numel(ax),1);
set(ax,{'position'},mat2cell(allAxPos,ones(numel(ax),1),4))
%%Method 2: Restore axis position and set colobar positions
% The axes maintain their original sizes prior to adding colorbar.
% The colorbar position and width is adjusted.
function addOutsideColorbar(ax)
pos = ax.Position;
cb = colorbar(ax,'EastOutside');
ax.Position = pos;
cb.Position(1) = sum(ax.Position([1,3]))+.01;
cb.Position(3) = cb.Position(3).*.5;
end
ax = gobjects(2,3);
for i = 1:5
ax(i) = subplot(3,2,i);
imagesc(ax(i),rand(100,1000))
addOutsideColorbar(ax(i))
end
ax(end) = subplot(3,2,6);
plot(ax(end), 1:1000,(1:1000).*rand(1,1000)*2)
%%Method 3: Use tiledlayout
ax = gobjects(2,3);
tlo = tiledlayout(3,2);
for i = 1:5
ax(i) = nexttile(tlo);
imagesc(ax(i),rand(100,1000))
colorbar(ax(i))
end
ax(end) = nexttile(tlo);
plot(ax(end), 1:1000,(1:1000).*rand(1,1000)*2)

카테고리

Help CenterFile Exchange에서 AI for Signals에 대해 자세히 알아보기

제품


릴리스

R2023b

Community Treasure Hunt

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

Start Hunting!

Translated by