Matlab:将频谱图保存在变量中并显示
Matlab : save a spectrogram in a variable and display it
我想要的很简单,或者我是这么想的。我有很多频谱图要计算和显示,计算起来很耗时,所以我想将它们保存在变量中以在不重做计算的情况下显示它们。问题是,如果我直接使用函数 spectogram(),我找不到像它们出现时那样绘制它们的方法。
示例:
sampling_rate = 100;
spectrogram(data,100,20,[],sampling_rate,'yaxis');
caxis([-20 60])
这显示了我想要的频谱图:
我阅读了文档,我知道我可以通过执行以下操作来保存结果:
[S,F,T] = spectrogram(data,100,20,[],sampling_rate);
另外,我知道函数spectogram内部调用了surf()。
我发现 this post 这样做似乎可以解决我的问题 :
[S,F,T] = spectrogram(data,100,20,[],sampling_rate);
surf(T,F,abs(S),'EdgeColor','none');
axis tight; view(0,90);
但是我得到了这个情节,这与我的预期相去甚远:
轴标签和颜色条消失了,颜色完全没有缩放。如果我像以前一样通过添加 colorbar; caxis([-20 60]);
手动执行此操作,我会得到这个东西:
没有一个简单的解决方案来保存频谱图并在命令中显示它吗?
喜欢 S = spectogram(...)
然后 plot(S)
?
我找到了解决方案的开始。
如果我写:
[S,F,T,P] = spectrogram(data(1:3000),100,20,[],sampling_rate);
P把谱功率密度保存在一个矩阵中,画起来挺方便的不用忘记加上10*log10(P):
h = pcolor(10*log10(P));
colorbar;
caxis([-20 60]);
set(h,'EdgeColor','none')
我得到这个好多了:
但我仍然缺少时间和频率轴,因为它当前显示的是矩阵 P 的维数。
编辑:
我终于找到了某种手动处理轴的解决方案。时间显示仍然很糟糕,我相信有更好的方法,但我们开始吧:
[S,F,T,P] = spectrogram(data(1001:3000),100,50,[],sampling_rate);
h = pcolor(10*log10(P));
cb = colorbar;
caxis([-20 60]);
ylabel(cb, 'Power/frequency (dB/Hz')
set(h,'EdgeColor','none')
xticks(0:round(size(P,2)/6):size(P,2))
xt = xticks;
xticklabels([T(xt(2)) T(xt(2:end))]);
xlabel('Time (secs)');
yticks([0:13:size(P,1) size(P,1)])
yt = yticks;
yticklabels(0:5:50);
ylabel('Frequency (Hz)')
时间被保存在向量 T 中,这对于将其应用于 x 标签非常方便。频率存储为 F,但在我的情况下,它始终在 0-50Hz 之间,所以我手动编写了它。
我希望它能帮助一些人,如果你知道如何正确设置时间轴 自动标记(秒、分钟、小时根据持续时间自动设置), 我很想知道。
如果 或多或少按预期工作,则以下较短的代码也应执行相同的操作:
[S,F,T,P] = spectrogram(data(1:3000),100,20,[],sampling_rate);
h = imagesc(T,F,10*log10(P),[-20,60]);
xlabel('Time (secs)')
ylabel('Frequency (Hz)')
colorbar;
(我没有数据来测试它。)请注意,这里的 x 和 y 刻度是自动设置的。如果你想 select 秒、分、小时取决于 T 的比例,你可以这样做:
lab = 'Time (secs)';
if T(end) > 60*60*3
T = T/(60*60);
lab = 'Time (hours)';
elseif T(end) > 60*3
T = T/60;
lab = 'Time (mins)'
end
h = imagesc(T,F,10*log10(P),[-20,60]);
xlabel(lab)
ylabel('Frequency (Hz)')
colorbar;
我想要的很简单,或者我是这么想的。我有很多频谱图要计算和显示,计算起来很耗时,所以我想将它们保存在变量中以在不重做计算的情况下显示它们。问题是,如果我直接使用函数 spectogram(),我找不到像它们出现时那样绘制它们的方法。
示例:
sampling_rate = 100;
spectrogram(data,100,20,[],sampling_rate,'yaxis');
caxis([-20 60])
这显示了我想要的频谱图:
我阅读了文档,我知道我可以通过执行以下操作来保存结果:
[S,F,T] = spectrogram(data,100,20,[],sampling_rate);
另外,我知道函数spectogram内部调用了surf()。
我发现 this post 这样做似乎可以解决我的问题 :
[S,F,T] = spectrogram(data,100,20,[],sampling_rate);
surf(T,F,abs(S),'EdgeColor','none');
axis tight; view(0,90);
但是我得到了这个情节,这与我的预期相去甚远:
轴标签和颜色条消失了,颜色完全没有缩放。如果我像以前一样通过添加 colorbar; caxis([-20 60]);
手动执行此操作,我会得到这个东西:
没有一个简单的解决方案来保存频谱图并在命令中显示它吗?
喜欢 S = spectogram(...)
然后 plot(S)
?
我找到了解决方案的开始。
如果我写:
[S,F,T,P] = spectrogram(data(1:3000),100,20,[],sampling_rate);
P把谱功率密度保存在一个矩阵中,画起来挺方便的不用忘记加上10*log10(P):
h = pcolor(10*log10(P));
colorbar;
caxis([-20 60]);
set(h,'EdgeColor','none')
我得到这个好多了:
但我仍然缺少时间和频率轴,因为它当前显示的是矩阵 P 的维数。
编辑:
我终于找到了某种手动处理轴的解决方案。时间显示仍然很糟糕,我相信有更好的方法,但我们开始吧:
[S,F,T,P] = spectrogram(data(1001:3000),100,50,[],sampling_rate);
h = pcolor(10*log10(P));
cb = colorbar;
caxis([-20 60]);
ylabel(cb, 'Power/frequency (dB/Hz')
set(h,'EdgeColor','none')
xticks(0:round(size(P,2)/6):size(P,2))
xt = xticks;
xticklabels([T(xt(2)) T(xt(2:end))]);
xlabel('Time (secs)');
yticks([0:13:size(P,1) size(P,1)])
yt = yticks;
yticklabels(0:5:50);
ylabel('Frequency (Hz)')
时间被保存在向量 T 中,这对于将其应用于 x 标签非常方便。频率存储为 F,但在我的情况下,它始终在 0-50Hz 之间,所以我手动编写了它。
我希望它能帮助一些人,如果你知道如何正确设置时间轴 自动标记(秒、分钟、小时根据持续时间自动设置), 我很想知道。
如果
[S,F,T,P] = spectrogram(data(1:3000),100,20,[],sampling_rate);
h = imagesc(T,F,10*log10(P),[-20,60]);
xlabel('Time (secs)')
ylabel('Frequency (Hz)')
colorbar;
(我没有数据来测试它。)请注意,这里的 x 和 y 刻度是自动设置的。如果你想 select 秒、分、小时取决于 T 的比例,你可以这样做:
lab = 'Time (secs)';
if T(end) > 60*60*3
T = T/(60*60);
lab = 'Time (hours)';
elseif T(end) > 60*3
T = T/60;
lab = 'Time (mins)'
end
h = imagesc(T,F,10*log10(P),[-20,60]);
xlabel(lab)
ylabel('Frequency (Hz)')
colorbar;