使用Python绘制FFT–正弦波和余弦波的FFT

重点关注点:学习如何使用Python绘制正弦波和余弦波的FFT。了解FFT换档。使用FFT绘制单面、双面和归一化光谱。

介绍

有大量文本可用于解释离散傅里叶变换的基础知识及其非常有效的实现——快速傅里叶转换(FFT)。我们经常面临生成用于模拟目的的简单标准信号(正弦、余弦、高斯脉冲、方波、孤立矩形脉冲、指数衰减、线性调频信号)的需求。我打算(在一系列文章中)展示如何在Python中生成这些基本信号,以及如何使用FFT在频域中表示它们。如果您倾向于Matlab编程,请访问此处.

这篇文章是这本书的一部分使用Python的数字调制,ISBN:978-1712321638,提供电子书(PDF)和平装本(硬拷贝)格式

正弦波

为了产生正弦波,第一步是固定正弦波的频率f。例如,我们希望生成一个f=10赫兹最小和最大振幅为-1伏+1伏分别是。给定正弦波的频率,下一步是确定采样率。

对于基带信号,采样是直接进行的。奈奎斯特·香农抽样定理为了在离散域中忠实地再现连续信号,必须以一定的速率对信号进行采样fs(模糊)至少高于最大频率的两倍f_米包含在信号中(实际上,它是实际信号占用的单边带宽的两倍。对于基带信号带宽(0f_米)和最大频率f_米在给定频带内是等效的)。

对于Python实现,让我们编写一个函数,使用Python's Numpy库生成正弦信号。Numpy是Python中科学计算的基本库。为了使用numpy包,需要导入它。这里,我们导入numpy包并将其重命名为较短的别名净现值.

将numpy导入为np

接下来,我们定义一个函数,用于生成具有所需参数的正弦波信号。

定义正弦波(f,overSampRate,相位,nCyl):"""使用以下参数生成正弦波信号参数:f:正弦波频率(赫兹)overSampRate:过采样率(整数)相位:以弧度表示的所需相移nCyl:要生成的正弦波周期数退货:(t,g):时基(t)和信号g(t)作为元组例子:f=10;过采样率=30;相位=1/3*np.pi;nCyl=5;(t,g)=正弦波(f,overSampRate,相位,nCyl)"""fs=overSampRate*f#采样频率t=np.arange(0,nCyl*1/f-1/fs,1/fs)#时基g=np.sin(2*np.pi*f*t+相位)#如果需要余弦波,则替换为cosreturn(t,g)#返回时基和信号g(t)作为元组

我们注意到函数正弦波是在一个名为signalgen.py的文件中定义的。我们将在同一个文件中添加更多类似的函数。其目的是将所有相关的信号生成功能保存在一个文件中。这种方法可以扩展到面向对象编程。既然我们已经在signalgen.py中定义了正弦波函数,我们所需要做的就是用所需的参数调用它并绘制输出。

"""用给定的采样率模拟正弦信号"""将numpy导入为np导入matplotlib.pyplot作为plt#库进行打印从signalgen import sine_wave#导入函数f=10#频率=10Hz过采样率=30#过采样率fs=f*overSampRate#采样频率相位=1/3*np.pi#以弧度表示的相移nCyl=5#期望的正弦波周期数(t,x)=sine_wave(f,overSampRate,phase,nCyl)#函数调用plt.plot(t,x)#使用matplotlib包中的pyplot库进行绘图plt.title(‘正弦波f=’+str(f)+‘Hz’)#图标题plt.xlabel(“时间”)#x轴标签plt.ylabel(“振幅”)#y轴标签plt.show()#显示图形

Python是一种基于解释器的软件语言,以数字方式处理一切。为了获得平滑的正弦波,采样率必须远远高于规定的最低要求采样率,即至少是频率的两倍(f)–根据Nyquist-Shannon定理。因此,我们需要以明显高于奈奎斯特准则规定的速率对输入信号进行采样。较高的过采样率需要更多的内存用于信号存储。建议将过采样因子保持在可接受的值。

