2

I'm very new to Python and I have a basic understanding problem. To me it seems that the result of an FFT is just based on the linspace chosen by oneself.

# Number of samplepoints
N = 600
# sample spacing
T = 1.0 / 800.0
x = p.linspace(0.0, N*T, N)
y = p.sin(50.0 * 2.0*p.pi*x) + 0.5*p.sin(80.0 * 2.0*p.pi*x)
yf = p.fft(y)
xf = p.linspace(0.0, 1.0/(2.0*T), N/2)

plt.plot(xf, 2.0/N * np.abs(yf[0:N/2]))
plt.grid()
plt.show()

By running this fft as an example I get two spikes, at 50 and at 80 Hz. When I change xf to:

xf = p.linspace(0.0, 5.0/(2.0*T), N/2)

the spikes are around 250 and 400 Hz.

Doesn't this mean, that I have to know the correct results beforehand (in this case the frequencies of the two sinus waves the input signal consists of), so that I can later adjust the scaling of the axis to fit those results? Probably not, so I'd be glad if someone could explain this problem.

Thore
  • 21
  • 5

2 Answers2

1

You must calculate the correct frequencies depending on sample rate, number of samples and samples used in the fft (NFFT). The FFT algorithm does not know what time-scale you are operating in. For example, the frequency axis could also be given in angular frequency in which case you would just scale the axis with 2*pi.

Therefore, you must know the sample rate and number of samples of the input signal to create a correct frequency axis for the FFT result - you do not, however, need to know anything about the shape of the input signal (disregarding aliasing concerns).

The frequencies [Hz] can be calculated using:

dt = 0.0001 # your T
Fs = 1 / dt # sample rate
xt = np.arange (0, 10, dt)
nt = len (xt) # length of time series, your N

# make signal
st = .5 * np.sin (50 * 2 * np.pi * xt) + .5 * np.sin (80 * 2 * np.pi * xt)

# take fourier transform and shift frequency spectra
S  = np.fft.fftshift(np.fft.fft (st))

## make argument array, frequency [Hz]
#
# extending from -Fs/2 to Fs/2, the Nyquist frequency, with the same
# number of samples as in the time series (xt and st).

freqs = Fs * np.linspace (-1/2, 1/2, nt)

# plot absolute value, scaled with number of samples
# ( note that it is also interesting to plot the complex angle
#   using np.angle () ). together they make a bode-plot.

plt.plot (freqs, np.abs(S) / nt)
plt.xlabel ('Frequency [Hz]')
gauteh
  • 16,435
  • 4
  • 30
  • 34
-1

You are calculating correctly the FFT of a sine function in:

yf = p.fft(y)

Then you are ploting it against an list of values constructed using linespace which is wrong. You should plot the magnitude of FFT against its frequency. See this example for details.

Amritbir Singh Gill
  • 366
  • 1
  • 3
  • 12