Reputation: 41
I am trying to plot the fft of a wav file, I have successfully completed it using the regular fft but I wanted to experiment with rfft
as my application was to perform this in music. When I try to plot xf
and yf
(figure 2) I run into an issue where xf
is half the length of yf
and I can't figure out why, I assume its due to the negative frequencies missing but I thought changing both function calls to rfft
and rfftfreq
would handle it.
import numpy as np
import soundfile as sf
import matplotlib.pyplot as plt
square = 'square.wav'
sine = 'sine.wav'
k = '1Khz.wav'
cello = 'cello.wav'
data, fs = sf.read(k)
#Plot the Signal
N = len(data)
T = 1.0/fs
x = np.linspace(0, (N*T), N)
plt.plot(x, data)
plt.grid()
count = 0
yf = np.fft.rfft(data)
xf = np.fft.rfftfreq(yf.size, d=T)
plt.figure(2)
plt.plot(xf, yf)
plt.show()
Upvotes: 1
Views: 6672
Reputation: 14577
The sizes used for numpy.fft.rfft
and numpy.fft.rfftfreq
need to match. As such you should use your data.size
rather yf.size
(since the size of yf
is already reduced by not including the negative frequencies) as argument to rfftfreq
:
yf = np.fft.rfft(data)
xf = np.fft.rfftfreq(data.size, d=T)
Finally note that as you plot yf
with plt.plot(xf, yf)
you would get a warning about the imaginary part being lost. If you are interested in plotting the magnitude of the frequency spectrum, you should rather use plt.plot(xf, abs(yf))
.
Upvotes: 1
Reputation: 7141
You need to convert the frequencies to the sample rate. See https://stackoverflow.com/a/27191172/7919597 or the doc of rfftfreq:
signal = np.array([-2, 8, 6, 4, 1, 0, 3, 5, -3, 4], dtype=float)
fourier = np.fft.rfft(signal)
n = signal.size
sample_rate = 100
freq = np.fft.fftfreq(n, d=1./sample_rate)
print(freq)
freq = np.fft.rfftfreq(n, d=1./sample_rate)
print(freq)
Upvotes: 0