brandon kinman
brandon kinman

Reputation: 113

Understanding matplotlib magnitude_spectrum output

I'm having problems understanding the output generated by matplotlib's magnitude_spectrum function call.

I have generated a sine with 50khz frequency,

f_s = 488000.0 # Hz
t = np.arange(0.0, 1.0, 1/f_s)
s1 = 100*np.sin(2*np.pi*50000*t)

I then plot the resulting magnitude spectrum, after dividing by the number of FFT bins

s1_magspec = plt.magnitude_spectrum(s1,Fs=f_s)
plt.plot(s1_magspec[0]/len(s1_magspec[0]))

The result is a single spike at 50khz, but with a magnitude of 50, as opposed to the expected 100.

Can anybody explain why this is?

Here is a link to an ipython notebook describing showing the afforementioned code and the resulting plot:

http://nbviewer.ipython.org/gist/bkinman/22cc15d3ad3b9b2db09e

Upvotes: 4

Views: 2609

Answers (2)

insaneinvader
insaneinvader

Reputation: 101

The amplitude (100%) is divided into negative (50%) and positive (50%) frequencies. You can see what I mean if you put in this code (note the sides='twosided'):

s1_magspec = plt.magnitude_spectrum(s1, Fs=f_s, sides='twosided')

Just be careful if you add some DC offset, e.g. 30, its amplitude goes completely to 0 Hz (note the + 30):

s1 = 100*np.sin(2*np.pi*50000*t) + 30
s1_magspec = plt.magnitude_spectrum(s1, Fs=f_s, sides='twosided')

Upvotes: 0

Ajean
Ajean

Reputation: 5659

It looks like it has to do with the default setting for the FFT window used. The documentation says that the default is a Hanning window. If you use a boxcar window instead:

s1_magspec = plt.magnitude_spectrum(s1, Fs=f_s, window=np.ones(s1.shape))

you'll get your peak at 100, just like with a straight numpy FFT.

By the way, it would be good if you edited your question to put in the line of code creating s1_magspec rather than relying on the notebook viewer, the link to which will undoubtedly break someday.

Upvotes: 5

Related Questions