过采样因子30在上一个函数中选择。这是为了绘制一个平滑的连续的正弦波。因此,采样率变为f_s=30\次f=30\次10=300赫兹。如果正弦波需要相移,也请指定相移。

使用python的正弦波
图1:具有5个周期和1/3π弧度相移的10Hz正弦波

FFT的不同表示:

快速傅里叶变换只是一个数值计算N个-点DFT,有很多方法来绘制结果。FFT,实施于Scipy.fft包包,是J.W.Cooley和
J.W.Tuckey高效计算DFT。

实现FFT和IFFT可以按如下方式调用

从scipy.fftpack导入fft,ifftX=fft(X,N)#计算X[k]x=ifft(x,N)#计算x[N]

1.绘制DFT的原始值:

x轴从0N-1号机组–代表N个样本值。DFT值很复杂DFT的大小绝对值(X)绘制在y轴上。从这张图中,我们无法确定生成的正弦曲线的频率。

将numpy导入为np将matplotlib.pyplot作为plt导入从scipy.fftpack导入fftNFFT=1024#NFFT-点DFTX=fft(X,NFFT)#使用fft计算DFT图1,ax=plt.subplots(nrows=1,ncols=1)#创建图形句柄nVals=np.arange(start=0,stop=NFFT)#FFT图的原始索引ax.图(nVals,np.abs(X))ax.set_title('双面FFT-无FFTShift')ax.set_xlabel('采样点(N点DFT)')ax.set_ylabel(“DFT值”)图1.显示()
双面FFT–不使用python进行FFTShift
图2:双侧FFT–无FFTShift

2.FFT绘图–根据标准化频率轴绘制原始值:

在下一版本的绘图中,频率轴(x轴)被标准化为单位。只需将x轴上的样本索引除以长度N个FFT的。这使x轴相对于采样率标准化fs(模糊)然而,我们无法从曲线图中计算出正弦曲线的频率。

将numpy导入为np将matplotlib.pyplot作为plt导入从scipy.fftpack导入fftNFFT=1024#NFFT点DFTX=fft(X,NFFT)#使用fft计算DFT图2,ax=plt.subplots(nrows=1,ncols=1)#创建图形句柄nVals=np.arange(start=0,stop=NFFT)/NFFT#标准化DFT采样点ax.图(nVals,np.abs(X))ax.set_title('双面FFT-无FFTShift')ax.set_xlabel('归一化频率')ax.set_ylabel(“DFT值”)图2.显示()
使用python的带归一化x轴的双侧FFT
图3:具有标准化x轴的双面FFT(0到1)

3.FFT图–根据标准化频率(正负频率)绘制原始值:

如您所知,在频域中,这些值同时占据正频率轴和负频率轴。为了用正值和负值绘制频率轴上的DFT值0必须位于数组中间。这是通过使用FFT换档中的函数Scipy Pythonx轴从-0.50.5其中,端点是相对于采样率的标准化“折叠频率”fs(模糊).

将numpy导入为np将matplotlib.pyplot作为plt导入从scipy.fftpack导入fft,fftshiftNFFT=1024#NFFT-点DFTX=fftshift(fft(X,NFFT))#使用fft计算DFT图3,ax=plt.subplots(nrows=1,ncols=1)#创建图形句柄fVals=np.arange(start=-NFFT/2,stop=NFFT/2)/NFFT#DFT采样点ax.图(fVals,np.abs(X))ax.set_title(“双面FFT-带FFTShift”)ax.set_xlabel('归一化频率')ax.set_ylabel('DFT值');ax.自动缩放(启用=True,轴='x',紧密=True)ax.set_xticks(np.arange(-0.5,0.5+0.1,0.1))图show()
使用python的标准化x轴双面FFT
图4:具有标准化x轴的双面FFT(-0.5到0.5)

4.FFT图–x轴上的绝对频率与y轴上的幅值:

