1.概述
时域信号经FFT变换后得到了频谱,在作图时还必须设置正确的频率刻度,这样才能从图中得到正确的结果。
2.案例分析
下面透过一个简单的例子来分析频谱图中频率刻度(横坐标)的设置的重要性。一余弦信号,信号频率为30Hz,采样频率100Hz,信号长128,在FFT后做谱图,代码如下:
clear; clc; close all;
fs=128; % 采样频率
N=128; % 信号长度
t=(0:N-1)/fs; % 时间序列
y=cos(2*pi*30*t); % 余弦信号
Y=fft(y,N); % FFT
f=linspace(0,64,64);
plot(f,abs(Y(1:64)),'k');
% xlim([25 35]);
xlabel('频率(Hz)'); ylabel('幅值');
谱分析后,最大值谱线应该在30Hz处。从图中看到得到的最大值谱线在30Hz与31Hz之间为30.47Hz,这表明信号不是30Hz的正弦信号,其频率在30Hz与31Hz之间,这明显不符合初始设置。发生这种错误的原因是频率刻度的设置错误。
3.解决方法
当N为偶数和N为奇数时频率刻度的设置方法稍有不同。这里讨论N为偶数和奇数的情况。
clear all; clc; close all;
fs=128; % 采样频率
N=128; % 信号长度
t=(0:N-1)/fs; % 时间序列
y=cos(2*pi*30*t); % 余弦信号
y=fft(y,N); % FFT
freq=(0:N/2)*fs/N; % 按式(2-2-6c)设置正频率刻度
% 作图
plot(freq,abs(y(1:N/2+1)),'k')
xlabel('频率(Hz)'); ylabel('幅值');
title('频谱图')
set(gcf,'color','w');
运行程序后,图中频率刻度符合式(2-2-6),只用了正频率来表示。本例中用的信号与案例分析中用的信号是相同的,但从图2-2-3中可看到,最大值的谱线在30Hz处,与信号设置频率一致。但是此时的频率对了但是其幅值无法体现信号的真实幅值因此需要进一步的处理。
关键部分代码如下:
function Hutu_FFT(data, fs)
N=length(data);
fft_data=fft(data);
if mod(N, 2) == 1
freq=(0:N/2)*fs/N;
magY=abs(fft_data(1:N/2+1))*2/N;
plot(freq,magY,'k');
else
freq=(0:(N-1)/2)*fs/N;
magY=abs(fft_data(1:(N-1)/2+1))*2/N;
plot(freq,magY,'k');
end
set(gca,'FontWeight','normal','LineWidth',0.8, ...
'XMinorTick','off','XGrid','on','YGrid','on','YMinorTick','off','GridLineStyle', '--',...
'FontSize',10,'FontAngle','normal' ,'FontSmoothing','on')
title('\fontname{宋体}频谱图') %标题
xlabel('\fontname{宋体}频率/\fontname{Times new roman}\it{Hz}'); %x轴标签
ylabel('\fontname{宋体}幅值/\fontname{Times new roman}\it{mm}'); %y轴标签
end
本人编写画频谱图函数的使用说明
clear; clc; close all;
fs=128; % 采样频率
N=128; % 信号长度
t=(0:N-1)/fs; % 时间序列
y=cos(2*pi*30*t); % 余弦信号
Y=fft(y,N); % FFT
f=linspace(0,64,64);
figure;Hutu_FFT(y, fs)
使用本人编写的频谱图函数的效果图,可看出可以较好得到信号所在的频率和幅值相关信息
获取代码请关注MATLAB科研小白的个人公众号(即文章下方二维码),并回复频谱图的绘制本公众号致力于解决找代码难,写代码怵。各位有什么急需的代码,欢迎后台留言~不定时更新科研技巧类推文,可以一起探讨科研,写作,文献,代码等诸多学术问题,我们一起进步。