Gre*_*uce 6 python numpy fft matplotlib
我正在尝试使用该fft
函数获取周期信号的频谱。然后绘制变换的幅度和相位。幅度图没问题,但相位图完全出乎意料。例如,我使用了函数 Sin³(t) 和 Cos³(t)。我使用的代码是:
import matplotlib.pyplot as plt
import numpy.fft as nf
import math
import numpy as np
pi = math.pi
N=512
# Sin³(x)
t=np.linspace(-4*pi,4*pi,N+1);t=t[:-1]
y=(np.sin(t))**3
Y=nf.fftshift(nf.fft(y))/N
w=np.linspace(-64,64,N+1);w=w[:-1]
plt.figure("0")
plt.subplot(2,1,1)
plt.plot(w,abs(Y),'ro',lw=2)
plt.xlim((-4,4))
plt.ylabel(r"$|Y|$",size=16)
plt.title("Spectrum of sin\u00B3(t)")
plt.grid(True)
plt.subplot(2,1,2)
ii=np.where(abs(Y)>1e-3)
plt.plot(w[ii],np.angle(Y[ii]),'go',lw=2)
plt.xlim((-4,4))
plt.ylabel(r"Phase of $Y$",size=16)
plt.xlabel(r"$\omega$",size=16)
plt.grid(True)
# Cos³(x)
t=np.linspace(-4*pi,4*pi,N+1);t=t[:-1]
y=(np.cos(t))**3
Y=nf.fftshift(nf.fft(y))/N
w=np.linspace(-64,64,N+1);w=w[:-1]
plt.figure("1")
plt.subplot(2,1,1)
plt.plot(w,abs(Y),'ro',lw=2)
plt.xlim((-4,4))
plt.ylabel(r"$|Y|$",size=16)
plt.title("Spectrum of cos\u00B3(t)")
plt.grid(True)
plt.subplot(2,1,2)
ii=np.where(abs(Y)>1e-3)
plt.plot(w[ii],(np.angle(Y[ii])),'go',lw=2)
plt.xlim((-4,4))
plt.ylabel(r"Phase of $Y$",size=16)
plt.xlabel(r"$\omega$",size=16)
plt.grid(True)
Run Code Online (Sandbox Code Playgroud)
得到的图是:
i) 对于 Sin³(t) - Sin³(t) 的频谱幅度和相位
ii) 对于 Cos³(t) - Cos³(t) 的频谱幅度和相位
正如您在上面的链接中看到的,两个函数的大小都很好。Sin³(t) 的频谱相位如预期的那样正确。
由于 Cos³(t) 是实数和偶数,并且以复指数形式展开表明系数的相位为 0。但绘制的图形显示了完全不同的答案(参见2):在 w=-3 时,相位接近 5弧度。我犯了什么错误,实现 FFT 的正确方法是什么。
np.fft
表现符合预期;是你的阴谋造成了混乱。致电plt.tight_layout()
应该可以帮助您解决问题:
如果仔细查看 cos\xc2\xb3(t) 相位的 y 轴,您会发现这些值都有一个 1e-17 前置因子。因此,当 w = -3 时,相位并不接近5 弧度,它实际上接近 5e-17 弧度(实际上为零)。
\n\n我在研究这个问题时整理了你的代码:
\n\nimport matplotlib.pyplot as plt\nimport numpy.fft as nf\nimport numpy as np\n\nplt.rcParams[\'axes.grid\'] = True\n\npi = np.pi\nN = 512\n\nt = np.linspace(-4*pi, 4*pi, N+1)[:-1]\n\n\ndef fft_func(x, func, N):\n y = func(x) ** 3\n Y = nf.fftshift(nf.fft(y)) / N\n w = np.linspace(-64, 64, N+1)[:-1]\n return y, Y, w\n\n\ndef plot_mag_phase(w, Y, func_name):\n fig, ax = plt.subplots(2, 1)\n\n ii = np.where(abs(Y) > 1e-3)\n\n ax[0].plot(w, abs(Y), \'ro\', lw=2)\n ax[1].plot(w[ii], np.angle(Y[ii]), \'go\', lw=2)\n\n ax[0].set_xlim(-4, 4)\n ax[1].set_xlim(-4, 4)\n\n ax[0].set_ylabel("$|Y|$", size=16)\n ax[1].set_ylabel("Phase of $Y$", size=16)\n\n ax[0].set_title("Spectrum of {}\\u00B3(t)".format(func_name))\n ax[1].set_xlabel(r\'$\\omega$\', size=16)\n\n fig.tight_layout()\n\n# sin x ^ 3\ny, Y, w = fft_func(t, np.sin, N)\nplot_mag_phase(w, Y, \'sin\')\n\n# cos x ^ 3\ny, Y, w = fft_func(t, np.cos, N)\nplot_mag_phase(w, Y, \'cos\')\n
Run Code Online (Sandbox Code Playgroud)\n