2

I looked into many examples of scipy.fft and numpy.fft. Specifically this example Scipy/Numpy FFT Frequency Analysis is very similar to what I want to do. Therefore, I used the same subplot positioning and everything looks very similar.

I want to import data from a file, which contains just one column to make my first test as easy as possible.

My code writes like this:

import numpy as np
import scipy as sy
import scipy.fftpack as syfp
import pylab as pyl

# Read in data from file here
array = np.loadtxt("data.csv")
length = len(array)
# Create time data for x axis based on array length
x = sy.linspace(0.00001, length*0.00001, num=length)

# Do FFT analysis of array
FFT = sy.fft(array)
# Getting the related frequencies
freqs = syfp.fftfreq(array.size, d=(x[1]-x[0]))

# Create subplot windows and show plot
pyl.subplot(211)
pyl.plot(x, array)
pyl.subplot(212)
pyl.plot(freqs, sy.log10(FFT), 'x')
pyl.show()

The problem is that I will always get my peak at exactly zero, which should not be the case at all. It really should appear at around 200 Hz.

enter image description here

With smaller range:
enter image description here

Still biggest peak at zero.

Community
  • 1
  • 1
A_Pete
  • 33
  • 1
  • 1
  • 5
  • 2
    Are you sure there isn't a peak at 200Hz? You have plotted up to frequencies of 600,000, so seeing what happens at 200 Hz is difficult in your plot. You *do* have a DC component in the data though, so I am not so the peak at 0 is probably accurate. – Hannes Ovrén Dec 17 '13 at 13:04
  • That said, can we get a plot of the interval [-400,400] or something as well? – Hannes Ovrén Dec 17 '13 at 13:04
  • Yes, because even if I just plot from frequencies of -500 to 500 there will just show up one peak at 0. As can be seen here: http://s29.postimg.org/439jgrzon/stack_OFlow_range.png – A_Pete Dec 17 '13 at 13:10
  • Uhm, that is the same data, just with different numbers on the axis. – Hannes Ovrén Dec 17 '13 at 13:35
  • Hmm... well what I did is just add this array: `pltfreqs = freqs/100` and then plot by `pyl.plot(pltfreqs, sy.log10(FFT), 'x')` . Is that wrong? Excuse my question, but this is the first time I ever used python. – A_Pete Dec 17 '13 at 13:37
  • No, because that just changes the values on the line, they will still show the same data. You would have to either zoom using e.g. `pyl.xlim(-500,500)` or slice your **data**, and not the **coordinates of the data**. – Hannes Ovrén Dec 17 '13 at 13:43
  • Yeah that was really dumb by myself. Just figured that out. Now I still do have the biggest peak at zero and many smaller ones around 200: http://s24.postimg.org/l4izy26t1/stack_OFlow_range_2.png – A_Pete Dec 17 '13 at 13:47
  • Looks reasonable to me. – Hannes Ovrén Dec 17 '13 at 13:50
  • This question appears to be off-topic because it is about signal processing and not programming. – Hannes Ovrén Dec 17 '13 at 13:51
  • Yeah you're right. I just thought the peaks should be more significant. Thank you very much! – A_Pete Dec 17 '13 at 13:57

1 Answers1

4

As already mentioned, it seems like your signal has a DC component, which will cause a peak at f=0. Try removing the mean with, e.g., arr2 = array - np.mean(array).

Furthermore, for analyzing signals, you might want to try plotting power spectral density.:

import matplotlib.pylab as plt
import matplotlib.mlab as mlb

Fs = 1./(d[1]- d[0])  # sampling frequency
plt.psd(array, Fs=Fs, detrend=mlb.detrend_mean) 
plt.show()

Take a look at the documentation of plt.psd(), since there a quite a lot of options to fiddle with. For investigating the change of the spectrum over time, plt.specgram() comes in handy.

Dietrich
  • 5,241
  • 3
  • 24
  • 36