def update_labels(self): """ Trigger an updaet of labels The method calls `get_labels` which in turn calls the widget's `get_label_data`. The obtained labels are shown if the corresponding points are selected or if `label_only_selected` is `false`. """ for label in self.labels: self.plot_widget.removeItem(label) self.labels = [] if self.scatterplot_item is None \ or self.label_only_selected and self.selection is None: return labels = self.get_labels() if labels is None: return black = pg.mkColor(0, 0, 0) x, y = self.scatterplot_item.getData() if self.label_only_selected: selected = np.nonzero(self._filter_visible(self.selection)) labels = labels[selected] x = x[selected] y = y[selected] for label, xp, yp in zip(labels, x, y): ti = TextItem(label, black) ti.setPos(xp, yp) self.plot_widget.addItem(ti) self.labels.append(ti)
def update_labels(self): """ Trigger an update of labels The method calls `get_labels` which in turn calls the widget's `get_label_data`. The obtained labels are shown if the corresponding points are selected or if `label_only_selected` is `false`. """ for label in self.labels: self.plot_widget.removeItem(label) self.labels = [] if self.scatterplot_item is None \ or self.label_only_selected and self.selection is None: self._signal_too_many_labels(False) return labels = self.get_labels() if labels is None: self._signal_too_many_labels(False) return (x0, x1), (y0, y1) = self.view_box.viewRange() x, y = self.scatterplot_item.getData() mask = np.logical_and(np.logical_and(x >= x0, x <= x1), np.logical_and(y >= y0, y <= y1)) if self.label_only_selected: mask = np.logical_and(mask, self._filter_visible(self.selection) != 0) if mask.sum() > self.MAX_VISIBLE_LABELS: self._signal_too_many_labels(True) return black = pg.mkColor(0, 0, 0) labels = labels[mask] x = x[mask] y = y[mask] for label, xp, yp in zip(labels, x, y): ti = TextItem(label, black) ti.setPos(xp, yp) self.plot_widget.addItem(ti) self.labels.append(ti) self._signal_too_many_labels(False)
def update_labels(self): """ Trigger an update of labels The method calls `get_labels` which in turn calls the widget's `get_label_data`. The obtained labels are shown if the corresponding points are selected or if `label_only_selected` is `false`. """ for label in self.labels: self.plot_widget.removeItem(label) self.labels = [] mask = None if self.scatterplot_item is not None: x, y = self.scatterplot_item.getData() mask = self._label_mask(x, y) if mask is not None: labels = self.get_labels() if labels is None: mask = None self._signal_too_many_labels( mask is not None and mask.sum() > self.MAX_VISIBLE_LABELS) if self._too_many_labels or mask is None or not np.any(mask): return black = pg.mkColor(0, 0, 0) labels = labels[mask] x = x[mask] y = y[mask] for label, xp, yp in zip(labels, x, y): ti = TextItem(label, black) ti.setPos(xp, yp) self.plot_widget.addItem(ti) self.labels.append(ti)
def update_labels(self): """ Trigger an update of labels The method calls `get_labels` which in turn calls the widget's `get_label_data`. The obtained labels are shown if the corresponding points are selected or if `label_only_selected` is `false`. """ for label in self.labels: self.plot_widget.removeItem(label) self.labels = [] mask = None if self.scatterplot_item is not None: x, y = self.scatterplot_item.getData() mask = self._label_mask(x, y) if mask is not None: labels = self.get_labels() if labels is None: mask = None self._signal_too_many_labels(mask is not None and mask.sum() > self.MAX_VISIBLE_LABELS) if self._too_many_labels or mask is None or not np.any(mask): return black = pg.mkColor(0, 0, 0) labels = labels[mask] x = x[mask] y = y[mask] for label, xp, yp in zip(labels, x, y): ti = TextItem(label, black) ti.setPos(xp, yp) self.plot_widget.addItem(ti) self.labels.append(ti)
def create_labels(self): for x, y in zip(*self.scatterplot_item.getData()): ti = TextItem() self.plot_widget.addItem(ti) ti.setPos(x, y) self.labels.append(ti)
def plotData(self): offset = 0 lastAutoRangeState = self._graphicsView.vb.getState()['autoRange'] self._graphicsView.disableAutoRange(ViewBox.XYAxes) if self.lastEnabledChannels and self.lastEnabledChannels != self.signalTableModel.enabledList: for curve in concatenate_iter(self.curveBundle, self.curveAuxBundle, self.curveTriggerBundle, self.curveGateBundle): if curve: self._graphicsView.removeItem(curve) self.curveBundle = None self.curveAuxBundle = None self.curveTriggerBundle = None self.curveGateBundle = None if self.textItems: for item in self.textItems: self._graphicsView.removeItem(item) if self.yDataBundle: if self.curveBundle is None: self.curveBundle = list() for i, yData in enumerate(self.yDataBundle): if yData: curve = PlotCurveItem(self.xData, yData, stepMode=True, fillLevel=offset, brush=penList[1][4], pen=penList[1][0]) self._graphicsView.addItem(curve) self.curveBundle.append(curve) textItem = TextItem( self.signalTableModel.primaryChannelName(i), anchor=(1, 1), color=(0, 0, 0)) textItem.setPos(0, offset) self._graphicsView.addItem(textItem) self.textItems.append(textItem) offset += 1 else: self.curveBundle.append(None) else: for curve, yData in zip(self.curveBundle, self.yDataBundle): if yData: if curve: curve.setData(x=self.xData, y=yData) nextChannel = self.settings.numChannels if self.yAuxDataBundle: if self.curveAuxBundle is None: self.curveAuxBundle = list() for i, yAuxData in enumerate(self.yAuxDataBundle): if yAuxData: curve = PlotCurveItem(self.xAuxData, yAuxData, stepMode=True, fillLevel=offset, brush=penList[2][4], pen=penList[2][0]) self._graphicsView.addItem(curve) self.curveAuxBundle.append(curve) textItem = TextItem( self.signalTableModel.auxChannelName(i), anchor=(1, 1), color=(0, 0, 0)) textItem.setPos(0, offset) self._graphicsView.addItem(textItem) self.textItems.append(textItem) offset += 1 else: self.curveAuxBundle.append(None) else: for curve, yAuxData in zip(self.curveAuxBundle, self.yAuxDataBundle): if yAuxData: if curve: curve.setData(x=self.xAuxData, y=yAuxData) nextChannel += self.settings.numAuxChannels if self.yTriggerBundle: if self.curveTriggerBundle is None: self.curveTriggerBundle = list() for i, yTrigger in enumerate(self.yTriggerBundle): if yTrigger: curve = PlotCurveItem(self.xTrigger, yTrigger, stepMode=True, fillLevel=offset, brush=penList[3][4], pen=penList[3][0]) self._graphicsView.addItem(curve) self.curveTriggerBundle.append(curve) textItem = TextItem( self.signalTableModel.triggerChannelName(i), anchor=(1, 1), color=(0, 0, 0)) textItem.setPos(0, offset) self._graphicsView.addItem(textItem) self.textItems.append(textItem) offset += 1 else: self.curveTriggerBundle.append(None) else: for curve, yTrigger in zip(self.curveTriggerBundle, self.yTriggerBundle): if yTrigger: if curve: curve.setData(x=self.xTrigger, y=yTrigger) nextChannel = self.settings.numTriggerChannels if self.yGateDataBundle: if self.curveGateBundle is None: self.curveGateBundle = list() for i, yGateData in enumerate(self.yGateDataBundle): if yGateData: curve = PlotCurveItem(self.xGateData, yGateData, stepMode=True, fillLevel=offset, brush=penList[2][4], pen=penList[2][0]) self._graphicsView.addItem(curve) self.curveGateBundle.append(curve) textItem = TextItem( self.signalTableModel.gateChannelName(i), anchor=(1, 1), color=(0, 0, 0)) textItem.setPos(0, offset) self._graphicsView.addItem(textItem) self.textItems.append(textItem) offset += 1 else: self.curveGateBundle.append(None) else: for curve, yGateData in zip(self.curveGateBundle, self.yGateDataBundle): if yGateData: if curve: curve.setData(x=self.xGateData, y=yGateData) self.lastEnabledChannels = list(self.signalTableModel.enabledList) xautorange, yautorange = lastAutoRangeState if xautorange: self._graphicsView.enableAutoRange(ViewBox.XAxis) if yautorange: self._graphicsView.enableAutoRange(ViewBox.YAxis) self._graphicsView.autoRange()
class FftGraph: """ """ def __init__(self, gv, layout): self.gv = gv self.curve_freq = [] self.layout = layout self.dock_area = DockArea() layout.addWidget(self.dock_area, 1, 0, 1, 8) # Plot self.plot_d = self.init_plot_dock() self.plot = self.init_plot() self.add_regions_filter_to_plot() self.connect_classif_region() # Settings self.create_settings_dock() # Filter settings self.filter_d = self.create_filter_settings_dock() self.init_filters() self.timer = self.init_timer() def init_plot_dock(self): plot_d = InnerDock(self.layout, 'plot') self.dock_area.addDock(plot_d.dock) return plot_d def init_timer(self): timer = QtCore.QTimer() timer.timeout.connect(self.update_plotting) return timer def init_plot(self): """Create the plot widget and its characteristics""" plot = pg.PlotWidget(background=dark_grey) plot.plotItem.showGrid(x=True, y=True, alpha=0.3) plot.plotItem.setLabel(axis='bottom', text='Frequency', units='Hz') # TODO: ALEXM : verifier l'uniter plot.plotItem.setLabel(axis='left', text='Amplitude', units='None') plot.setXRange(0, 130) plot.setYRange(0, 1000000) # Add to tab layout self.plot_d.layout.addWidget(plot, 2, 0, 5, 5) for ch in range(self.gv.N_CH): self.curve_freq.append( plot.plot( deque(np.ones(self.gv.DEQUE_LEN), maxlen=self.gv.DEQUE_LEN))) self.curve_freq[ch].setPen(pen_colors[ch]) self.gv.curve_freq = self.curve_freq return plot def add_param_tree(self): self.ptree = ptree.ParameterTree(showHeader=False) self.filter = DataFilterParameter() params = ptree.Parameter.create(name='params', type='group', children=[self.filter]) self.ptree.setParameters(params, showTop=False) self.filter_layout.addWidget(self.ptree) self.filterText = TextItem(border=getConfigOption('foreground')) self.filterText.setPos(60, 20) self.filterText.setParentItem(self.plot.plotItem) self.filter.sigFilterChanged.connect(self.filterChanged) self.filter.setFields([('butterFilter', {'units': 'Hz'})]) def filterChanged(self): print('cool') def add_regions_filter_to_plot(self): """Add a region to the plot that will be use as the bondaries for the filter (blue for pass and red for cut)""" # Band pass filter self.pass_f_region = pg.LinearRegionItem([ self.gv.min_pass_filter, self.gv.max_pass_filter ]) # TODO: ALEXM: avoid redondancy in the creation of filters self.pass_f_region.setBrush(blue) self.plot.addItem(self.pass_f_region, ignoreBounds=True) # Band cut filter self.cut_f_region = pg.LinearRegionItem( [self.gv.min_cut_filter, self.gv.max_cut_filter]) self.cut_f_region.setBrush(red) self.plot.addItem(self.cut_f_region, ignoreBounds=True) def connect_classif_region(self): self.pass_f_region.sigRegionChanged.connect( partial(self.update_pass_filter_region)) self.cut_f_region.sigRegionChanged.connect( partial(self.update_cut_filter_region)) def update_pass_filter_region(self): self.gv.min_pass_filter, self.gv.max_pass_filter = \ self.pass_f_region.getRegion() def update_cut_filter_region(self): self.gv.min_cut_filter, self.gv.max_cut_filter = \ self.cut_f_region.getRegion() def update_plotting(self): self.all_frequency() def all_frequency(self): for ch in range(self.gv.N_CH): f_range, fft = self.gv.freq_calculator.get_fft_to_plot( np.array(self.gv.data_queue[ch]) [self.gv.filter_min_bound:self.gv.filter_max_bound]) self.curve_freq[ch].setData(f_range, fft) # self.curve_freq[ch].setData( # self.gv.freq_calculator.freq_range, # self.gv.freq_calculator.fft[ch]) # TODO: ALEXM prendre abs ou real? avec real il y a des valeurs negatives est-ce que c'est normal? def init_on_off_button(self, layout): btn('Start', layout, (0, 0), func_conn=self.start, color=dark_blue_tab, toggle=True, txt_color=white, min_width=100) def create_settings_dock(self): settings_d = InnerDock(self.layout, 'Settings', toggle_button=True, size=(1, 1)) self.init_on_off_button(settings_d.layout) create_param_combobox(settings_d.layout, 'Max Freq', (0, 1), ['Auto', '60 Hz', '80 Hz', '100 Hz', '120 Hz'], partial(self.scale_axis, axis_name='x')) create_param_combobox(settings_d.layout, 'Max Uv', (0, 2), [ 'Auto', '1000 uv', '10000 uv', '100000 uv', '1000000 uv', '10000000 uv' ], partial(self.scale_axis, axis_name='y')) create_param_combobox(settings_d.layout, 'Log', (0, 3), ['False', 'True'], self.log_axis) create_param_combobox(settings_d.layout, 'Filter', (0, 4), ['No filter', 'Bandpass', 'Bandstop', 'Both'], self.show_filter) self.combo_to_filter = { 'No filter': [], 'Bandpass': ['bandpass'], 'Bandstop': ['bandstop'], 'Both': ['bandpass', 'bandstop'] } create_param_combobox( settings_d.layout, 'Ch On', (0, 5), ['ch 1', 'ch 2', 'ch 3', 'ch 4', 'ch 5', 'ch 6', 'ch 7', 'ch 8'], self.ch_on_off, editable=False) self.dock_area.addDock(settings_d.dock, 'top') def create_filter_settings_dock(self): filter_d = InnerDock(self.layout, 'Filter', toggle_button=True, size=(1, 1), b_pos=(0, 1), b_checked=False) self.dock_area.addDock(filter_d.dock, 'right') filter_d.dock.hide() return filter_d def init_filters(self): ## Create flowchart, define input/output terminals fc = Flowchart(terminals={ 'dataIn': { 'io': 'in' }, 'dataOut': { 'io': 'out' } }) ## Add flowchart control panel to the main window self.filter_d.layout.addWidget(fc.widget(), 0, 0, 2, 1) ## Add two plot widgets pw1 = pg.PlotWidget() pw2 = pg.PlotWidget() self.filter_d.layout.addWidget(pw1, 0, 1) self.filter_d.layout.addWidget(pw2, 1, 1) ## generate signal data to pass through the flowchart data = np.random.normal(size=1000) data[200:300] += 1 data += np.sin(np.linspace(0, 100, 1000)) data = metaarray.MetaArray(data, info=[{ 'name': 'Time', 'values': np.linspace(0, 1.0, len(data)) }, {}]) ## Feed data into the input terminal of the flowchart fc.setInput(dataIn=data) ## populate the flowchart with a basic set of processing nodes. ## (usually we let the user do this) plotList = {'Top Plot': pw1, 'Bottom Plot': pw2} pw1Node = fc.createNode('PlotWidget', pos=(0, -150)) pw1Node.setPlotList(plotList) pw1Node.setPlot(pw1) pw2Node = fc.createNode('PlotWidget', pos=(150, -150)) pw2Node.setPlot(pw2) pw2Node.setPlotList(plotList) fNode = fc.createNode('GaussianFilter', pos=(0, 0)) fNode.ctrls['sigma'].setValue(5) fc.connectTerminals(fc['dataIn'], fNode['In']) fc.connectTerminals(fc['dataIn'], pw1Node['In']) fc.connectTerminals(fNode['Out'], pw2Node['In']) fc.connectTerminals(fNode['Out'], fc['dataOut']) def scale_axis(self, txt, axis_name): try: if txt == 'Auto': self.plot.enableAutoRange() else: r = int(re.search(r'\d+', txt).group()) if axis_name == 'x': self.plot.setXRange(0, r) elif axis_name == 'y': self.plot.setYRange(0, r) except AttributeError: print("Come on bro, this value doesn't make sens") def log_axis(self, txt): self.plot.setLogMode(y=eval(txt)) def ch_on_off(self): pass def show_filter(self, txt): self.gv.filter_to_use = self.combo_to_filter[txt] @QtCore.pyqtSlot(bool) def start(self, checked): if checked: if not self.gv.freq_calculator.activated: self.gv.freq_calculator.timer.start(100) self.gv.freq_calculator.activated = True self.timer.start(100) else: self.timer.stop() self.gv.freq_calculator.timer.stop() self.gv.freq_calculator.activated = False
def plotData(self): offset = 0 lastAutoRangeState = self._graphicsView.vb.getState()['autoRange'] self._graphicsView.disableAutoRange(ViewBox.XYAxes) if self.lastEnabledChannels and self.lastEnabledChannels!=self.signalTableModel.enabledList: for curve in concatenate_iter(self.curveBundle, self.curveAuxBundle, self.curveTriggerBundle, self.curveGateBundle): if curve: self._graphicsView.removeItem(curve) self.curveBundle = None self.curveAuxBundle = None self.curveTriggerBundle = None self.curveGateBundle = None if self.textItems: for item in self.textItems: self._graphicsView.removeItem(item) if self.yDataBundle: if self.curveBundle is None: self.curveBundle = list() for i, yData in enumerate(self.yDataBundle): if yData: curve = PlotCurveItem(self.xData, yData, stepMode=True, fillLevel=offset, brush=penList[1][4], pen=penList[1][0]) self._graphicsView.addItem( curve ) self.curveBundle.append( curve ) textItem = TextItem( self.signalTableModel.primaryChannelName(i), anchor=(1, 1), color=(0, 0, 0) ) textItem.setPos( 0, offset ) self._graphicsView.addItem(textItem) self.textItems.append(textItem) offset += 1 else: self.curveBundle.append( None ) else: for curve, yData in zip(self.curveBundle, self.yDataBundle): if yData: if curve: curve.setData(x=self.xData, y=yData) nextChannel = self.settings.numChannels if self.yAuxDataBundle: if self.curveAuxBundle is None: self.curveAuxBundle = list() for i, yAuxData in enumerate(self.yAuxDataBundle): if yAuxData: curve = PlotCurveItem(self.xAuxData, yAuxData, stepMode=True, fillLevel=offset, brush=penList[2][4], pen=penList[2][0]) self._graphicsView.addItem( curve ) self.curveAuxBundle.append( curve ) textItem = TextItem( self.signalTableModel.auxChannelName(i), anchor=(1, 1), color=(0, 0, 0) ) textItem.setPos( 0, offset ) self._graphicsView.addItem(textItem) self.textItems.append(textItem) offset += 1 else: self.curveAuxBundle.append( None ) else: for curve, yAuxData in zip(self.curveAuxBundle, self.yAuxDataBundle): if yAuxData: if curve: curve.setData(x=self.xAuxData, y=yAuxData) nextChannel += self.settings.numAuxChannels if self.yTriggerBundle: if self.curveTriggerBundle is None: self.curveTriggerBundle = list() for i, yTrigger in enumerate(self.yTriggerBundle): if yTrigger: curve = PlotCurveItem(self.xTrigger, yTrigger, stepMode=True, fillLevel=offset, brush=penList[3][4], pen=penList[3][0]) self._graphicsView.addItem( curve ) self.curveTriggerBundle.append( curve ) textItem = TextItem( self.signalTableModel.triggerChannelName(i), anchor=(1, 1), color=(0, 0, 0) ) textItem.setPos( 0, offset ) self._graphicsView.addItem(textItem) self.textItems.append(textItem) offset += 1 else: self.curveTriggerBundle.append( None ) else: for curve, yTrigger in zip(self.curveTriggerBundle, self.yTriggerBundle): if yTrigger: if curve: curve.setData(x=self.xTrigger, y=yTrigger) nextChannel = self.settings.numTriggerChannels if self.yGateDataBundle: if self.curveGateBundle is None: self.curveGateBundle = list() for i, yGateData in enumerate(self.yGateDataBundle): if yGateData: curve = PlotCurveItem(self.xGateData, yGateData, stepMode=True, fillLevel=offset, brush=penList[2][4], pen=penList[2][0]) self._graphicsView.addItem( curve ) self.curveGateBundle.append( curve ) textItem = TextItem( self.signalTableModel.gateChannelName(i), anchor=(1, 1), color=(0, 0, 0) ) textItem.setPos( 0, offset ) self._graphicsView.addItem(textItem) self.textItems.append(textItem) offset += 1 else: self.curveGateBundle.append( None ) else: for curve, yGateData in zip(self.curveGateBundle, self.yGateDataBundle): if yGateData: if curve: curve.setData(x=self.xGateData, y=yGateData) self.lastEnabledChannels = list( self.signalTableModel.enabledList ) xautorange, yautorange = lastAutoRangeState if xautorange: self._graphicsView.enableAutoRange(ViewBox.XAxis) if yautorange: self._graphicsView.enableAutoRange(ViewBox.YAxis) self._graphicsView.autoRange()
class Application(QObject, Ui_mainWindow): def __init__(self, mainWindow: QMainWindow): super().__init__() self.mainWindow = mainWindow self.userId: int = 0 self.dbFile: str = "" self.setupUi() mainWindow.show() def setupUi(self): super().setupUi(self.mainWindow) self.createMediaPlayer() self.createGraphWidget() self.pickDirectory.clicked.connect(self.pickVideoClick) self.exitApplication.clicked.connect(self.mainWindow.close) self.showDataBase.clicked.connect(self.pickDataBaseClick) self.clearScene.clicked.connect(self.graphicsView.scene().clearSelection) self.playButton.clicked.connect(self.playButtonClicked) self.mediaDurationSlider.sliderMoved.connect(self.mediaPlayer.setPosition) self.graphicsView.scene().regionSelected.connect(self.displayGraph) def createMediaPlayer(self): self.mediaPlayer = SeqPlayer(self.mainWindow) self.mediaPlayer.setVideoOutput(self.graphicsView.scene().videoItem) self.mediaPlayer.videoAvailableChanged.connect(self.playButton.setEnabled) self.mediaPlayer.videoAvailableChanged.connect( self.mediaDurationSlider.setEnabled ) self.mediaPlayer.stateChanged.connect(self.mediaPlayerStateChanged) self.mediaPlayer.durationChanged.connect(self.durationChanged) self.mediaPlayer.positionChanged.connect(self.mediaDurationSlider.setValue) self.mediaPlayer.positionChanged.connect(self.displayCurrentTemperature) self.mediaPlayerStateChanged(QMediaPlayer.StoppedState) def createGraphWidget(self): plotWidget = pg.PlotWidget() self.graphLayout.addWidget(plotWidget) self.plotItem = plotWidget.getPlotItem() self.plotItem.showGrid(x=True, y=True) self.plotItem.setLabel("left", "Średnia temperatura [°C]") self.plotItem.setLabel("bottom", "Czas [s]") self.plot = self.plotItem.plot() self.plotCurrent = self.plotItem.plot( symbol="o", symbolPen=(0, 122, 217), symbolBrush=(0, 122, 217) ) self.currentLabel = TextItem("cell", (255, 255, 255), anchor=(0, 0)) @Slot() def pickVideoClick(self): filePath, _ = QFileDialog.getOpenFileName( self.mainWindow, "Otwórz plik", "", "SEQ files (*.seq);;IMG files (*.img)" ) if filePath: self.videoPath = pathlib.Path(filePath) self.userId = self.videoPath.stem[0:2] self.mediaPlayer.setFile(self.videoPath) self.graphicsView.scene().clearSelection() self.displayUserData() self.mediaPlayer.play() @Slot() def playButtonClicked(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() @Slot(int) def durationChanged(self, duration: int): self.mediaDurationSlider.setMaximum(duration - 1) @Slot(QMediaPlayer.State) def mediaPlayerStateChanged(self, state: QMediaPlayer.PlayingState): if state == QMediaPlayer.PlayingState: buttonText = "Pause" buttonIcon = QStyle.SP_MediaPause else: buttonText = "Play" buttonIcon = QStyle.SP_MediaPlay self.playButton.setText(buttonText) self.playButton.setIcon(self.playButton.style().standardIcon(buttonIcon)) @Slot(int) def displayCurrentTemperature(self, position: int): temperature = self.values[position] self.plotCurrent.setData([position], [temperature]) self.currentLabel.setPos(position, temperature) self.currentLabel.setText(f"{position}, {temperature:.2f}") if self.currentLabel not in self.plotItem.items: self.plotItem.addItem(self.currentLabel) @Slot(QRect) def displayGraph(self, selection: QRect): reader = self.mediaPlayer.reader() if not reader: logging.error("Video not available") self.values = [] for frame_number in range(reader.num_frames): frame = reader.frame(frame_number) temperatures = frame.data if not selection.isEmpty(): temperatures = temperatures[ selection.top() : selection.bottom(), selection.left() : selection.right(), ] self.values.append(numpy.average(temperatures)) self.plot.setData(self.values) self.displayCurrentTemperature(self.mediaPlayer.position()) self.plotItem.getViewBox().autoRange(padding=0.11) self.plotItem.getViewBox().setRange(xRange=(-10, reader.num_frames * 1.12)) def getSurveyResults(self, userId: int): with sqlite3.connect(self.dbFile) as connection: connection.row_factory = sqlite3.Row cursor = connection.cursor() return cursor.execute( "SELECT * FROM Ankieta WHERE Id=?", (userId,) ).fetchall() @Slot() def pickDataBaseClick(self): dbFile, _ = QFileDialog.getOpenFileName( self.mainWindow, "Otwórz bazę danych", "", "Database files (*.db)" ) if dbFile: self.dbFile = dbFile self.displayUserData() def displayUserData(self): if not self.dbFile: self.userData.setText("Otwórz plik bazy danych") elif not self.userId: self.userData.setText("Załaduj plik z obrazem") else: try: surveyResults = self.getSurveyResults(self.userId) if surveyResults: self.displaySurveyResults(surveyResults[0]) else: self.userData.setText( dedent( f"""\ Brak pasującego wyniku w bazie danych dla użytkownika o ID "{self.userId}" (dwa pierwsze znaki nazwy pliku wideo) """ ) ) except Exception as e: self.userData.setText(f"Nie udało się otworzyć bazy danych:\n {e}") def displaySurveyResults(self, userData): self.userData.setHtml( dedent( f""" <p> <b>Id:</b> {userData['Id']}<br /> <b>Płeć:</b> {userData['Plec']}<br /> <b>Wiek:</b> {userData['Wiek']}<br /> <b>Województwo zamieszkania:</b> {userData['Wojewodztwo']}<br /> <b>Jak często marzną dłonie/stopy:</b> {userData['Marzniecie']}<br /> <b>Jak często bieleją lub sinieją dłonie/stopy:</b> {userData['Sinienie']}<br /> <b>Jak często bierze zimne kąpiele:</b> {userData['ZimneKapiele']}<br /> <b>Jak często morsuje:</b> {userData['Morsowanie']}<br /> <b>Choroby:</b> {userData['Choroby']}<br /> <b>Przyjmowane leki:</b> {userData['Leki']}<br /> </p> <b>Temperatura badanego:</b> {userData['TempBadanego']} °C <br /> <b>Tetno początkowe badanego:</b> {userData['TetnoPoczatkowe']}/min <br /> <b>Ciśnienie początkowe badanego:</b> {userData['CisSkurczPoczatkowe']}/{userData['CisRozkurczPoczatkowe']} mmHg <br /> <b>Temperatura wody przed pierwszym badaniem:</b> {userData['TempWodyDo1Badania']} °C <br /> <b>Tętno po pierwszym badaniu:</b> {userData['TetnoPo1Badaniu']}/min <br /> <b>Ciśnienie po pierwszym badaniu:</b> {userData['CisSkurczPo1Badaniu']}/{userData['CisRozkurczPo1Badaniu']} mmHg <br /> <b>Temperatura wody przed drugim badaniem:</b> {userData['TempWodyDo2Badania']} °C <br /> <b>Tętno po drugim badaniu:</b> {userData['TetnoPo2Badaniu']}/min <br /> <b>Ciśnienie po drugim badaniu:</b> {userData['CisSkurczPo2Badaniu']}/{userData['CisRozkurczPo2Badaniu']} mmHg <br /> """ ) )
class OWScatterPlotGraph(gui.OWComponent, ScaleScatterPlotData): attr_color = ContextSetting("", ContextSetting.OPTIONAL) attr_label = ContextSetting("", ContextSetting.OPTIONAL) attr_shape = ContextSetting("", ContextSetting.OPTIONAL) attr_size = ContextSetting("", ContextSetting.OPTIONAL) point_width = Setting(10) alpha_value = Setting(255) show_grid = Setting(False) show_legend = Setting(True) tooltip_shows_all = Setting(False) square_granularity = Setting(3) space_between_cells = Setting(True) CurveSymbols = np.array("o x t + d s ?".split()) MinShapeSize = 6 DarkerValue = 120 UnknownColor = (168, 50, 168) def __init__(self, scatter_widget, parent=None, _="None"): gui.OWComponent.__init__(self, scatter_widget) self.view_box = InteractiveViewBox(self) self.plot_widget = pg.PlotWidget(viewBox=self.view_box, parent=parent) self.plot_widget.setAntialiasing(True) self.replot = self.plot_widget ScaleScatterPlotData.__init__(self) self.scatterplot_item = None self.tooltip_data = [] self.tooltip = TextItem( border=pg.mkPen(200, 200, 200), fill=pg.mkBrush(250, 250, 200, 220)) self.tooltip.hide() self.labels = [] self.master = scatter_widget self.shown_attribute_indices = [] self.shown_x = "" self.shown_y = "" self.pen_colors = self.brush_colors = None self.valid_data = None # np.ndarray self.selection = None # np.ndarray self.n_points = 0 self.gui = OWPlotGUI(self) self.continuous_palette = ContinuousPaletteGenerator( QColor(255, 255, 0), QColor(0, 0, 255), True) self.discrete_palette = ColorPaletteGenerator() self.selection_behavior = 0 self.legend = self.color_legend = None self.scale = None # DiscretizedScale self.tips = TooltipManager(self) # self.setMouseTracking(True) # self.grabGesture(QPinchGesture) # self.grabGesture(QPanGesture) self.update_grid() def set_data(self, data, subset_data=None, **args): self.plot_widget.clear() ScaleScatterPlotData.set_data(self, data, subset_data, **args) def update_data(self, attr_x, attr_y): self.shown_x = attr_x self.shown_y = attr_y self.remove_legend() if self.scatterplot_item: self.plot_widget.removeItem(self.scatterplot_item) for label in self.labels: self.plot_widget.removeItem(label) self.labels = [] self.tooltip_data = [] self.set_axis_title("bottom", "") self.set_axis_title("left", "") if self.scaled_data is None or not len(self.scaled_data): self.valid_data = None self.n_points = 0 return index_x = self.attribute_name_index[attr_x] index_y = self.attribute_name_index[attr_y] self.valid_data = self.get_valid_list([index_x, index_y]) x_data, y_data = self.get_xy_data_positions( attr_x, attr_y, self.valid_data) x_data = x_data[self.valid_data] y_data = y_data[self.valid_data] self.n_points = len(x_data) for axis, name, index in (("bottom", attr_x, index_x), ("left", attr_y, index_y)): self.set_axis_title(axis, name) var = self.data_domain[index] if isinstance(var, DiscreteVariable): self.set_labels(axis, get_variable_values_sorted(var)) color_data, brush_data = self.compute_colors() size_data = self.compute_sizes() shape_data = self.compute_symbols() self.scatterplot_item = ScatterPlotItem( x=x_data, y=y_data, data=np.arange(self.n_points), symbol=shape_data, size=size_data, pen=color_data, brush=brush_data) self.plot_widget.addItem(self.scatterplot_item) self.plot_widget.addItem(self.tooltip) self.scatterplot_item.selected_points = [] self.scatterplot_item.sigClicked.connect(self.select_by_click) self.scatterplot_item.scene().sigMouseMoved.connect(self.mouseMoved) self.update_labels() self.make_legend() self.plot_widget.replot() def set_labels(self, axis, labels): axis = self.plot_widget.getAxis(axis) if labels: ticks = [[(i, labels[i]) for i in range(len(labels))]] axis.setTicks(ticks) else: axis.setTicks(None) def set_axis_title(self, axis, title): self.plot_widget.setLabel(axis=axis, text=title) def get_size_index(self): size_index = -1 attr_size = self.attr_size if attr_size != "" and attr_size != "(Same size)": size_index = self.attribute_name_index[attr_size] return size_index def compute_sizes(self): size_index = self.get_size_index() if size_index == -1: size_data = np.full((self.n_points,), self.point_width) else: size_data = \ self.MinShapeSize + \ self.no_jittering_scaled_data[size_index] * self.point_width size_data[np.isnan(size_data)] = self.MinShapeSize - 2 return size_data def update_sizes(self): if self.scatterplot_item: size_data = self.compute_sizes() self.scatterplot_item.setSize(size_data) update_point_size = update_sizes def get_color_index(self): color_index = -1 attr_color = self.attr_color if attr_color != "" and attr_color != "(Same color)": color_index = self.attribute_name_index[attr_color] color_var = self.data_domain[attr_color] if isinstance(color_var, DiscreteVariable): self.discrete_palette.set_number_of_colors( len(color_var.values)) return color_index def compute_colors(self, keep_colors=False): if not keep_colors: self.pen_colors = self.brush_colors = None color_index = self.get_color_index() if color_index == -1: color = self.plot_widget.palette().color(OWPalette.Data) pen = [QPen(QBrush(color), 1.5)] * self.n_points if self.selection is not None: brush = [(QBrush(QColor(128, 128, 128, 255)), QBrush(QColor(128, 128, 128)))[s] for s in self.selection] else: brush = [QBrush(QColor(128, 128, 128))] * self.n_points return pen, brush c_data = self.original_data[color_index, self.valid_data] if isinstance(self.data_domain[color_index], ContinuousVariable): if self.pen_colors is None: self.scale = DiscretizedScale(np.min(c_data), np.max(c_data)) c_data -= self.scale.offset c_data /= self.scale.width c_data = np.floor(c_data) + 0.5 c_data /= self.scale.bins c_data = np.clip(c_data, 0, 1) palette = self.continuous_palette self.pen_colors = palette.getRGB(c_data) self.brush_colors = np.hstack( [self.pen_colors, np.full((self.n_points, 1), self.alpha_value)]) self.pen_colors *= 100 / self.DarkerValue self.pen_colors = [QPen(QBrush(QColor(*col)), 1.5) for col in self.pen_colors.tolist()] if self.selection is not None: self.brush_colors[:, 3] = 0 self.brush_colors[self.selection, 3] = self.alpha_value else: self.brush_colors[:, 3] = self.alpha_value pen = self.pen_colors brush = np.array([QBrush(QColor(*col)) for col in self.brush_colors.tolist()]) else: if self.pen_colors is None: palette = self.discrete_palette n_colors = palette.number_of_colors c_data = c_data.copy() c_data[np.isnan(c_data)] = n_colors c_data = c_data.astype(int) colors = palette.getRGB(np.arange(n_colors + 1)) colors[n_colors] = (128, 128, 128) pens = np.array( [QPen(QBrush(QColor(*col).darker(self.DarkerValue)), 1.5) for col in colors]) self.pen_colors = pens[c_data] self.brush_colors = np.array([ [QBrush(QColor(0, 0, 0, 0)), QBrush(QColor(col[0], col[1], col[2], self.alpha_value))] for col in colors]) self.brush_colors = self.brush_colors[c_data] if self.selection is not None: brush = np.where( self.selection, self.brush_colors[:, 1], self.brush_colors[:, 0]) else: brush = self.brush_colors[:, 1] pen = self.pen_colors return pen, brush def update_colors(self, keep_colors=False): if self.scatterplot_item: pen_data, brush_data = self.compute_colors(keep_colors) self.scatterplot_item.setPen(pen_data, update=False, mask=None) self.scatterplot_item.setBrush(brush_data, mask=None) if not keep_colors: self.make_legend() update_alpha_value = update_colors def create_labels(self): for x, y in zip(*self.scatterplot_item.getData()): ti = TextItem() self.plot_widget.addItem(ti) ti.setPos(x, y) self.labels.append(ti) def update_labels(self): if not self.attr_label: for label in self.labels: label.setText("") return if not self.labels: self.create_labels() label_column = self.raw_data.get_column_view(self.attr_label)[0] formatter = self.raw_data.domain[self.attr_label].str_val label_data = map(formatter, label_column) black = pg.mkColor(0, 0, 0) for label, text in zip(self.labels, label_data): label.setText(text, black) def get_shape_index(self): shape_index = -1 attr_shape = self.attr_shape if attr_shape and attr_shape != "(Same shape)" and \ len(self.data_domain[attr_shape].values) <= \ len(self.CurveSymbols): shape_index = self.attribute_name_index[attr_shape] return shape_index def compute_symbols(self): shape_index = self.get_shape_index() if shape_index == -1: shape_data = self.CurveSymbols[np.zeros(self.n_points, dtype=int)] else: shape_data = self.original_data[shape_index] shape_data[np.isnan(shape_data)] = len(self.CurveSymbols) - 1 shape_data = self.CurveSymbols[shape_data.astype(int)] return shape_data def update_shapes(self): if self.scatterplot_item: shape_data = self.compute_symbols() self.scatterplot_item.setSymbol(shape_data) self.make_legend() def update_grid(self): self.plot_widget.showGrid(x=self.show_grid, y=self.show_grid) def update_legend(self): if self.legend: self.legend.setVisible(self.show_legend) def create_legend(self): self.legend = PositionedLegendItem(self.plot_widget.plotItem, self) def remove_legend(self): if self.legend: self.legend.setParent(None) self.legend = None if self.color_legend: self.color_legend.setParent(None) self.color_legend = None def make_legend(self): self.remove_legend() self.make_color_legend() self.make_shape_legend() self.update_legend() def make_color_legend(self): color_index = self.get_color_index() if color_index == -1: return color_var = self.data_domain[color_index] use_shape = self.get_shape_index() == color_index if isinstance(color_var, DiscreteVariable): if not self.legend: self.create_legend() palette = self.discrete_palette for i, value in enumerate(color_var.values): color = QColor(*palette.getRGB(i)) brush = color.lighter(self.DarkerValue) self.legend.addItem( ScatterPlotItem( pen=color, brush=brush, size=10, symbol=self.CurveSymbols[i] if use_shape else "o"), value) else: legend = self.color_legend = PositionedLegendItem( self.plot_widget.plotItem, self, legend_id="colors", at_bottom=True) label = PaletteItemSample(self.continuous_palette, self.scale) legend.addItem(label, "") legend.setGeometry(label.boundingRect()) def make_shape_legend(self): shape_index = self.get_shape_index() if shape_index == -1 or shape_index == self.get_color_index(): return if not self.legend: self.create_legend() shape_var = self.data_domain[shape_index] color = self.plot_widget.palette().color(OWPalette.Data) pen = QPen(color.darker(self.DarkerValue)) color.setAlpha(self.alpha_value) for i, value in enumerate(shape_var.values): self.legend.addItem( ScatterPlotItem(pen=pen, brush=color, size=10, symbol=self.CurveSymbols[i]), value) # noinspection PyPep8Naming def mouseMoved(self, pos): act_pos = self.scatterplot_item.mapFromScene(pos) points = self.scatterplot_item.pointsAt(act_pos) text = "" if len(points): for i, p in enumerate(points): index = p.data() text += "Attributes:\n" if self.tooltip_shows_all: text += "".join( ' {} = {}\n'.format(attr.name, self.raw_data[index][attr]) for attr in self.data_domain.attributes) else: text += ' {} = {}\n {} = {}\n'.format( self.shown_x, self.raw_data[index][self.shown_x], self.shown_y, self.raw_data[index][self.shown_y]) if self.data_domain.class_var: text += 'Class:\n {} = {}\n'.format( self.data_domain.class_var.name, self.raw_data[index][self.raw_data.domain.class_var]) if i < len(points) - 1: text += '------------------\n' self.tooltip.setText(text, color=(0, 0, 0)) self.tooltip.setPos(act_pos) self.tooltip.show() self.tooltip.setZValue(10) else: self.tooltip.hide() def zoom_button_clicked(self): self.scatterplot_item.getViewBox().setMouseMode( self.scatterplot_item.getViewBox().RectMode) def pan_button_clicked(self): self.scatterplot_item.getViewBox().setMouseMode( self.scatterplot_item.getViewBox().PanMode) def select_button_clicked(self): self.scatterplot_item.getViewBox().setMouseMode( self.scatterplot_item.getViewBox().RectMode) def reset_button_clicked(self): self.view_box.autoRange() def select_by_click(self, _, points): self.select(points) def select_by_rectangle(self, value_rect): points = [point for point in self.scatterplot_item.points() if value_rect.contains(QPointF(point.pos()))] self.select(points) def unselect_all(self): self.selection = None self.update_colors(keep_colors=True) def select(self, points): # noinspection PyArgumentList keys = QApplication.keyboardModifiers() if self.selection is None or not keys & ( Qt.ShiftModifier + Qt.ControlModifier + Qt.AltModifier): self.selection = np.full(self.n_points, False, dtype=np.bool) indices = [p.data() for p in points] if keys & Qt.ControlModifier: self.selection[indices] = False elif keys & Qt.AltModifier: self.selection[indices] = 1 - self.selection[indices] else: # Handle shift and no modifiers self.selection[indices] = True self.update_colors(keep_colors=True) self.master.selection_changed() def get_selection(self): if self.selection is None: return np.array([], dtype=int) else: return np.arange(len(self.raw_data) )[self.valid_data][self.selection] def set_palette(self, p): self.plot_widget.setPalette(p) def save_to_file(self, size): pass