I've loaded an audio file with librosa to plot its magnitude spectrum
signal, sr = librosa.load(audio_file, sr=44100)
signal_fft = np.fft.fft(signal)
magnitude = np.abs(signal_fft)
frequency = np.linspace(0, sr, len(magnitude))
plt.plot(frequency[:30000], magnitude[:30000]) # cutting the plot at the Nyquist frequency
plt.xlabel("Frequency (Hz)")
plt.ylabel("Magnitude")
plt.title("Magnitude spectrum")
plt.show()
Here is the magnitude spectrum :
I have then tried to find the peaks of the spectrum with scipy.signal.find_peaks
peaks, _ = find_peaks(magnitude[:30000], height=350)
plt.plot(magnitude[:30000])
plt.plot(peaks, magnitude[peaks], "x")
plt.show()
Then I wanted to know if it is possible to plot the peaks on the frequency scale ? I'm having troubles to define the x axis because, when it is plotted it is appearing with another scale.
As indicated in matplotlib.pyplot.plot
's documentation:
x
values are optional and default torange(len(y))
As a result, your second plot uses indices for the x-axis instead of frequencies.
To get values in Hz you need the frequency at each of the plotted magnitude, which you fortunately have through your frequency
variable. You can thus generate your second plot with the same scale as the first with the following:
peaks, _ = find_peaks(magnitude[:30000], height=350)
plt.plot(frequency[:30000], magnitude[:30000])
plt.plot(frequency[peaks], magnitude[peaks], "x")
plt.show()