Search code examples
pythonnumpysignal-processingfft

How to get the correct frequency amplitudes in the FFT of a signal


I have the following 1Hz/10Hz signal

import numpy as np

total_time = 5
sampling_frequency = 200

t = np.linspace(0, total_time , total_time * sampling_frequency)
signal = np.sin(2 * np.pi * 1 * t) + 0.5 * np.sin(2 * np.pi * 10 * t)

plt.plot(t, signal)

enter image description here

That's the discrete FFT I get

fft_spectrum = np.fft.rfft(signal)
fft_spectrum_abs = np.abs(fft_spectrum)

freq = np.fft.rfftfreq(signal.size, d=1./sampling_frequency)

plt.plot(freq, fft_spectrum_abs)
plt.xlabel("frequency, Hz")
plt.ylabel("amplitude, units")
plt.show()

enter image description here

I would have expected the peak at 1Hz to have an amplitude of 1, and the peak at 10 to have an amplitude of 0.5 given my original signal. I'm having a factor of 500 off however looking at the values I'm getting on the plot - from where this factor is coming and how can I recover the original amplitudes?


Solution

  • You need to scale the output by dividing by the number of samples, in this example, 1000. Then, because the input is real and this is a one-sided FFT and there are no negative frequency bins, you multiply by 2. That will give you the 1 and 0.5 amplitude you're looking for.