Mike Sr
Mike Sr

Reputation: 543

pyQTGraph set axis values (FFT)

class FFT_Plot():

def __init__(self,
             win,
             nSamples,
             aData,
             sRate,
             wFunction,
             zStart = 0):
    self.nSamples = nSamples    # Number of Sample must be a 2^n power
    self.aData = aData          # Amplitude data array
    self.sRate = sRate          # Sample Rate
    self.wFunction = wFunction  # Windowing Function
    self.zStart = zStart        # Start of Zoom Window if Used
    self.zStop = nSamples/2     # End of Zoom Window if Used
    # Instantiate a plot window within an existing pyQtGraph window.
    self.plot = win.addPlot(title="FFT")
    self.update(aData)
    self.grid_state()

    self.plot.setLabel('left', 'Amplitude', 'Volts')
    self.plot.setLabel('bottom', 'Frequency', 'Hz')

def update(self, aData):
    x = np.fft.fft(aData,)
    amplitude = np.absolute(x)
    fScale = np.linspace(0 , 50000, self.nSamples)
    self.plot.plot(amplitude)
    # Calculate and set-up X axis
    self.plot.setXRange(SampleSize/2, 0)

def grid_state(self, x = True, y = True):
    self.plot.showGrid(x, y)

My problem is fairly simple. How do I change the values displayed along the x and y axis'?

When using 2048 samples and displaying half the samples (0 to samples/2) I get 0 to 1 displayed. It does me no good to calculate the Frequency or Amplitude if I can't display them.

If I change the range I effectively Zoom the spectrum... I've seen some examples but I was quickly lost by the lack of any explanations as to what's going on.

Any help would be appreciated...

As Luke shared... I missed the fact that I could use an 'X' Array. :) The corrected beginners Class is below:

class FFT_Plot():

def __init__(self,
             win,
             nSamples,
             aData,
             sRate,
             wFunction,
             zStart = 0):
    self.nSamples = nSamples    # Number of Sample must be a 2^n power
    self.aData = aData          # Amplitude data array
    self.sRate = sRate          # Sample Rate as Frequency
    self.wFunction = wFunction  # Windowing Function
    self.zStart = zStart        # Start of Zoom Window if Used
    self.zStop = nSamples/2     # End of Zoom Window if Used
    # Instantiate a plot window within an existing pyQtGraph window.
    self.plot = win.addPlot(title="FFT")
    self.update(aData)
    self.grid_state()
    self.plot.setLabel('left', 'Amplitude', 'Volts')
    self.plot.setLabel('bottom', 'Frequency', 'Hz')

def update(self, aData):
    x = np.fft.fft(aData,)
    amplitude = np.absolute(x)
    # Create a linear scale based on the Sample Rate and Number of Samples.
    fScale = np.linspace(0 , self.sRate, self.nSamples)
    self.plot.plot(x = fScale, y = amplitude, pen={'color': (0, 0, 0), 'width': 2})
    # Because the X-axis is now tied to the fScale, which os based on sRate,
    # to set any range limits you must use the sRate.
    self.plot.setXRange(self.sRate/2, 0)

def grid_state(self, x = True, y = True):
    self.plot.showGrid(x, y)

Any DSP types please feel free to add non mathematical comments.

Also, it appears that to get the Y-Axis to read properly the Amplitude array will have to be pre-scaled accordingly.

Upvotes: 1

Views: 3347

Answers (1)

Luke
Luke

Reputation: 11644

In pyqtgraph, the axis values are determined automatically based on the coordinate system of the displayed data. When you call plot() with only the y-values specified, it assumes you want integer x-values like range(len(yValues)). So if you want the x-values of your samples to range from 0 to 50k, you need to provide those values in the call to plot: self.plot.plot(x=fScale, y=amplitude). You should find that the axis values react accordingly.

Upvotes: 2

Related Questions