日志轴上具有fftpack的实际数据的功率谱

时间:2014-02-04 02:59:13

标签: python numpy scipy fft fftpack

我已经阅读过很多关于此主题的讨论(comparison between lomb-scargle and fft Plotting power spectrum in pythonScipy/Numpy FFT Frequency Analysis以及其他许多内容),但仍无法管理,所以我需要一些提示。 我有一个光子事件列表(检测与时间),数据可用here。列为timecountserrors,并且计入不同的能量带(您可以忽略它们)。我知道源的周期为8.9 days = 1.3*10^-6 Hz。 我想绘制功率谱密度,在此频率处显示峰值(可能在对数x轴上)。如果我可以避免绘图的一半(对称)也会很好。到目前为止这是我的代码,不是到目前为止,但仍然是:

import numpy as np
from scipy.fftpack import fft, rfft, fftfreq
import pylab as plt

x,y = np.loadtxt('datafile.txt', usecols = (0,1), unpack=True)
y = y - y.mean() # Removes the large value at the 0 frequency that we don't care about

f_range = np.linspace(10**(-7), 10**(-5), 1000)
W = fftfreq(y.size, d=x[1]-x[0])

plt.subplot(2,1,1)
plt.plot(x,y)
plt.xlabel('Time (days)')

f_signal = fft(y)
plt.subplot(2,1,2)
plt.plot(W, abs(f_signal))
plt.xlabel('Frequency (Hz)')

这里(无用的)情节产生: DFT

1 个答案:

答案 0 :(得分:4)

以上代码的改进版本:

import pyfits
import numpy as np
from scipy.fftpack import fft, rfft, fftfreq
import pylab as plt

x,y = np.loadtxt('data.txt', usecols = (0,1), unpack=True)
y = y - y.mean()

W = fftfreq(y.size, d=(x[1]-x[0])*86400)
plt.subplot(2,1,1)
plt.plot(x,y)
plt.xlabel('Time (days)')

f_signal = fft(y)
plt.subplot(2,1,2)
plt.plot(W, abs(f_signal)**2)
plt.xlabel('Frequency (Hz)')

plt.xscale('log')
plt.xlim(10**(-6), 10**(-5))
plt.show()

这里的情节产生(正确): fft 最高的峰值是我试图重现的峰值。第二个峰值也是预期的,但功率较低(确实如此)。 如果使用rfft代替fft(和rfftfreq而不是fftfreq),则会重现相同的绘图(在这种情况下,频率值,而不是模块,可以使用numpy.fft.rfft

我不想阻止这个话题,所以我会在这里问:我如何检索峰值的频率?在峰值旁边绘制频率会很棒。