Take the 2-minute tour ×

I am new to Python. I intend to do Fourier Transform to an array of discrete points, (time, acceleration), and plot the result out.

I copy and paste the sample FFT code, and modify accordingly.

Please see codes:

import numpy as np
import matplotlib.pyplot as plt

# Load the .txt file in
myData = np.loadtxt('twenty_z_up.txt')

# Extract the time and acceleration columns
time = copy(myData[:,0])

# Extract the acceleration columns
zAcc = copy(myData[:,3])

t = np.arange(10080)
sp = np.fft.fft(zAcc)
freq = np.fft.fftfreq(t.shape[-1])
plt.plot(freq, sp.real)

myData is a rectangular matrix with 10080 rows and 10 columns.

Thus, zAcc is the row3 extracted from the matrix.

In the plot drawn by Spyder, most of the harmonics concentrated around 0. They are all extremely small.

But my data are actually the accelerations of the phone carried by a walking person (including the gravity). So I expect the most significant harmonic happens around 2Hz.

Why is the graph non-sense?

Thanks in advance!

==============UPDATES: My Graphs====================== Time Domain

After the above-mentioned codes


The first time domain one:

x-axis is in millisecond.

y-axis is in m/s^2, due to earth gravity, it has a DC offset of ~10.

share|improve this question
np.arange(256) creates an array of integers (eg. from 0 to 255). When you call t.shape[-1] you are getting the length of the array t (which is 256). np.fft is the python fast fourier transform module. np.fft.fft() is the fast fourier transform function from the module. You need to call the function on the data. –  nicholaschris May 28 '13 at 9:34
@nicholaschris awesome! thanks! Then I modify 256 to 10080 to fit my case. The plot can be plotted after the change. But then the graph does not make sense.. Could you please help me check again? –  Farticle Pilter May 28 '13 at 9:41
What do you mean by harmonics around 0? If you mean there is energy at 0Hz i.e., DC, this indicates a DC offset in the time-domain data. Uploading an image would be useful (I'm not sure offhand how many points you need to add an image to the question, if you don't have enough leave a link to Imgur or similar and somebody will edit it in for you). –  Blair May 28 '13 at 9:53
You're not really providing enough information for getting proper help here. No doubt someone could guess the problem, but it's not trivial. What does the time-domain look like? If you think the data has a clear 2Hz oscillation, that should be pretty obvious on that plot. –  Henry Gomersall May 28 '13 at 10:05
most of the harmonics concentrated around 0. They are all extremely small. - what are your axis scales? 2Hz can be close to 0Hz especially on a log scale. –  Schorsch May 28 '13 at 17:19
show 3 more comments

2 Answers

up vote 2 down vote accepted

You do get two spikes at (approximately) 2Hz. Your sampling period is around 2.8 ms (as best as I can infer from your first plot), giving +/-2Hz the normalized frequency of +/-0.056, which is about where your spikes are. fft.fftfreq by default returns the normalized frequency (which scales the sampling period). You can set the d argument to be the sampling period, and you'll get a vector containing the actual frequency.

Your huge spike in the middle is obviously the DC offset (which you can trivially remove by subtracting the mean).

share|improve this answer
Wow. Awesome! Yes. Indeed. But since I am new to Python, could you please kindly tell me which Python statements I can use to make the graph properly displayed? By "Properly displayed", I mean 1. remove the trivial DC; 2. make x-axis really in Hz scale instead of kHz scale... –  Farticle Pilter May 29 '13 at 8:31
zAcc -= np.mean(zAcc) to remove the mean (with an in-place operation), and freq = np.fft.fftfreq(t.shape[-1], d=2.8e-3) for the frequency in Hz (with d being whatever the correct sampling period is). Also, you use copy but it's not clear where it comes from. I suggest you use the copy method rather than the copy function: time = myData[:,0].copy() –  Henry Gomersall May 29 '13 at 8:36
Great! Now I see. Thank you so so much for the kind help! –  Farticle Pilter May 29 '13 at 8:46
Also, just so everything is clear, your FFT plot is probably of the real part of the fft. I think that plot drops the imaginary part as it can't plot it sensibly. –  Henry Gomersall May 29 '13 at 9:59
add comment

As others said, we need to see the data, post it somewhere. Just to check, try first fixing the timestep size in fftfreq, then plot this synthetic signal, and then plot your signal to see how they compare:

timestep=1./50.#Assume sampling at 50Hz. Change this accordingly.
N=10080#the number of samples
t = np.linspace(0,T,N)#needed only to generate xAcc_synthetic
freq=2.#peak a frequency at 2Hz
#generate synthetic signal at 2Hz and add some noise to it
xAcc_synthetic = sin((2*np.pi)*freq*t)+np.random.rand(N)*0.2
sp_synthetic = np.fft.fft(xAcc_synthetic)
freq = np.fft.fftfreq(t.size,d=timestep)
print max(abs(freq))==(1/timestep)/2.#simple check highest freq.
plt.plot(freq, abs(sp_synthetic))

Now, at the x axis equal to 2 you actually have a physical frequency of 2Hz, and you may spot the more pronounced peak you are looking for. Moreover, you may want to have a look also at yAcc and zAcc.

share|improve this answer
I have posted the comparision graph. Please help. :) –  Farticle Pilter May 29 '13 at 1:37
add comment

Your Answer


