Print highest peak value of the frequency domain plot

不羁岁月 提交于 2021-01-28 20:45:01

问题


I've attempted to plot the oscillations of my home made quad in the time and frequency domain. How do I print the value of my highest peak in the frequency domain plot?

code:

import matplotlib.pyplot as plt
import numpy as np
from scipy import fft, arange

csv = np.genfromtxt ('/Users/shaunbarney/Desktop/Results/quadOscillations.csv', delimiter=",",dtype=float)
x = csv[:,0]
y = csv[:,1]
x = x - 6318        #Remove start offset
av=0
for i in xrange(1097):      #Calculate average sampling time in seconds oscillations 
    if i == 1076:
        avSampleTime = av/1097000     # 
        break
    av = av + (x[i+1]-x[i])

Fs = 1/avSampleTime   #Average sampling freq.
n = 1079              #no.Samples
k = arange(n)
Ts = n/Fs
frq = k/Ts            #Frequency range two sided
frq = frq[range(n/2)] #Frequency range one sided
Y = fft(y)/n          #Fast fourier transfors
Y = Y[range(n/2)]     #Normalise

#        PLOTS

plt.subplot(2,1,1)
plt.plot(frq,abs(Y),'r') # plotting the spectrum
plt.xlabel('Freq (Hz)')
plt.ylabel('|Y(freq)|')
plt.grid('on')
plt.subplot(2,1,2)
plt.plot(x,y)
plt.xlabel('Time (ms)')
plt.ylabel('Angle (degrees)')
plt.grid('on')
plt.show()

The results looks like:

Thanks, Shaun


回答1:


Since you're using numpy, just simply use numpy.max and numpy.argmax to determine the peak as well as the location of the peak so you can print this out to your screen. Once you find this location, index into your frequency array to obtain the final coordinate.

Assuming that all of your variables have been created when you run your code, simply do the following:

mY = np.abs(Y) # Find magnitude
peakY = np.max(mY) # Find max peak
locY = np.argmax(mY) # Find its location
frqY = frq[locY] # Get the actual frequency value

peakY contains the magnitude value that is the largest in your graph and frqY contains the frequency that this largest value (i.e. peak) is located at. As a bonus, you can plot that on your graph in a different colour and with a larger marker to distinguish it from the main magnitude graph. Remember that invoking multiple plot calls will simply append on top of the current figure of focus. Therefore, plot your spectrum then plot this point on top of the spectrum. I'll make the size of the point larger than the thickness of the plot as well as marking the point with a different colour. You could also perhaps make a title that reflects this largest peak value and the corresponding location.

Also remember that this is to be done on the magnitude, so before you plot your actual magnitude, simply do this:

#        PLOTS
# New - Find peak of spectrum - Code from above
mY = np.abs(Y) # Find magnitude
peakY = np.max(mY) # Find max peak
locY = np.argmax(mY) # Find its location
frqY = frq[locY] # Get the actual frequency value

# Code from before
plt.subplot(2,1,1)
plt.plot(frq,abs(Y),'r') # plotting the spectrum

# New - Plot the max point
plt.plot(frqY, peakY, 'b.', markersize=18)

# New - Make title reflecting peak information
plt.title('Peak value: %f, Location: %f Hz' % (peakY, frqY))

# Rest of the code is the same
plt.xlabel('Freq (Hz)')
plt.ylabel('|Y(freq)|')
plt.grid('on')
plt.subplot(2,1,2)
plt.plot(x,y)
plt.xlabel('Time (ms)')
plt.ylabel('Angle (degrees)')
plt.grid('on')
plt.show()



回答2:


print("maximum of |Y| is: %.4g" % np.max(np.abs(Y)))

Other suggestions: use array slicing: Y = Y[:n/2+1] rather than Y = Y[range(n/2)]. A Fourier transform of a real-valued data set with n inputs (with n an even number) will have n/2+1 frequency components. Your indexing misses the last point. If n is odd (as in your case), it gets more tricky.

Side note: it would be good to provide a self-contained example with the question, i.e. one that does not depend on a file that is on your computer.



来源:https://stackoverflow.com/questions/37049887/print-highest-peak-value-of-the-frequency-domain-plot

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!