Scipy FFT-如何获得相位角 [英] Scipy FFT - how to get phase angle

查看:455
本文介绍了Scipy FFT-如何获得相位角的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用python中的scipy fft模块无法获得简单正弦曲线的相位.我遵循了教程紧密结合,并将matlab代码转换为python.但是,无论我在输入中使用哪个阶段,该图始终显示3.我缺少什么?

I'm having trouble getting the phase of a simple sine curve using the scipy fft module in python. I followed this tutorial closely and converted the matlab code to python. However, no matter what phase I use for the input, the graph always shows 3. What am I missing?

import numpy as np
import matplotlib.pyplot as plt
import scipy.fftpack
import cmath
A=10
fc = 10
phase=60
fs=32#Sampling frequency with oversampling factor of 32

t = np.arange(0,2,1/fs)

#Convert the phase shift to radians from degrees.
phi = phase*np.pi/180

x=A*np.cos(2*np.pi*fc*t+phi)

N=256
X = scipy.fftpack.fftshift(scipy.fftpack.fft(x,N))/N

df=fs/N #Frequency resolution.
sampleindex = np.arange(-N/2,N/2,1) #Ordered index for FFT plot.
f = sampleindex*df #x-axis index continued to ordered frequencies

raw_phases = np.angle(X)

X2=np.copy(X)#Store the FFT results in another array.
#Detect very small numbers and ignore them.
tau = max(abs(X))/10
X2[abs(X)<tau]=0

phase=[cmath.phase(i) for i in X2]
plt.plot(f,phase)
plt.show()

这是一些简单的代码.似乎仍然无法达到阶段.

Here is some simpler code. Still can't seem to get the phase.

y = 28*np.sin(2*np.pi/7*x)
yf = scipy.fftpack.fft(y)
xf = np.linspace(0.0, 1.0/(2.0*T), N/2)
phase = np.angle(yf)
yf = np.abs(yf[:N//2])
phase = phase[:N//2]
xf = xf[1:]
yf = yf[1:]
phase = phase[1:]
yf = yf-np.mean(yf)
#The frequencies seem to always be scaled by 0.1433, not sure why.
c = 2*np.pi/7/0.143301
freqs = xf[yf>np.std(yf)]*c
phases = phase[yf>np.std(yf)]

我得到的频率聚集在2 * np.pi/7附近.但是我得到的阶段是:

The frequencies I get are clustered around 2*np.pi/7. But the phases I get are:

array([-0.217795  , -0.22007488, -0.22226087,  2.91723935,  2.91524011,
    2.91333367])

根本没有相位.

推荐答案

这是显示如何获取角度的最简单的代码.

This is the simplest code to show how to get the angles.

请注意,我已经创建了信号y,使得其中包含整数个周期(如我建议的 a>).

Note that I've created the signal y such that there is an integer number of periods in it (as I suggested in a comment, and @hotpaw2 suggested in their answer).

这是OP代码的问题.

我使用linspace使用endpoint=False选项创建了时间轴.这很重要,如果t包含数字10,那么我们将不再有确切的整数周期.使用离散傅立叶变换时,可以帮助您考虑重复信号时会发生什么.只需采用y,并连接其自身的副本:np.hstack((y,y)).这个新信号仍然是单个正弦波的采样,还是我们创建了更复杂的信号?在两个副本相遇的那一刻会发生什么?

I used linspace to create the time axis, using the endpoint=False option. This is important, if t were to contain the number 10, then we no longer have an exact integer number of periods. When working with the discrete Fourier transform, it helps to think of what happens when you repeat the signal. Simply take y, and concatenate a copy of itself: np.hstack((y,y)). Is this new signal still a sampling of a single sine wave, or did we create something more complex? What happens at that point where the two copies meet?

import numpy as np
import matplotlib.pyplot as plt
import scipy.fftpack

phase = np.pi / 4
t = np.linspace(0, 10, num=200, endpoint=False)
y = np.cos(2 * np.pi * t + phase)
Y = scipy.fftpack.fftshift(scipy.fftpack.fft(y))
f = scipy.fftpack.fftshift(scipy.fftpack.fftfreq(len(t)))

p = np.angle(Y)
p[np.abs(Y) < 1] = 0
plt.plot(f, p)
plt.show()

这篇关于Scipy FFT-如何获得相位角的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