class Bp2DWidget(PlotWidget): def __init__(self): super(Bp2DWidget, self).__init__() # M.B. plot add to params self.setXRange(-60, 60) self.setYRange(-60, 60) self.img = ImageItem() self.addItem(self.img) _translate = QCoreApplication.translate self.setLabels(title=_translate("Bp2DWidget", "Beam pattern"), left=_translate("Bp2DWidget", "Elevation, °"), bottom=_translate("Bp2DWidget", "Azimuth, °")) self.setLogMode() colormap = ColorMap(*zip(*Gradients["bipolar"]["ticks"])) self.img.setLookupTable(colormap.getLookupTable()) #gradient_legend = GradientLegend(10, 10) #self.addItem(gradient_legend) @pyqtSlot() def on_data_changed(self): sender = self.sender() self.img.setImage(np.rot90(sender.data, -1)) self.img.setRect(self.__ensure_rect(np.shape(sender.data))) def __ensure_rect(self, shape): x_offset = 120. / (shape[0]-1) / 2 y_offset = 120. / (shape[1]-1) / 2 return QRectF(-60 - x_offset, 60 + y_offset, 120 + x_offset * 2, -120 - y_offset * 2)
class Image: """requires that parser would initialize self.image_array""" def gen_icon(self): qimage = QImage(self.image_array, self.image_array.shape[1], self.image_array.shape[0], QImage.Format_Grayscale8) self.icon = QIcon(QPixmap(qimage)) def gen_image_item(self, height, width): self.pg_image_item = ImageItem(self.image_array) self.pg_image_item.setRect(QRectF(0, height, width, -height))
def make_pg_image_item(image, extent=None, **kwargs): if image is None: return None image_args = kwargs image_args.setdefault('autoRange', False) image_args.setdefault('autoLevels', False) image_args.setdefault('axisOrder', 'row-major') image_args.setdefault('levels', levels_for(image)) item = ImageItem(image, **image_args) if extent is not None: xmin, xmax, ymin, ymax = extent item.setRect(QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax))) item.setAutoDownsample(True) return item
class PsdWaterfallPlotWidget(GraphicsLayoutWidget): """This class manages and displays the power spectrum distribution (PSD) data in a waterfall plot. Attributes ---------- arraySize : int The size of the data array to display. boundingRect : QtCore.QRectF The actual coordinate space base on frequency and time of acquisition. data : numpy.ndarray The 2D array for the PSD data. image : pyqtgraph.ImageItem The instance of the image item for display. timeScale : float The total time for the buffer to accumulate at the ROI FPS. """ def __init__(self, parent=None): """Initialize the class. Parameters ---------- parent : None, optional Top-level widget. """ super().__init__(parent) self.plot = self.addPlot() self.plot.invertY() self.image = ImageItem() self.image.setOpts(axisOrder='row-major') self.plot.addItem(self.image) self.data = None self.arraySize = None self.boundingRect = None self.timeScale = None self.colorMap = 'viridis' self.image.setLookupTable(getLutFromColorMap(self.colorMap)) def clearPlot(self): """Reset all data and clear the plot. """ self.data = None self.boundingRect = None self.image.clear() def getConfiguration(self): """Get the current plot configuration. Returns ------- int, str The set of current configuration parameters. """ return self.arraySize, self.colorMap def setConfiguration(self, config): """Set the new parameters into the widget. Parameters ---------- config : `config.PsdPlotConfig` The new parameters to apply. """ numBins = config.numWaterfallBins if self.arraySize != numBins: self.arraySize = numBins # Invalidate data self.data = None self.boundingRect = None colorMap = config.waterfallColorMap if self.colorMap != colorMap: self.colorMap = colorMap self.image.setLookupTable(getLutFromColorMap(self.colorMap)) def setTimeScale(self, timeScale): """Update the stored timescale and invalidate data and bounding rect. Parameters ---------- timeScale : float The new timescale. """ self.timeScale = timeScale self.data = None self.boundingRect = None def setup(self, arraySize, timeScale, axisLabel): """Setup the widget with the array size. Parameters ---------- arraySize : int The size fo the data array to display in terms of history. timeScale : float The total time for the buffer to accumulate at the ROI FPS. axisLabel : str Label for particular centroid coordinate. """ self.arraySize = arraySize self.timeScale = timeScale self.plot.setLabel('bottom', '{} {}'.format(axisLabel, HTML_NU), units='Hz') self.plot.setLabel('left', 'Time', units='s') def updatePlot(self, psd, freqs): """Update the current plot with the given data. Parameters ---------- psd : numpy.array The PSD data of a given centroid coordinate. freqs : numpy.array The frequency array associated with the PSD data. """ if self.data is None: self.data = np.zeros((self.arraySize, psd.size)) else: self.data[1:, ...] = self.data[:-1, ...] self.data[0, ...] = np.log(psd) self.image.setImage(self.data) if self.boundingRect is None: self.boundingRect = QtCore.QRectF(0, 0, freqs[-1], self.arraySize * self.timeScale) self.image.setRect(self.boundingRect)