Python 使用matplotlib绘制正弦波的傅里叶变换
我正试图绘制一个基于傅里叶变换的符号波Python 使用matplotlib绘制正弦波的傅里叶变换,python,matplotlib,scipy,fft,continuous-fourier,Python,Matplotlib,Scipy,Fft,Continuous Fourier,我正试图绘制一个基于傅里叶变换的符号波 所需输出 我想得到一个像这样的傅里叶变换图 电流输出 但是它看起来像这样 额外的 这就是我正在使用的正弦波 你应该得到你想要的。您的振幅计算不正确,因为您的分辨率和speriod不一致 更长的数据采集时间: import numpy as np import matplotlib.pyplot as plt import scipy.fft def sinWav(amp, freq, time, phase=0): return am
所需输出 我想得到一个像这样的傅里叶变换图 电流输出 但是它看起来像这样
额外的 这就是我正在使用的正弦波 你应该得到你想要的。您的振幅计算不正确,因为您的分辨率和speriod不一致 更长的数据采集时间:
import numpy as np
import matplotlib.pyplot as plt
import scipy.fft
def sinWav(amp, freq, time, phase=0):
return amp * np.sin(2 * np.pi * (freq * time - phase))
def plotFFT(f, speriod, time):
"""Plots a fast fourier transform
Args:
f (np.arr): A signal wave
speriod (int): Number of samples per second
time ([type]): total seconds in wave
"""
N = speriod * time
# sample spacing
T = 1.0 / 800.0
x = np.linspace(0.0, N*T, N, endpoint=False)
yf = scipy.fft.fft(f)
xf = scipy.fft.fftfreq(N, T)[:N//2]
amplitudes = 1/(speriod*4)* np.abs(yf[:N//2])
plt.plot(xf, amplitudes)
plt.grid()
plt.xlim([1,3])
plt.show()
speriod = 800
time = {
0: np.arange(0, 4*4, 1/speriod),
1: np.arange(4*4, 8*4, 1/speriod),
2: np.arange(8*4, 12*4, 1/speriod)
}
signal = np.concatenate([
sinWav(amp=0.25, freq=2, time=time[0]),
sinWav(amp=1, freq=2, time=time[1]),
sinWav(amp=0.5, freq=2, time=time[2])
]) # generate signal
plotFFT(signal, speriod, 48)
您还可以以交互方式绘制此图。您可能需要安装
pip安装scikit dsp comm
#!pip安装scikit dsp通信
#制作上述内容的交互式版本
从ipywidgets导入交互、交互
将numpy作为np导入
将matplotlib.pyplot作为plt导入
从scipy进口fftpack
plt.rcParams['figure.figsize']=[10,8]
字体={'weight':'bold',
“大小”:14}
plt.rc('font',**font)
def脉冲图(fm=1000,Fs=2010):
t长度=1.0#以秒为单位
#生成时间轴
tt=np.arange(np.round(tlen*Fs))/float(Fs)
#产生正弦
xt=np.sin(2*np.pi*fm*tt)
小地块(211)
plt.绘图(tt[:500],xt[:500],'-b')
plt.plt(tt[:500]、xt[:500]、'or',label='xt values')
plt.ylabel(“$x(t)$”)
plt.xlabel('t[sec]”)
strt2='正弦波形$x(t)$'
strt2=strt2+',$f_m={}$Hz,$f_s={}$Hz'。格式(fm,Fs)
产品名称(strt2)
plt.legend()
plt.grid()
X=fftpack.fft(xt)
freqs=fftpack.fftfreq(len(xt))*Fs
小地块(212)
N=xt.size
#密度泛函
X=np.fft.fft(xt)
X_db=20*np.log10(2*np.abs(X)/N)
#f=np.fft.fftfreq(N,1/Fs)
f=np.arange(0,N)*Fs/N
plt.绘图(f,X_db,'b')
plt.xlabel('频率单位为赫兹[赫兹])
plt.ylabel('频域\n(频谱)幅值')
plt.grid()
plt.紧_布局()
交互_图=交互(脉冲_图,fm=(10000000000000),Fs=(100040000,10));
输出=交互式绘图。子项[-1]
#output.layout.height='350px'
交互图
它应该像我发布的图,振幅为3.5,频率为2时,请参见编辑,为什么这不适用于其他采样率?频率不应该独立于采样率吗?我认为sr只是确定了信号被分割成的x轴的大小,如果你在处理连续数据,你是对的(在数学中也是如此)。但在物理学中,数据是不连续的。FFT指的是离散傅立叶变换,在特定的物理环境中。我改变的原因可以在这里找到:这都是关于这种关系。事实上,你的移动是由于光谱“折叠”造成的,因为你不符合奈奎斯特关系。我试图让我的图形看起来更连续,但我一直得到相同的块状图形为什么从-300到0?@Sam,因为y轴只是光谱量级。如果你想的话,你可以让它线性化。它不应该仍然是350吗?
import numpy as np
import matplotlib.pyplot as plt
import scipy.fft
def sinWav(amp, freq, time, phase=0):
return amp * np.sin(2 * np.pi * (freq * time - phase))
def plotFFT(f, speriod, time):
"""Plots a fast fourier transform
Args:
f (np.arr): A signal wave
speriod (int): Number of samples per second
time ([type]): total seconds in wave
"""
N = speriod * time
# sample spacing
T = 1.0 / 800.0
x = np.linspace(0.0, N*T, N, endpoint=False)
yf = scipy.fft.fft(f)
xf = scipy.fft.fftfreq(N, T)[:N//2]
amplitudes = 1/speriod* np.abs(yf[:N//2])
plt.plot(xf, amplitudes)
plt.grid()
plt.xlim([1,3])
plt.show()
speriod = 800
time = {
0: np.arange(0, 4, 1/speriod),
1: np.arange(4, 8, 1/speriod),
2: np.arange(8, 12, 1/speriod)
}
signal = np.concatenate([
sinWav(amp=0.25, freq=2, time=time[0]),
sinWav(amp=1, freq=2, time=time[1]),
sinWav(amp=0.5, freq=2, time=time[2])
]) # generate signal
plotFFT(signal, speriod, 12)
import numpy as np
import matplotlib.pyplot as plt
import scipy.fft
def sinWav(amp, freq, time, phase=0):
return amp * np.sin(2 * np.pi * (freq * time - phase))
def plotFFT(f, speriod, time):
"""Plots a fast fourier transform
Args:
f (np.arr): A signal wave
speriod (int): Number of samples per second
time ([type]): total seconds in wave
"""
N = speriod * time
# sample spacing
T = 1.0 / 800.0
x = np.linspace(0.0, N*T, N, endpoint=False)
yf = scipy.fft.fft(f)
xf = scipy.fft.fftfreq(N, T)[:N//2]
amplitudes = 1/(speriod*4)* np.abs(yf[:N//2])
plt.plot(xf, amplitudes)
plt.grid()
plt.xlim([1,3])
plt.show()
speriod = 800
time = {
0: np.arange(0, 4*4, 1/speriod),
1: np.arange(4*4, 8*4, 1/speriod),
2: np.arange(8*4, 12*4, 1/speriod)
}
signal = np.concatenate([
sinWav(amp=0.25, freq=2, time=time[0]),
sinWav(amp=1, freq=2, time=time[1]),
sinWav(amp=0.5, freq=2, time=time[2])
]) # generate signal
plotFFT(signal, speriod, 48)