Вы используете неправильную функцию для вычисления частот. БПФ-преобразования реальных сигналов имеют отрицательные частотные компоненты, которые являются комплексными сопряженными положительными, т. Е. Спектр является эрмитово-симметричным c. rfft()
использует этот факт и не выводит отрицательные частоты, только компонент D C и положительные. Следовательно, sig_psd
в два раза короче того, что вы получите, если вы используете fft()
вместо rfft()
и передача его в fftfreq()
эффективно удваивает частоты.
Решение: используйте rfftfreq()
вместо.
import numpy as np
import matplotlib.pyplot as plt
time_step = 1.0/100e3
t = np.arange(0, 2**14) * time_step
sig = np.sin(2*np.pi*1e3*t)
sig_fft = np.fft.rfft(sig)
#calculate the power spectral density
sig_psd = np.abs(sig_fft) ** 2 + 1
#create the frequencies
fftfreq = np.fft.rfftfreq(len(sig), d=time_step) # <-- note: len(sig), not len(sig_psd)
#filter out the positive freq
i = fftfreq > 0 # <-- note: Not really needed, this just removes the DC component
plt.plot(fftfreq[i], 10*np.log10(sig_psd[i]))
plt.xscale("log")