这里,归一化频率轴仅乘以采样率。从下图中,我们可以确定FFT的绝对值在10赫兹-10赫兹因此,生成的正弦信号的频率为10赫兹。峰值附近的小旁瓣10赫兹-10赫兹是由于光谱泄漏.

将numpy导入为np将matplotlib.pyplot作为plt导入从scipy.fftpack导入fft,fftshiftNFFT=1024X=fftshift(fft(X,NFFT))图4,ax=plt.subplots(nrows=1,ncols=1)#创建图形句柄fVals=np.arange(开始=-NFFT/2,停止=NFFT/2)*fs/NFFTax.图(fVals,np.abs(X),'b')ax.set_title(“双面FFT-带FFTShift”)ax.set_xlabel('频率(Hz)')ax.set_ylabel('|DFT值|')最大设置极限(-50,50)ax.set_xticks(np.arange(-50,50+10,10))图4.显示()
双面FFT-x轴上的绝对频率与y轴上的幅值
图5:双面FFT–x轴上的绝对频率与y轴上的幅值

5.功率谱–x轴上的绝对频率与y轴上的功率:

以下是FFT的最重要表示。它绘制了权力y轴上的每个频率分量和x轴上的频率。功率可以按线性比例或对数比例绘制。每个频率分量的功率计算如下

P_x(f)=x(f)x^{*}(f)

在哪里?X(f)是信号的频域表示x(吨)在Python中,必须使用适当的缩放项计算功率。

使用带python的FFT的功率谱密度
图6:使用FFT的功率谱密度

在对数刻度上用y轴绘制PSD图,可以生成信号处理中最常见的PSD图类型。

使用FFT和python的功率谱密度(对数刻度上的y轴)
图7:使用FFT的功率谱密度(对数刻度上的y轴)

对此文章进行评分:可怜的低于平均水平平均很好杰出的(14平均票数:4.29(共5个)

作者的书籍

Matlab中的无线通信系统
Matlab中的无线通信系统
第二版(PDF)

可怜的低于平均水平平均很好杰出的(168平均票数:3.71(共5个)

使用Python的数字调制
使用Python的数字调制
(PDF电子书)

可怜的低于平均水平平均很好杰出的(124平均票数:3.60(共5个)

数字模块使用matlab图书封面
使用Matlab的数字调制
(PDF电子书)

可怜的低于平均水平平均很好杰出的(129平均票数:3.71(共5个)

手绘通信工程最佳书籍
信号处理最佳书籍

本章主题

信号处理要点
生成标准测试信号
 正弦信号
 方波
 矩形脉冲
 高斯脉冲
 啁啾声信号
解释FFT结果-复杂DFT、频率箱和FFTShift
 实数和复数DFT
 快速傅里叶变换(FFT)
 解释FFT结果
 FFT换档
 IFFTShift(IFFT换档)
从FFT获取幅度和相位信息
 离散时间域表示
 用FFT在频域中表示信号
 从频域样本重构时域信号
功率谱密度
信号的功率和能量
 信号的能量
 信号的功率
 信号分类
 信号功率的计算-仿真和验证
多项式、卷积和Toeplitz矩阵
 多项式函数
 表示单变量多项式函数
 多项式乘法与线性卷积
 Toeplitz矩阵与卷积
卷积的计算方法
 方法1:Brute-force方法
 方法2:使用Toeplitz矩阵
 方法3:使用FFT计算卷积
 其他方法
解析信号及其应用
 解析信号与傅里叶变换
 提取瞬时振幅、相位、频率
 基于希尔伯特变换的相位解调
选择滤波器:FIR或IIR:理解设计视角
 设计说明书
 设计中的一般考虑因素

关于“使用Python绘制FFT–正弦波和余弦波的FFT”的思考

  1. 谢谢您!在计算PSD的最后一节中,你写道:“在Python中,功率必须用适当的缩放项来计算。”什么是适当的缩放?你有这个程序的例子吗?谢谢你,艾瑞斯

    答复

发表您的宝贵意见!!!