# numpy – Plotting power spectrum in python

## numpy – Plotting power spectrum in python

Numpy has a convenience function, `np.fft.fftfreq` to compute the frequencies associated with FFT components:

``````from __future__ import division
import numpy as np
import matplotlib.pyplot as plt

data = np.random.rand(301) - 0.5
ps = np.abs(np.fft.fft(data))**2

time_step = 1 / 30
freqs = np.fft.fftfreq(data.size, time_step)
idx = np.argsort(freqs)

plt.plot(freqs[idx], ps[idx])
``````

Note that the largest frequency you see in your case is not 30 Hz, but

``````In [7]: max(freqs)
Out[7]: 14.950166112956811
``````

You never see the sampling frequency in a power spectrum. If you had had an even number of samples, then you would have reached the Nyquist frequency, 15 Hz in your case (although numpy would have calculated it as -15).

if rate is the sampling rate(Hz), then `np.linspace(0, rate/2, n)` is the frequency array of every point in fft. You can use `rfft` to calculate the fft in your data is real values:

``````import numpy as np
import pylab as pl
rate = 30.0
t = np.arange(0, 10, 1/rate)
x = np.sin(2*np.pi*4*t) + np.sin(2*np.pi*7*t) + np.random.randn(len(t))*0.2
p = 20*np.log10(np.abs(np.fft.rfft(x)))
f = np.linspace(0, rate/2, len(p))
plot(f, p)
``````

signal x contains 4Hz & 7Hz sin wave, so there are two peaks at 4Hz & 7Hz.

#### numpy – Plotting power spectrum in python

You can also use scipy.signal.welch to estimate the power spectral density using Welchâ€™s method.
Here is an comparison between np.fft.fft and scipy.signal.welch:

``````from scipy import signal
import numpy as np
import matplotlib.pyplot as plt

fs = 10e3
N = 1e5
amp = 2*np.sqrt(2)
freq = 1234.0
noise_power = 0.001 * fs / 2
time = np.arange(N) / fs
x = amp*np.sin(2*np.pi*freq*time)
x += np.random.normal(scale=np.sqrt(noise_power), size=time.shape)

# np.fft.fft
freqs = np.fft.fftfreq(time.size, 1/fs)
idx = np.argsort(freqs)
ps = np.abs(np.fft.fft(x))**2
plt.figure()
plt.plot(freqs[idx], ps[idx])
plt.title(Power spectrum (np.fft.fft))

# signal.welch
f, Pxx_spec = signal.welch(x, fs, flattop, 1024, scaling=spectrum)
plt.figure()
plt.semilogy(f, np.sqrt(Pxx_spec))
plt.xlabel(frequency [Hz])
plt.ylabel(Linear spectrum [V RMS])
plt.title(Power spectrum (scipy.signal.welch))
plt.show()
``````

[