def addGraphPlot(self): graph = GraphicsLayoutWidget(self.stockTab2) graph.setObjectName("stock UI") p1 = graph.addPlot(row=1, col=0) p2 = graph.addPlot(row=2, col=0) p1.showGrid(x=True, y=True, alpha=0.5) return graph
def populate_spectrogram_widget(self, widget: GraphicsLayoutWidget, game_name: str, player_name: PlayerName, electrode_name: str): # https://stackoverflow.com/questions/51312923/plotting-the-spectrum-of-a-wavfile-in-pyqtgraph-using-scipy-signal-spectrogram f, t, Sxx = self._acquire_spectrogram_signal(game_name, player_name, electrode_name) plot = widget.addPlot() plot.setTitle('Frequency over time for electrode %s' % ELECTRODES[electrode_name]) img = ImageItem() plot.addItem(img) hist = HistogramLUTItem() hist.setImageItem(img) widget.addItem(hist) hist.setLevels(np.min(Sxx), np.max(Sxx)) hist.gradient.restoreState({ 'mode': 'rgb', 'ticks': [(0.5, (0, 182, 188, 255)), (1.0, (246, 111, 0, 255)), (0.0, (75, 0, 113, 255))] }) img.setImage(Sxx) img.scale(t[-1] / np.size(Sxx, axis=1), f[-1] / np.size(Sxx, axis=0)) plot.setLimits(xMin=0, xMax=t[-1], yMin=0, yMax=f[-1]) plot.setLabel('bottom', "Time", units='s') plot.setLabel('left', "Frequency", units='Hz')
def populate_eeg_graph_widget(self, widget: GraphicsLayoutWidget, game_name: str, player_name: PlayerName, electrode_name: str): data = self._acquire_eeg_signal(game_name, player_name, electrode_name) time = self._acquire_eeg_signal(game_name, player_name, 'time') plot = widget.addPlot() plot.plot(time, data, pen=mkPen({'color': "37AAD2"})) plot.setTitle('Amplitude of the EEG signal for electrode %s' % ELECTRODES[electrode_name]) plot.setLabel('bottom', "Time", units='s') plot.setLabel('left', "Amplitude", units='uV')
def get_spectrogram(wav: WavFile, graphics_layout: pyqtgraph.GraphicsLayoutWidget): f, t, Sxx = signal.spectrogram(wav.data, wav.rate) # Interpret image data as row-major instead of col-major pyqtgraph.setConfigOptions(imageAxisOrder='row-major') pyqtgraph.mkQApp() graphics_layout.clear() plot_widget = graphics_layout.addPlot() # A plot area (ViewBox + axes) for displaying the image # Item for displaying image data img = pyqtgraph.ImageItem() plot_widget.addItem(img) # Add a histogram with which to control the gradient of the image hist = pyqtgraph.HistogramLUTItem() # Link the histogram to the image hist.setImageItem(img) # If you don't add the histogram to the window, it stays invisible, but I find it useful. graphics_layout.addItem(hist) # Show the window graphics_layout.show() # Fit the min and max levels of the histogram to the data available #print("min: "+ str(np.min(Sxx)) + "max:" + str(np.max(Sxx))) hist.setLevels(0, 40000) # This gradient is roughly comparable to the gradient used by Matplotlib # You can adjust it and then save it using hist.gradient.saveState() hist.gradient.restoreState( {'mode': 'rgb', 'ticks': [(0.5, (0, 182, 188, 255)), (1.0, (246, 111, 0, 255)), (0.0, (75, 0, 113, 255))]}) # Sxx contains the amplitude for each pixel img.setImage(Sxx) # Scale the X and Y Axis to time and frequency (standard is pixels) img.scale(t[-1] / np.size(Sxx, axis=1), f[-1] / np.size(Sxx, axis=0)) # Limit panning/zooming to the spectrogram plot_widget.setLimits(xMin=0, xMax=t[-1], yMin=0, yMax=f[-1]) # Add labels to the axis plot_widget.setLabel('bottom', "Time", units='s') # If you include the units, Pyqtgraph automatically scales the axis and adjusts the SI prefix (in this case kHz) plot_widget.setLabel('left', "Frequency", units='Hz')
class Ui_MainWindow(QMainWindow): def __init__(self): super(Ui_MainWindow, self).__init__() self.traindata = [] self.numberofclasses = 0 self.trueTestDataLabels= [] self.labeltestdata= [] self.testData = [] def setupUi(self): self.centralwidget = QtWidgets.QWidget() self.setMinimumSize(QtCore.QSize(766, 430)) self.setMaximumSize(QtCore.QSize(766, 430)) self.centralwidget.setObjectName("centralwidget") self.graphicsView = GraphicsLayoutWidget(self.centralwidget) self.graphicsView.setGeometry(QtCore.QRect(10, 80, 751, 321)) self.graphicsView.setObjectName("graphicsView") self.pushButtonExplore = QtWidgets.QPushButton(self.centralwidget) self.pushButtonExplore.setGeometry(QtCore.QRect(12, 402, 337, 27)) self.pushButtonExplore.setObjectName("pushButtonExplore") self.graphicsView_2 = GraphicsLayoutWidget(self.centralwidget) self.graphicsView_2.setGeometry(QtCore.QRect(10, 440, 751, 221)) self.graphicsView_2.setObjectName("graphicsView_2") self.widget = QtWidgets.QWidget(self.centralwidget) self.widget.setGeometry(QtCore.QRect(11, 11, 750, 62)) self.widget.setObjectName("widget") self.gridLayout = QtWidgets.QGridLayout(self.widget) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setObjectName("gridLayout") self.pushButtotLoadIris = QtWidgets.QPushButton(self.widget) self.pushButtotLoadIris.setObjectName("pushButtotLoadIris") self.gridLayout.addWidget(self.pushButtotLoadIris, 0, 0, 1, 2) self.checkBoxSuspended = QtWidgets.QCheckBox(self.widget) self.checkBoxSuspended.setObjectName("checkBoxSuspended") self.gridLayout.addWidget(self.checkBoxSuspended, 0, 2, 1, 3) self.pushButtonCheckTest = QtWidgets.QPushButton(self.widget) self.pushButtonCheckTest.setObjectName("pushButtonCheckTest") self.gridLayout.addWidget(self.pushButtonCheckTest, 0, 5, 1, 3) self.pushButtonGenerate = QtWidgets.QPushButton(self.widget) self.pushButtonGenerate.setObjectName("pushButtonGenerate") self.gridLayout.addWidget(self.pushButtonGenerate, 1, 0, 1, 1) self.label_3 = QtWidgets.QLabel(self.widget) self.label_3.setObjectName("label_3") self.gridLayout.addWidget(self.label_3, 1, 1, 1, 2) self.spinBoxClasses = QtWidgets.QSpinBox(self.widget) self.spinBoxClasses.setMinimum(1) self.spinBoxClasses.setMaximum(8) self.spinBoxClasses.setObjectName("spinBoxClasses") self.gridLayout.addWidget(self.spinBoxClasses, 1, 3, 1, 1) self.label_2 = QtWidgets.QLabel(self.widget) self.label_2.setObjectName("label_2") self.gridLayout.addWidget(self.label_2, 1, 4, 1, 1) self.spinBoxElements = QtWidgets.QSpinBox(self.widget) self.spinBoxElements.setMinimum(1) self.spinBoxElements.setProperty("value", 20) self.spinBoxElements.setObjectName("spinBoxElements") self.gridLayout.addWidget(self.spinBoxElements, 1, 5, 1, 1) self.label = QtWidgets.QLabel(self.widget) self.label.setObjectName("label") self.gridLayout.addWidget(self.label, 1, 6, 1, 1) self.spinBoxK = QtWidgets.QSpinBox(self.widget) self.spinBoxK.setMinimum(3) self.spinBoxK.setSingleStep(2) self.spinBoxK.setObjectName("spinBoxK") self.gridLayout.addWidget(self.spinBoxK, 1, 7, 1, 1) self.retranslateUi() QtCore.QMetaObject.connectSlotsByName(self) self.w1 = self.graphicsView.addPlot() self.w2 = self.graphicsView_2.addPlot() self.legend= self.w2.addLegend() self.w1.scene().sigMouseClicked.connect(self.onClick) self.pushButtonGenerate.clicked.connect(self.generateDate) self.pushButtotLoadIris.clicked.connect(self.loadIris) self.pushButtonCheckTest.clicked.connect(self.checkTest) self.pushButtonExplore.clicked.connect(self.explore) self.setCentralWidget(self.centralwidget) def retranslateUi(self): _translate = QtCore.QCoreApplication.translate self.pushButtonExplore.setText(_translate("MainWindow", "Исследование влияния k для разных метрик")) self.pushButtotLoadIris.setText(_translate("MainWindow", "Загрузить данные с рисом")) self.checkBoxSuspended.setText(_translate("MainWindow", "Использовать взвешенный kNN")) self.pushButtonCheckTest.setText(_translate("MainWindow", "Проверить тестовую выборку")) self.pushButtonGenerate.setText(_translate("MainWindow", "Сгенерировать выборку")) self.label_3.setText(_translate("MainWindow", "Кол-во классов")) self.label_2.setText(_translate("MainWindow", "Кол-во элементов")) self.label.setText(_translate("MainWindow", "Кол-во соседей(K)")) def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: self.close() if e.key() == Qt.Key_Delete: self.w1.clear() classes = [] i = 0 while i < 20: classes.append([]) i += 1 for i in self.traindata: classes[i[1]].append(np.asarray(i[0])) i = 0 for j in classes: myS = pg.ScatterPlotItem(size=10, pen=pg.mkPen(colors[i]), brush=pg.mkBrush(255, 255, 255, 120)) myspots = [] if (len(j)): for k in j: myspots.append({'pos': k, 'data': i}) i += 1 myS.addPoints(myspots) self.w1.addItem(myS) def onClick(self, event): if len(self.traindata) == 0: return 1 vb = self.w1.vb mousePoint = vb.mapSceneToView(event.scenePos()) testdata = [[mousePoint.x(), mousePoint.y()]] testDataLabels = classifyKNN(self.traindata, testdata, self.spinBoxK.value(), self.numberofclasses,self.checkBoxSuspended.isChecked(),0) myS = pg.ScatterPlotItem(size=10, pen=pg.mkPen(colors[testDataLabels[0]]), brush=pg.mkBrush(255, 255, 255, 120)) myspots = [] myspots.append({'pos': np.asarray([mousePoint.x(), mousePoint.y()]), 'data': testDataLabels[0]}) myS.addPoints(myspots) self.w1.addItem(myS) self.traindata.append([[mousePoint.x(), mousePoint.y()], testDataLabels[0]]) print(self.traindata) def loadIris(self): with open('train', 'rb') as fp: train = pickle.load(fp) with open('labels', 'rb') as fp: labels = pickle.load(fp) self.w1.clear() self.numberofclasses = 3 self.traindata = [] n = 0 for i in train: self.traindata.append([]) self.traindata[n].append(i.tolist()) self.traindata[n].append(labels[n]) n += 1 # testDataLabels = classifyKNN(trainData, testData, 5, 2) trainData, self.trueTestDataLabels = splitTrainTest(self.traindata, 0.33) self.traindata = trainData self.testData = [self.trueTestDataLabels[i][0] for i in range(len(self.trueTestDataLabels))] # self.labeltestdata = classifyKNN(trainData, self.testData, self.spinBoxK.value(), self.numberofclasses,self.checkBoxSuspended.isChecked()) classes = [] i = 0 while i < 20: classes.append([]) i += 1 for i in self.traindata: classes[i[1]].append(np.asarray(i[0])) i = 0 for j in classes: myS = pg.ScatterPlotItem(size=10, pen=pg.mkPen(colors[i]), brush=pg.mkBrush(255, 255, 255, 120)) myspots = [] if (len(j)): for k in j: myspots.append({'pos': k, 'data': i}) i += 1 myS.addPoints(myspots) self.w1.addItem(myS) self.spinBoxClasses.setValue(3) self.spinBoxK.setValue(4) self.spinBoxK.setSingleStep(3) self.spinBoxElements.setValue(75) def checkTest(self): if len(self.traindata) == 0: return 1 print(self.testData) self.labeltestdata = classifyKNN(self.traindata, self.testData, self.spinBoxK.value(), self.numberofclasses,self.checkBoxSuspended.isChecked(),0) x = sum([int(self.labeltestdata[i] == self.trueTestDataLabels[i][1]) for i in range(len(self.trueTestDataLabels))]) / float( len(self.trueTestDataLabels)) classes = [] i = 0 while i < 20: classes.append([]) i += 1 for i in self.trueTestDataLabels: classes[i[1]].append(np.asarray(i[0])) i = 0 for j in classes: myS = pg.ScatterPlotItem(size=10, pen=pg.mkPen(colors[i]), brush=pg.mkBrush(255, 255, 255, 120)) myspots = [] if (len(j)): for k in j: myspots.append({'pos': k, 'data': i}) i += 1 myS.addPoints(myspots) self.w1.addItem(myS) dialog = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Information, "Точность классификации ", str(x), buttons=QtWidgets.QMessageBox.Ok , parent=None) result = dialog.exec_() def changeK(self, i): self.spinBoxK.setSingleStep(i) self.spinBoxK.setMinimum(i + 1) self.spinBoxK.setProperty("value", i + 1) def generateDate(self): self.w1.clear() data = generateData(self.spinBoxElements.value(), self.spinBoxClasses.value()) self.numberofclasses = self.spinBoxClasses.value() trainData, self.trueTestDataLabels = splitTrainTest(data, 0.33) self.traindata = trainData self.testData = [self.trueTestDataLabels[i][0] for i in range(len(self.trueTestDataLabels))] # self.labeltestdata = classifyKNN(trainData, self.testData, self.spinBoxK.value(), self.numberofclasses,self.checkBoxSuspended.isChecked()) classes = [] i = 0 while i < 20: classes.append([]) i += 1 for i in trainData: classes[i[1]].append(np.asarray(i[0])) i = 0 for j in classes: myS = pg.ScatterPlotItem(size=10, pen=pg.mkPen(colors[i]), brush=pg.mkBrush(255, 255, 255, 120)) myspots = [] if (len(j)): for k in j: myspots.append({'pos': k, 'data': i}) i += 1 myS.addPoints(myspots) self.w1.addItem(myS) def explore(self): if not(self.traindata): return self.w2.clear() self.legend.scene().removeItem(self.legend) self.legend = self.w2.addLegend() myspots = [] i = self.spinBoxK.value() while i < self.spinBoxElements.value(): self.labeltestdata = classifyKNN(self.traindata, self.testData, i, self.numberofclasses, self.checkBoxSuspended.isChecked(), 0) myspots.append([i, sum([int(self.labeltestdata[i] == self.trueTestDataLabels[i][1]) for i in range(len(self.trueTestDataLabels))]) / float( len(self.trueTestDataLabels))]) i += self.spinBoxK.singleStep() self.w2.plot(x=[x[0] for x in myspots], y=[y[1] for y in myspots], symbol='o', name = "Евклидово расстояние", pen = (0, 0, 255), ) myspots = [] i = self.spinBoxK.value() while i < self.spinBoxElements.value(): self.labeltestdata = classifyKNN(self.traindata, self.testData, i, self.numberofclasses, self.checkBoxSuspended.isChecked(), 1) myspots.append([i, sum([int(self.labeltestdata[i] == self.trueTestDataLabels[i][1]) for i in range(len(self.trueTestDataLabels))]) / float( len(self.trueTestDataLabels))]) i += self.spinBoxK.singleStep() self.w2.plot(x=[x[0] for x in myspots], y=[y[1] for y in myspots], pen=(255, 0, 0), symbolBrush=(255, 0, 0), symbolPen='w', name="Манхэттенское расстояние") myspots = [] i = self.spinBoxK.value() while i < self.spinBoxElements.value(): self.labeltestdata = classifyKNN(self.traindata, self.testData, i, self.numberofclasses, self.checkBoxSuspended.isChecked(), 2) myspots.append([i, sum([int(self.labeltestdata[i] == self.trueTestDataLabels[i][1]) for i in range(len(self.trueTestDataLabels))]) / float( len(self.trueTestDataLabels))]) i += self.spinBoxK.singleStep() self.w2.plot(x=[x[0] for x in myspots], y=[y[1] for y in myspots], pen=(0, 255, 0), symbolBrush=(0, 255, 0), symbolPen='g', name="Расстояние Чебышева") self.w2.setLabels(title='Сравнение метрик', left="Точность", bottom="K") self.setMinimumSize(QtCore.QSize(766, 717)) self.setMaximumSize(QtCore.QSize(766, 717))
class EEGViewer(QThread): """docstring for EEGViewer""" StoppedState = 0 PausedState = 1 RunningState = 2 def __init__(self, mode='single', rows=4): super(EEGViewer, self).__init__() self.mode = mode self.rows = rows self.view = GraphicsLayoutWidget() self.view.setAntialiasing(True) self.view.setWindowTitle('EEG Viewer') self.state = self.StoppedState self.position = 0 self.maxPosition = 0 self.plotItem = list() self.plotTrace = dict() # Holders self.wait = 0 self.wsize = 0 self.hsize = 0 self.color = dict() self.window = list([0, 0]) self.channel = list() def widget(self): return self.view def show(self): self.view.show() def hide(self): self.view.hide() def getState(self): return self.state def isVisible(self): return self.view.isVisible() def setSize(self, width, height): self.view.resize(width, height) def configure(self, channel, color, wsize, fs=0): # Link params nCh = len(channel) self.wait = 1 / (fs * nCh) if fs > 0 else 0 self.wsize = wsize self.hsize = wsize / 2 self.color = color self.channel = channel self.window = np.array([0, wsize]) # Remove previous items and traces self.view.clear() self.plotItem.clear() self.plotTrace.clear() # Create new canvas if self.mode == 'single': self.singleLayout() else: self.multipleLayout() def singleLayout(self): canvas = self.view.addPlot(0, 0) canvas.disableAutoRange() canvas.setClipToView(True) canvas.setLimits(yMin=0, yMax=1) canvas.setDownsampling(mode='subsample') canvas.showGrid(x=True, y=True, alpha=0.25) for ch in self.channel: pen = mkPen(color=self.color[ch], width=2) self.plotTrace[ch] = canvas.plot(pen=pen) self.plotItem.append(canvas) def multipleLayout(self): col = 0 rowLimit = self.rows for i, ch in enumerate(self.channel): pen = mkPen(color=self.color[ch], width=2) canvas = self.view.addPlot(i % rowLimit, col) canvas.disableAutoRange() canvas.setClipToView(True) canvas.setLimits(yMin=0, yMax=1) canvas.setDownsampling(mode='subsample') canvas.showGrid(x=True, y=True, alpha=0.25) self.plotItem.append(canvas) self.plotTrace[ch] = canvas.plot(pen=pen) if (i + 1) % rowLimit == 0: col += 1 def plotData(self, D): for ch in self.channel: self.plotTrace[ch].setData(D[ch].values) self.position = 0 self.maxPosition = D.index.size def addMark(self, position, label=None): for canvas in self.plotItem: pen = mkPen(color='g', width=2.5, style=Qt.DashLine) hpen = mkPen(color='r', width=2.5, style=Qt.DashLine) mark = canvas.addLine(x=position, pen=pen, label=label, labelOpts={'position': 0.9}, movable=True, hoverPen=hpen) return mark def setPosition(self, position): self.window[0] = position - self.hsize self.window[1] = position + self.hsize self.position = position self.update() def update(self): for plot in self.plotItem: plot.setRange(xRange=self.window) self.position += 1 if self.position < self.maxPosition else 0 def play(self): self.state = self.RunningState self.start() def pause(self): self.state = self.PausedState def toggle(self): self.state = self.PausedState if self.state == self.RunningState else self.RunningState def stop(self): self.state = self.StoppedState self.quit() self.setPosition(0) def run(self): while True: if self.state == self.RunningState: self.setPosition(self.position) elif self.state == self.PausedState: pass else: break sleep(self.wait)
class Ui_MainWindow(object): def variables(self): self.D1_='D1' self.D2_='D2' self.D3_='D3' self.AVF_='AVF' self.AVR_='AVR' self.AVL_='AVL' self.GENRAL_='GENRAL' def setupUi(self, MainWindow): try: base_path= sys._MEIPASS except Exception: base_path=os.path.abspath(".") path1 = os.path.join(base_path, "imagen1.jpeg") path2 = os.path.join(base_path, "imagen2.jpeg") MainWindow.setObjectName("MainWindow") MainWindow.resize(1350, 747) #MainWindow.setStyleSheet("background-color: blue;") self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.pushButtonAbrir = QtWidgets.QPushButton(self.centralwidget) self.pushButtonAbrir.setGeometry(QtCore.QRect(280, 10, 300, 32)) self.pushButtonAbrir.setObjectName("pushButtonAbrir") #self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget) #self.pushButton_2.setGeometry(QtCore.QRect(510, 90, 151, 41)) #self.pushButton_2.setObjectName("pushButton_2") self.graphicsView = GraphicsLayoutWidget(self.centralwidget) self.graphicsView.setGeometry(QtCore.QRect(750, 230, 585, 370)) self.graphicsView.setObjectName("graphicsView") #self.graphicsView.setBackground(background=None) self.label_7 = QtWidgets.QLabel(self.centralwidget) self.label_7.setGeometry(QtCore.QRect(1050, 1, 300, 100)) self.label_7.setObjectName("label_7") pixmap = QPixmap(path1) self.label_7.setPixmap(pixmap) self.label_8 = QtWidgets.QLabel(self.centralwidget) self.label_8.setGeometry(QtCore.QRect(800, 1, 300, 100)) self.label_8.setObjectName("label_8") pixmap = QPixmap(path2) self.label_8.setPixmap(pixmap) #Persona que creo el programa self.label_9 = QtWidgets.QLabel(self.centralwidget) self.label_9.setGeometry(QtCore.QRect(1000, 630, 2000, 70)) self.label_9.setObjectName("label_9") #Nombre del proyecto self.label_10 = QtWidgets.QLabel(self.centralwidget) self.label_10.setGeometry(QtCore.QRect(1000, 595, 2000, 70)) self.label_10.setObjectName("label_10") #Parametros de la persona self.label_nom = QtWidgets.QLabel(self.centralwidget) self.label_nom.setGeometry(QtCore.QRect(800, 20, 800, 200)) self.label_nom.setObjectName("label_nom") self.label_edad = QtWidgets.QLabel(self.centralwidget) self.label_edad.setGeometry(QtCore.QRect(800, 60, 800, 200)) self.label_edad.setObjectName("label_edad") self.label_sexo = QtWidgets.QLabel(self.centralwidget) self.label_sexo.setGeometry(QtCore.QRect(800, 100, 800, 200)) self.label_sexo.setObjectName("label_sexo") self.groupBox = QtWidgets.QGroupBox(self.centralwidget) self.groupBox.setGeometry(QtCore.QRect(20, 40, 675, 841)) self.groupBox.setObjectName("groupBox") self.graphicD1 = GraphicsLayoutWidget(self.groupBox) self.graphicD1.setObjectName("graphicD1") self.graphicD1.setGeometry(QtCore.QRect(65, 30, 1000, 110)) self.graphicD1.setBackground(background=None) self.graphicD2 = GraphicsLayoutWidget(self.groupBox) self.graphicD2.setObjectName("graphicD2") self.graphicD2.setGeometry(QtCore.QRect(65, 130, 1000, 110)) self.graphicD2.setBackground(background=None) self.graphicD3 = GraphicsLayoutWidget(self.groupBox) self.graphicD3.setObjectName("graphicD3") self.graphicD3.setGeometry(QtCore.QRect(65, 230, 1000, 110)) self.graphicD3.setBackground(background=None) self.graphicD3_2 = GraphicsLayoutWidget(self.groupBox) self.graphicD3_2.setObjectName("graphicD3_2") self.graphicD3_2.setGeometry(QtCore.QRect(65, 330, 1000, 110)) self.graphicD3_2.setBackground(background=None) self.graphicD3_3 = GraphicsLayoutWidget(self.groupBox) self.graphicD3_3.setGeometry(QtCore.QRect(65, 430, 1000, 110)) self.graphicD3_3.setObjectName("graphicD3_3") self.graphicD3_3.setBackground(background=None) self.graphicD3_4 = GraphicsLayoutWidget(self.groupBox) self.graphicD3_4.setObjectName("graphicD3_4") self.graphicD3_4.setGeometry(QtCore.QRect(65, 530, 1000, 110)) self.graphicD3_4.setBackground(background=None) self.label = QtWidgets.QLabel(self.groupBox) self.label.setGeometry(QtCore.QRect(10, 65, 50, 24)) self.label.setObjectName("label") self.label_2 = QtWidgets.QLabel(self.groupBox) self.label_2.setGeometry(QtCore.QRect(10, 165, 50, 24)) self.label_2.setObjectName("label_2") self.label_3 = QtWidgets.QLabel(self.groupBox) self.label_3.setGeometry(QtCore.QRect(10, 265, 50, 24)) self.label_3.setObjectName("label_3") self.label_4 = QtWidgets.QLabel(self.groupBox) self.label_4.setGeometry(QtCore.QRect(10, 365, 60, 24)) self.label_4.setObjectName("label_4") self.label_5 = QtWidgets.QLabel(self.groupBox) self.label_5.setGeometry(QtCore.QRect(10, 465, 60, 24)) self.label_5.setObjectName("label_5") self.label_6 = QtWidgets.QLabel(self.groupBox) self.label_6.setGeometry(QtCore.QRect(10, 565, 60, 24)) self.label_6.setObjectName("label_6") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 863, 22)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) self.pushButtonAbrir.clicked.connect(self.mybutton_clicked) #self.pushButton_2.clicked.connect(self.generatedReport) #Cajas de texto self.line_nom = QtWidgets.QLineEdit(self.centralwidget) self.line_nom.resize(200, 32) self.line_nom.move(875, 100) self.line_edad = QtWidgets.QLineEdit(self.centralwidget) self.line_edad.resize(200, 32) self.line_edad.move(875, 140) #self.line_sexo = QtWidgets.QLineEdit(self.centralwidget) #self.line_sexo.resize(200, 32) #self.line_sexo.move(875, 180) self.combo_sexo = QtWidgets.QComboBox(self.centralwidget) self.combo_sexo.resize(200, 32) self.combo_sexo.move(875, 180) self.combo_sexo.addItems(["None","Male","Female" ]) QtCore.QMetaObject.connectSlotsByName(MainWindow) def mybutton_clicked(self): try: self.variables() #Nombre de encabezados del archivo CSV persona = {"Nombre":self.line_nom.text(),"Edad":self.line_edad.text(),"Genero":self.combo_sexo.currentText()} combo_textt =self.combo_sexo.currentText() #print(combo_textt) filename= QtWidgets.QFileDialog.getOpenFileName() df = pandas.read_csv(filename[0]) x_max=df['x'].max() a=(df["x"])/4 b= (df["x"]+x_max)/4 c= (df["x"]+(2*x_max))/4 d= (df["x"]+(3*x_max))/4 r = pandas.concat([a,b,c,d]) s= pandas.concat([df[self.D1_],df[self.D1_],df[self.D1_],df[self.D1_]]) t= pandas.concat([df[self.D2_],df[self.D2_],df[self.D2_],df[self.D2_]]) u= pandas.concat([df[self.D3_],df[self.D3_],df[self.D3_],df[self.D3_]]) v= pandas.concat([df[self.AVF_],df[self.AVF_],df[self.AVF_],df[self.AVF_]]) w= pandas.concat([df[self.AVR_],df[self.AVR_],df[self.AVR_],df[self.AVR_]]) x= pandas.concat([df[self.AVL_],df[self.AVL_],df[self.AVL_],df[self.AVL_]]) y= pandas.concat([df[self.GENRAL_],df[self.GENRAL_],df[self.GENRAL_],df[self.GENRAL_]]) df = pandas.DataFrame({"x":r, "D1":s,"D2":t,"D3":u,"AVF":v,"AVR":w,"AVL":x,"GENRAL":y}) self.d1_INTERVAL_1=df.query('x >= 3.03 & x <= 3.08')#st self.d1_INTERVAL_2=df.query('x >= 1.7 & x <= 1.9')#t self.d1_INTERVAL_3=df.query('x >= 4.2 & x <= 4.3')#p self.d1_INTERVAL_1_MAX= self.d1_INTERVAL_1[self.D1_].max() self.d1_INTERVAL_2_MAX= self.d1_INTERVAL_2[self.D1_].max() self.d1_INTERVAL_3_MAX= self.d1_INTERVAL_3[self.D1_].max() self.d2_INTERVAL_1=df.query('x >= 15.4 & x <= 15.44')#ST self.d2_INTERVAL_2=df.query('x >= 16.2 & x <= 16.4')#T self.d2_INTERVAL_3=df.query('x >= 16.6 & x <= 16.7')#P self.d2_INTERVAL_1_MAX= self.d2_INTERVAL_1[self.D2_].max() self.d2_INTERVAL_2_MAX= self.d2_INTERVAL_2[self.D2_].max() self.d2_INTERVAL_3_MAX= self.d2_INTERVAL_3[self.D2_].max() self.d3_INTERVAL_1=df.query('x >= 67.01 & x <= 67.05')#st self.d3_INTERVAL_2=df.query('x >= 49.85 & x <= 50')#t self.d3_INTERVAL_3=df.query('x >= 50.35 & x <= 50.45')#p self.d3_INTERVAL_1_MAX= self.d3_INTERVAL_1[self.D3_].max() self.d3_INTERVAL_2_MAX= self.d3_INTERVAL_2[self.D3_].max() self.d3_INTERVAL_3_MAX= self.d3_INTERVAL_3[self.D3_].max() self.avf_INTERVAL_1=df.query('x >= 111.635 & x <= 111.7')#st self.avf_INTERVAL_2=df.query('x >= 113.82 & x <= 114')#t self.avf_INTERVAL_3=df.query('x >= 153.4 & x <= 153.545')#p self.avf_INTERVAL_1_MAX= self.avf_INTERVAL_1[self.AVF_].max() self.avf_INTERVAL_2_MAX= self.avf_INTERVAL_2[self.AVF_].max() self.avf_INTERVAL_3_MAX= self.avf_INTERVAL_3[self.AVF_].max() self.avr_INTERVAL_1=df.query('x >= 99.27 & x <= 99.29')#st self.avr_INTERVAL_2=df.query('x >= 102.06& x <= 102.26')#t self.avr_INTERVAL_3=df.query('x >= 105.95 & x <= 106.09')#p self.avr_INTERVAL_1_MAX= self.avr_INTERVAL_1[self.AVR_].min() self.avr_INTERVAL_2_MAX= self.avr_INTERVAL_2[self.AVR_].min() self.avr_INTERVAL_3_MAX= self.avr_INTERVAL_3[self.AVR_].min() self.avl_INTERVAL_1=df.query('x >= 95.93 & x <= 96.12')#st self.avl_INTERVAL_2=df.query('x >= 104.75 & x <= 104.8')#t self.avl_INTERVAL_3=df.query('x >= 130.67 & x <= 130.81')#p self.avl_INTERVAL_1_MAX= self.avl_INTERVAL_1[self.AVL_].max() self.avl_INTERVAL_2_MAX= self.avl_INTERVAL_2[self.AVL_].max() self.avl_INTERVAL_3_MAX= self.avl_INTERVAL_3[self.AVL_].max() #VALORES ST Y T values_ST_T ={ self.D1_: { "d1_INTERVAL_1_MAX":self.d1_INTERVAL_1_MAX, "d1_INTERVAL_2_MAX":self.d1_INTERVAL_2_MAX, "d1_INTERVAL_3_MAX":self.d1_INTERVAL_3_MAX }, self.D2_: { "d2_INTERVAL_1_MAX":self.d2_INTERVAL_1_MAX, "d2_INTERVAL_2_MAX":self.d2_INTERVAL_2_MAX, "d2_INTERVAL_3_MAX":self.d2_INTERVAL_3_MAX }, self.D3_: { "d3_INTERVAL_1_MAX":self.d3_INTERVAL_1_MAX, "d3_INTERVAL_2_MAX":self.d3_INTERVAL_2_MAX, "d3_INTERVAL_3_MAX":self.d3_INTERVAL_3_MAX }, self.AVF_: { "avf_INTERVAL_1_MAX":self.avf_INTERVAL_1_MAX, "avf_INTERVAL_2_MAX":self.avf_INTERVAL_2_MAX, "avf_INTERVAL_3_MAX":self.avf_INTERVAL_3_MAX }, self.AVR_: { "avr_INTERVAL_1_MAX":self.avr_INTERVAL_1_MAX, "avr_INTERVAL_2_MAX":self.avr_INTERVAL_2_MAX, "avr_INTERVAL_3_MAX":self.avr_INTERVAL_3_MAX }, self.AVL_: { "avl_INTERVAL_1_MAX":self.avl_INTERVAL_1_MAX, "avl_INTERVAL_2_MAX":self.avl_INTERVAL_2_MAX, "avl_INTERVAL_3_MAX":self.avl_INTERVAL_3_MAX, } } #Intervalo general limit=16 GENER_INTERVAL=df.query('x >= 236 & x <= 243') print(GENER_INTERVAL) contPuls=0 bandera = True for index, row in GENER_INTERVAL.iterrows(): if int(row[self.GENRAL_]) >= limit and bandera==True: contPuls = contPuls + 1 bandera = False elif int(row[self.GENRAL_])<limit and bandera == False: contPuls = contPuls + 1 bandera = True #Graficar valores self.graphicD1.plot(x=df['x'], y=df[self.D1_], pen='#2196F3') self.graphicD2.plot(x=(df['x']), y=df[self.D2_], pen='#2196F3') self.graphicD3.plot(x=(df['x']), y=df[self.D3_], pen='#2196F3') self.graphicD3_2.plot(x=(df['x']), y=df[self.AVF_], pen='#2196F3') self.graphicD3_3.plot(x=(df['x']), y=df[self.AVR_], pen='#2196F3') self.graphicD3_4.plot(x=(df['x']), y=df[self.AVL_], pen='#2196F3') self.graphicsView.plot(x=(df['x']), y=df[self.GENRAL_], pen='#2196F3') self.graphicsView.setLabel("bottom", "Time / s") self.generatedReport(df,persona,values_ST_T,contPuls/2) except NameError: print("error: "+NameError) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "RECAHOLT")) MainWindow.setWindowIcon(QtGui.QIcon('ico.png')) self.pushButtonAbrir.setText(_translate("MainWindow", "Open file and report generator")) #self.pushButton_2.setText(_translate("MainWindow", "Generar Reporte")) self.label_9.setText(_translate("MainWindow", "by Jonathan Recalde")) self.label_9.setFont(QtGui.QFont('Times', 20)) self.label_10.setText(_translate("MainWindow", "RECAHOLT")) self.label_10.setFont(QtGui.QFont('Times', 20)) self.groupBox.setTitle(_translate("MainWindow", "Graphics")) self.groupBox.setFont(QtGui.QFont('Times', 20)) self.label.setText(_translate("MainWindow", "D1")) self.label_2.setText(_translate("MainWindow", "D2")) self.label_3.setText(_translate("MainWindow", "D3")) self.label_4.setText(_translate("MainWindow", "aVF")) self.label_5.setText(_translate("MainWindow", "aVR")) self.label_6.setText(_translate("MainWindow", "aVL")) self.label_nom.setText(_translate("MainWindow", "Name:")) self.label_edad.setText(_translate("MainWindow", "Age:")) self.label_sexo.setText(_translate("MainWindow", "Gender:")) self.graphicD1 = self.graphicD1.addPlot(row=1, col=1) self.graphicD2 = self.graphicD2.addPlot(row=1, col=1) self.graphicD3 = self.graphicD3.addPlot(row=1, col=1) self.graphicD3_2 = self.graphicD3_2.addPlot(row=1, col=1) self.graphicD3_3 = self.graphicD3_3.addPlot(row=1, col=1) self.graphicD3_4 = self.graphicD3_4.addPlot(row=1, col=1) self.graphicsView = self.graphicsView.addPlot(row=1, col=1) def generatedReport(self,df,persona,values_ST_T,contPuls): #Valores D1 D1_max= df[self.D1_].max() Time_D1=df.query("D1 == '{0}'".format(D1_max)) int_timeD1= float(Time_D1["x"].values[0]) ST_D1= values_ST_T[self.D1_]['d1_INTERVAL_1_MAX'] Time_ST_D1=self.d1_INTERVAL_1.query("D1 == '{0}'".format(ST_D1)) int_time_ST_D1= float(Time_ST_D1["x"].values[0]) T_D1= values_ST_T[self.D1_]['d1_INTERVAL_2_MAX'] Time_T_D1=self.d1_INTERVAL_2.query("D1 == '{0}'".format(T_D1)) int_time_T_D1= float(Time_T_D1["x"].values[0]) P_D1= values_ST_T[self.D1_]['d1_INTERVAL_3_MAX'] Time_P_D1=self.d1_INTERVAL_3.query("D1 == '{0}'".format(P_D1)) int_time_P_D1= float(Time_P_D1["x"].values[0]) #Valores D2 D2_max= df[self.D2_].max() Time_D2=df.query("D2 == '{0}'".format(D2_max)) int_timeD2= float(Time_D2["x"].values[0]) ST_D2= values_ST_T[self.D2_]['d2_INTERVAL_1_MAX'] Time_ST_D2=self.d2_INTERVAL_1.query("D2 == '{0}'".format(ST_D2)) int_time_ST_D2= float(Time_ST_D2["x"].values[0]) T_D2= values_ST_T[self.D2_]['d2_INTERVAL_2_MAX'] Time_T_D2=self.d2_INTERVAL_2.query("D2 == '{0}'".format(T_D2)) int_time_T_D2= float(Time_T_D2["x"].values[0]) P_D2= values_ST_T[self.D2_]['d2_INTERVAL_3_MAX'] Time_P_D2=self.d2_INTERVAL_3.query("D2 == '{0}'".format(P_D2)) int_time_P_D2= float(Time_P_D2["x"].values[0]) #Valores D3 D3_max= df[self.D3_].max() Time_D3=df.query("D3 == '{0}'".format(D3_max)) int_timeD3= float(Time_D3["x"].values[0]) ST_D3= values_ST_T[self.D3_]['d3_INTERVAL_1_MAX'] Time_ST_D3=self.d3_INTERVAL_1.query("D3 == '{0}'".format(ST_D3)) int_time_ST_D3= float(Time_ST_D3["x"].values[0]) T_D3= values_ST_T[self.D3_]['d3_INTERVAL_2_MAX'] Time_T_D3=self.d3_INTERVAL_2.query("D3 == '{0}'".format(T_D3)) int_time_T_D3= float(Time_T_D3["x"].values[0]) P_D3= values_ST_T[self.D3_]['d3_INTERVAL_3_MAX'] Time_P_D3=self.d3_INTERVAL_3.query("D3 == '{0}'".format(P_D3)) int_time_P_D3= float(Time_P_D3["x"].values[0]) #Valores AVF AVF_max= df[self.AVF_].max() Time_AVF=df.query("AVF == '{0}'".format(AVF_max)) int_timeAVF= float(Time_AVF["x"].values[0]) ST_AVF= values_ST_T[self.AVF_]['avf_INTERVAL_1_MAX'] Time_ST_AVF=self.avf_INTERVAL_1.query("AVF == '{0}'".format(ST_AVF)) int_time_ST_AVF= float(Time_ST_AVF["x"].values[0]) T_AVF= values_ST_T[self.AVF_]['avf_INTERVAL_2_MAX'] Time_T_AVF=self.avf_INTERVAL_2.query("AVF == '{0}'".format(T_AVF)) int_time_T_AVF= float(Time_T_AVF["x"].values[0]) P_AVF= values_ST_T[self.AVF_]['avf_INTERVAL_3_MAX'] Time_P_AVF=self.avf_INTERVAL_3.query("AVF == '{0}'".format(P_AVF)) int_time_P_AVF= float(Time_P_AVF["x"].values[0]) #Valores AVR AVR_max= df[self.AVR_].min() Time_AVR=df.query("AVR == '{0}'".format(AVR_max)) int_timeAVR= float(Time_AVR["x"].values[0]) ST_AVR= values_ST_T[self.AVR_]['avr_INTERVAL_1_MAX'] Time_ST_AVR=self.avr_INTERVAL_1.query("AVR == '{0}'".format(ST_AVR)) int_time_ST_AVR= float(Time_ST_AVR["x"].values[0]) T_AVR= values_ST_T[self.AVR_]['avr_INTERVAL_2_MAX'] Time_T_AVR=self.avr_INTERVAL_2.query("AVR == '{0}'".format(T_AVR)) int_time_T_AVR= float(Time_T_AVR["x"].values[0]) P_AVR= values_ST_T[self.AVR_]['avr_INTERVAL_3_MAX'] Time_P_AVR=self.avr_INTERVAL_3.query("AVR == '{0}'".format(P_AVR)) int_time_P_AVR= float(Time_P_AVR["x"].values[0]) #Valores AVL AVL_max= df[self.AVL_].max() Time_AVL=df.query("AVL == '{0}'".format(AVL_max)) int_timeAVL= float(Time_AVL["x"].values[0]) ST_AVL= values_ST_T[self.AVL_]['avl_INTERVAL_1_MAX'] Time_ST_AVL=self.avl_INTERVAL_1.query("AVL == '{0}'".format(ST_AVL)) int_time_ST_AVL= float(Time_ST_AVL["x"].values[0]) T_AVL= values_ST_T[self.AVL_]['avl_INTERVAL_2_MAX'] Time_T_AVL=self.avl_INTERVAL_2.query("AVL == '{0}'".format(T_AVL)) int_time_T_AVL= float(Time_T_AVL["x"].values[0]) P_AVL= values_ST_T[self.AVL_]['avl_INTERVAL_3_MAX'] Time_P_AVL=self.avl_INTERVAL_3.query("AVL == '{0}'".format(P_AVL)) int_time_P_AVL= float(Time_P_AVL["x"].values[0]) # ################################### # Content try: base_path= sys._MEIPASS except Exception: base_path=os.path.abspath(".") path5 = os.path.join(base_path, 'Report.pdf') fileName = path5 documentTitle = 'ECG REPORT' title = 'ECG REPORT' subTitle = 'Name:'+persona["Nombre"] +" Age:"+persona["Edad"] +" Gender:"+persona["Genero"] textLines = [ 'D1 / R:'+str(float(D1_max))+' ST: '+str(float(ST_D1))+' T: '+str(float(T_D1))+' P: '+str(float(P_D1)), 'Time: '+str(float(int_timeD1)) +' Time: '+str(float(int_time_ST_D1))+' Time: '+str(float(int_time_T_D1))+' Time: '+str(float(int_time_P_D1)), 'D2 / R:'+str(float(D2_max))+' ST: '+str(float(ST_D2))+' T: '+str(float(T_D2)) +' P: '+str(float(P_D2)), 'Time: '+str(float(int_timeD2)) +' Time: '+str(float(int_time_ST_D2))+' Time: '+str(float(int_time_T_D2))+' Time: '+str(float(int_time_P_D2)), 'D3 / R:'+str(float(D3_max))+' ST: '+str(float(ST_D3))+' T: '+str(float(T_D3))+' P: '+str(float(P_D3)), 'Time: '+str(float(int_timeD3)) +' Time: '+str(float(int_time_ST_D3))+' Time: '+str(float(int_time_T_D3))+' Time: '+str(float(int_time_P_D3)), 'aVF / R:'+str(float(AVF_max)) +' ST: '+str(float(ST_AVF))+' T: '+str(float(T_AVF))+' P: '+str(float(P_AVF)), 'Time: '+str(float(int_timeAVF)) +' Time: '+str(float(int_time_ST_AVF))+' Time: '+str(float(int_time_T_AVF))+' Time: '+str(float(int_time_P_AVF)), 'aVR / R:'+str(float(AVR_max)) +' ST: '+str(float(ST_AVR))+' T: '+str(float(T_AVR))+' P: '+str(float(P_AVR)), 'Time: '+str(float(int_timeAVR)) +' Time: '+str(float(int_time_ST_AVR))+' Time: '+str(float(int_time_T_AVR))+' Time: '+str(float(int_time_P_AVR)), 'aVL / R:'+str(float(AVL_max)) +' ST: '+str(float(T_AVL))+' T: '+str(float(ST_AVL))+' P: '+str(float(P_AVL)), 'Time: '+str(float(int_timeAVL)) +' Time: '+str(float(int_time_ST_AVL))+' Time: '+str(float(int_time_T_AVL))+' Time: '+str(float(int_time_P_AVL)), ] # ################################### # 0) Create document from reportlab.pdfgen import canvas pdf = canvas.Canvas(fileName) pdf.setTitle(documentTitle) #self.drawMyRuler#(pdf) # ################################### # 1) Title :: Set fonts # # Print available fonts # for font in pdf.getAvailableFonts(): # print(font) # Register a new font from reportlab.pdfbase.ttfonts import TTFont from reportlab.pdfbase import pdfmetrics try: base_path= sys._MEIPASS except Exception: base_path=os.path.abspath(".") path4 = os.path.join(base_path, 'SakBunderan.ttf') print(path4) pdfmetrics.registerFont( TTFont('abc', path4) ) pdf.setFont('abc', 36) pdf.drawCentredString(300, 770, title) # ################################### # 2) Sub Title # RGB - Red Green and Blue pdf.setFillColorRGB(0, 0, 255) pdf.setFont("Courier-Bold", 24) pdf.drawCentredString(290,720, subTitle) # ################################### # 3) Draw a line pdf.line(30, 710, 550, 710) # ################################### # 4) Text object :: for large amounts of text from reportlab.lib import colors text = pdf.beginText(40, 680) text.setFont("Courier", 13) text.setFillColor(colors.red) val=True for line in textLines: text.textLine(line) if val: text.setFillColor(colors.black) val=False else : text.setFillColor(colors.red) val=True text.textLine("") #Valor maximo de X value_max_X=float(df["x"].max())/3600 text.textLine("") text.textLine("") text.textLine("") text.textLine("") text.setFillColor(colors.blue) truncate = "%.6f" % value_max_X text.textLine('Connetion time: '+str(truncate) +" h") text.textLine("") text.textLine('Heart rate: '+str(round(contPuls)*10) +" bpm") pdf.drawText(text) pdf.save()
class MainUi(QMainWindow): def __init__(self): super().__init__() pg.setConfigOption('background', '#19232D') pg.setConfigOption('foreground', 'd') pg.setConfigOptions(antialias=True) # 窗口居中显示 self.center() self.init_ui() # 设置城市的编号 self.code = "" # 多次查询时,查询近5天, 受限于 API 接口提供的数量 self.num = 5 # return request json file self.rep = "" # 创建绘图面板 self.plt = [] # 控制绘图的文件名称 self.filename = 1 # 默认的状态栏 # 可以设置其他按钮点击 参考多行文本显示 然而不行 self.status = self.statusBar() self.status.showMessage("我在主页面~") # 标题栏 self.setWindowTitle("天气查询软件") self.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5()) def init_ui(self): # self.setFixedSize(960,700) # 创建窗口主部件 self.main_widget = QWidget() # 创建主部件的网格布局 self.main_layout = QGridLayout() # 设置窗口主部件布局为网格布局 self.main_widget.setLayout(self.main_layout) # 创建左侧部件 self.left_widget = QWidget() self.left_widget.setObjectName('left_widget') # 创建左侧部件的网格布局层 self.left_layout = QGridLayout() # 设置左侧部件布局为网格 self.left_widget.setLayout(self.left_layout) # 创建右侧部件 self.right_widget = QWidget() self.right_widget.setObjectName('right_widget') self.right_layout = QGridLayout() self.right_widget.setLayout(self.right_layout) # 左侧部件在第0行第0列,占8行3列 self.main_layout.addWidget(self.left_widget, 0, 0, 12, 5) # 右侧部件在第0行第3列,占8行9列 self.main_layout.addWidget(self.right_widget, 0, 5, 12, 7) # 设置窗口主部件 self.setCentralWidget(self.main_widget) # function button self.single_query = QPushButton("查询今日") self.single_query.clicked.connect(self.request_weather) self.single_query.setEnabled(False) # self.single_query.setFixedSize(400, 30) self.btn_tempa = QPushButton("温度预测(可绘图)") self.btn_tempa.clicked.connect(self.request_weather) self.btn_tempa.setEnabled(False) self.btn_wind = QPushButton("风力预测(可绘图)") self.btn_wind.clicked.connect(self.request_weather) self.btn_wind.setEnabled(False) self.btn_stawea = QPushButton("综合天气预测") self.btn_stawea.clicked.connect(self.request_weather) self.btn_stawea.setEnabled(False) self.left_layout.addWidget(self.single_query, 2, 0, 1, 5) self.left_layout.addWidget(self.btn_tempa, 3, 0, 1, 5) self.left_layout.addWidget(self.btn_wind, 4, 0, 1, 5) self.left_layout.addWidget(self.btn_stawea, 5, 0, 1, 5) # lineEdit to input a city self.city_line = QLineEdit() self.city_line.setPlaceholderText("输入城市回车确认") self.city_line.returnPressed.connect(self.match_city) self.left_layout.addWidget(self.city_line, 1, 0, 1, 5) # save figure and quit window self.save_fig = QPushButton("保存绘图") self.save_fig.setEnabled(False) self.save_fig.clicked.connect(self.fig_save) self.left_layout.addWidget(self.save_fig, 6, 0, 1, 5) self.load = QPushButton("写日记") self.left_layout.addWidget(self.load, 7, 0, 1, 5) self.quit_btn = QPushButton("退出") self.quit_btn.clicked.connect(self.quit_act) self.left_layout.addWidget(self.quit_btn, 8, 0, 1, 5) # tablewidgt to view data self.query_result = QTableWidget() self.left_layout.addWidget(self.query_result, 9, 0, 2, 5) self.query_result.verticalHeader().setVisible(False) self.label = QLabel("预测天气情况绘图展示区") self.right_layout.addWidget(self.label, 0, 6, 1, 7) self.plot_weather_wind = GraphicsLayoutWidget() self.plot_weather_temp = GraphicsLayoutWidget() self.right_layout.addWidget(self.plot_weather_temp, 1, 6, 4, 7) self.right_layout.addWidget(self.plot_weather_wind, 6, 6, 4, 7) self.setWindowOpacity(0.9) # 设置窗口透明度 # self.setWindowFlag(QtCore.Qt.FramelessWindowHint) # 隐藏边框 self.main_layout.setSpacing(0) # 按照城市的code, 请求一个城市的天气 返回 json 形式 def request_weather(self): root_url = "http://t.weather.sojson.com/api/weather/city/" url = root_url + str(self.code) self.rep = get_weather.run(url) sender = self.sender() if sender.text() == "查询今日": self.query(1, 5, '温度', '风向', '风力', 'PM2.5', '天气描述') if sender.text() == "温度预测(可绘图)": self.btn_tempa.setEnabled(False) self.query(self.num, 2, '日期', '温度') if sender.text() == "风力预测(可绘图)": self.btn_wind.setEnabled(False) self.query(self.num, 2, '日期', '风力') if sender.text() == "综合天气预测": self.query(self.num, 4, '温度', '风向', '风力', '天气描述') # 读取 json 文件, 获得城市的code def match_city(self): # 输入城市后才能点击绘图 self.btn_tempa.setEnabled(True) self.btn_wind.setEnabled(True) self.single_query.setEnabled(True) self.btn_stawea.setEnabled(True) # 在外部json文件中 读取所有城市的 code city = read_citycode.read_code("最新_city.json") line_city = self.city_line.text() # code与输入的城市对比, 如果有, 返回code, 如果没有则默认为北京 if line_city in city.keys(): self.code = city[line_city] else: self.code = "101010100" self.city_line.setText("北京") Qreply = QMessageBox.about(self, "你犯了一个粗误", "输入城市无效,请示新输入,否则默认为北京") # 保存图片成功时的提醒 def pic_messagebox(self): string = '第' + str(self.filename) + '张图片.png' Qreply = QMessageBox.information(self, string, "已经成功保存图片到当前目录, 关闭软件后请及时拷贝走") # 保存图片的设置 pyqtgraph 保存无法设置图片路径 def fig_save(self): ex = pe.ImageExporter(self.plt.scene()) filename = '第' + str(self.filename) + '张图片.png' self.filename += 1 ex.export(fileName=filename) self.pic_messagebox() def get_date(self, dateFormat="%Y-%m-%d", addDays=0): ls = [] timeNow = datetime.datetime.now() key = 0 if (addDays != 0) and key < addDays - 1: for i in range(addDays): anotherTime = timeNow + datetime.timedelta(days=key) anotherTime.strftime(dateFormat) ls.append(str(anotherTime)[0:10]) key += 1 else: anotherTime = timeNow return ls # 查询, 可以接受多个参数, 更加灵活的查询 def query(self, row_num, col_num, *args): # true value tempature = self.rep.json()['data']['wendu'] wind_power = self.rep.json()['data']['forecast'][0]['fl'] wind_direction = self.rep.json()['data']['forecast'][0]['fx'] pm = self.rep.json()['data']['pm25'] type_ = self.rep.json()['data']['forecast'][0]['type'] # forecast value pre_tempature = [] pre_wind_power = [] pre_wind_direction = [] pre_pm = [] pre_type_ = [] for i in range(self.num): pre_tempature.append( str(self.rep.json()['data']['forecast'][i]['low'])) pre_wind_power.append( str(self.rep.json()['data']['forecast'][i]['fl'])) pre_wind_direction.append( str(self.rep.json()['data']['forecast'][i]['fx'])) pre_type_.append( str(self.rep.json()['data']['forecast'][i]['type'])) # 设置当前查询结果的行列 self.query_result.setRowCount(row_num) # 否则不会显示 self.query_result.setColumnCount(col_num) # 表头自适应伸缩 self.query_result.horizontalHeader().setSectionResizeMode( QHeaderView.Stretch) # 按照 传入的参数设置表头, 因为每次查询的表头都不一样 ls = [i for i in args] self.query_result.setHorizontalHeaderLabels(ls) if col_num > 2 and row_num == 1: item = QTableWidgetItem(str(tempature) + "℃") # 设置单元格文本颜色 item.setForeground(QBrush(QColor(144, 182, 240))) self.query_result.setItem(0, 0, item) item = QTableWidgetItem(str(wind_direction)) item.setForeground(QBrush(QColor(144, 182, 240))) self.query_result.setItem(0, 1, item) item = QTableWidgetItem(str(wind_power)) item.setForeground(QBrush(QColor(144, 182, 240))) self.query_result.setItem(0, 2, item) item = QTableWidgetItem(str(pm)) item.setForeground(QBrush(QColor(144, 182, 240))) self.query_result.setItem(0, 3, item) item = QTableWidgetItem(str(type_)) item.setForeground(QBrush(QColor(144, 182, 240))) self.query_result.setItem(0, 4, item) if col_num > 2 and row_num > 1: for i in range(0, self.num): item = QTableWidgetItem("最" + str(pre_tempature[i])) # 设置单元格文本颜色 item.setForeground(QBrush(QColor(144, 182, 240))) self.query_result.setItem(i, 0, item) item = QTableWidgetItem(str(pre_wind_direction[i])) item.setForeground(QBrush(QColor(144, 182, 240))) self.query_result.setItem(i, 1, item) item = QTableWidgetItem(str(pre_wind_power[i])) item.setForeground(QBrush(QColor(144, 182, 240))) self.query_result.setItem(i, 2, item) item = QTableWidgetItem(str(pre_type_[i])) item.setForeground(QBrush(QColor(144, 182, 240))) self.query_result.setItem(i, 3, item) if col_num == 2 and row_num > 1: date = self.get_date(addDays=self.num) key = 0 for i in date: item = QTableWidgetItem(i) item.setForeground(QBrush(QColor(144, 182, 240))) self.query_result.setItem(key, 0, item) key += 1 if self.query_result.horizontalHeaderItem(1).text() == '温度': key = 0 for i in pre_tempature: item = QTableWidgetItem("最" + i) item.setForeground(QBrush(QColor(144, 182, 240))) self.query_result.setItem(key, 1, item) key += 1 if self.query_result.horizontalHeaderItem(1).text() == '风力': key = 0 for i in pre_wind_power: item = QTableWidgetItem(i) item.setForeground(QBrush(QColor(144, 182, 240))) self.query_result.setItem(key, 1, item) key += 1 # 只有两列的时候才可以绘制图像, if col_num < 4: ls, y = [], [] x = np.linspace(1, self.num, self.num) # 将 treeview 里面的结果以数字的形式返回到列表中, 用于绘图 for row in range(self.num): str1 = str(self.query_result.item(row, 1).text()) ls.extend(re.findall(r'\d+(?:\.\d+)?', str1)) if len(ls) == 5: y = [float(i) for i in ls] if len(ls) == 10: lt = [float(i) for i in ls] for i in range(0, len(lt), 2): y.append((lt[i] + lt[i + 1]) / 2) if len(ls) == 5: y = [float(i) for i in ls] else: y = [float(i) for i in ls[0:5]] # 获取 treeview 的标题, 以得到绘图时的标得 if self.query_result.horizontalHeaderItem(1).text() == '温度': title_ = "近期一个月温度变化(预测)" if self.query_result.horizontalHeaderItem(1).text() == '风力': title_ = "近期一个月风力变化(预测)" # 绘图时先清空面板 否则会新加一列,效果不好 # 且 pyqtgraph 的新加一列有bug, 效果不是很好 下次使用 matplotlib if title_ == "近期一个月风力变化(预测)": self.plot_weather_wind.clear() bg1 = pg.BarGraphItem(x=x, height=y, width=0.3, brush=QColor(137, 232, 165)) self.plt1 = self.plot_weather_wind.addPlot(title=title_) self.plt1.addItem(bg1) if title_ == "近期一个月温度变化(预测)": self.plot_weather_temp.clear() self.plt = self.plot_weather_temp.addPlot(title=title_) bg2 = pg.BarGraphItem(x=x, height=y, width=0.3, brush=QColor(32, 235, 233)) self.plt.addItem(bg2) # 绘图后才可以保存图片 self.save_fig.setEnabled(True) # 退出按钮 def quit_act(self): # sender 是发送信号的对象 sender = self.sender() print(sender.text() + '键被按下') qApp = QApplication.instance() qApp.quit() def center(self): ''' 获取桌面长宽 获取窗口长宽 移动 ''' screen = QDesktopWidget().screenGeometry() size = self.geometry() self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2)
class ScopeWindow(QtGui.QMainWindow): def __init__(self, parent=None, maxepisodes=10): super(ScopeWindow, self).__init__(parent) self.episodes = None self.index = [] # set a limit on how many episodes to memorize self.maxepisodes = maxepisodes # Record state of the scope window self.isclosed = True # This keeps track of the indices of which episodes are loaded self._loaded_array = [] # Default options self.options = {'colorfy':False,\ 'layout':[['Voltage', 'A', 0, 0], ['Current', 'A', 1, 0]]} # layout = [Stream, Channel, row, col] # Keep track of which colors have been used self._usedColors = [] # Set up the GUI window self.setupUi(self) self.setDisplayTheme() def setupUi(self, MainWindow): """This function is converted from the .ui file from the designer""" MainWindow.setObjectName(_fromUtf8("Scope Window")) MainWindow.resize(1200, 600) self.centralwidget = QtGui.QWidget(MainWindow) self.centralwidget.setObjectName(_fromUtf8("centralwidget")) # Graphics layout self.horizontalLayout = QtGui.QHBoxLayout(self.centralwidget) self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.graphicsLayout = QtGui.QHBoxLayout() self.graphicsLayout.setObjectName(_fromUtf8("graphicsLayout")) self.graphicsView = GraphicsLayoutWidget(self.centralwidget) self.graphicsView.setObjectName(_fromUtf8("graphicsView")) self.graphicsLayout.addWidget(self.graphicsView) self.horizontalLayout.addLayout(self.graphicsLayout) # Side panel layout: initialize as a list view self.sideDockPanel = QtGui.QDockWidget("Settings", self) self.sideDockPanel.setAllowedAreas(QtCore.Qt.LeftDockWidgetArea | QtCore.Qt.RightDockWidgetArea) self.sideDockPanel.setObjectName(_fromUtf8("sideDockPanel")) self.sideDockPanel.hide() # self.sidePanelLayout = QtGui.QHBoxLayout() # self.sidePanelLayout.setObjectName(_fromUtf8("sidePanelLayout")) self.listView = QtGui.QListView(self.centralwidget) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.listView.sizePolicy().hasHeightForWidth()) self.listView.setSizePolicy(sizePolicy) self.listView.setObjectName(_fromUtf8("listView")) self.sideDockPanel.setWidget(self.listView) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.sideDockPanel) # self.sidePanelLayout.addWidget(self.listView) # self.horizontalLayout.addLayout(self.sidePanelLayout) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtGui.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 1225, 26)) self.menubar.setObjectName(_fromUtf8("menubar")) self.setMenuBarItems() MainWindow.setMenuBar(self.menubar) self.statusbar = QtGui.QStatusBar(MainWindow) self.statusbar.setObjectName(_fromUtf8("statusbar")) MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) # ---------------- Additional main window behaviors ----------------------- def setMenuBarItems(self): # File Menu fileMenu = self.menubar.addMenu('&File') # File: Export exportMenu = fileMenu.addMenu('&Export') exportWithScaleBarAction = QtGui.QAction(QtGui.QIcon('export.png'), 'Export with scalebar', self) exportWithScaleBarAction.setShortcut('Ctrl+Alt+E') exportWithScaleBarAction.setStatusTip('Export with scalebar') exportWithScaleBarAction.triggered.connect(self.printme) exportMenu.addAction(exportWithScaleBarAction) # View Menu viewMenu = self.menubar.addMenu('&View') # View: show settings viewMenu.addAction(self.sideDockPanel.toggleViewAction()) # View: Colorfy colorfyAction = QtGui.QAction('Color code traces', self, checkable=True, checked=False) colorfyAction.setShortcut('Ctrl+Alt+C') colorfyAction.setStatusTip('Toggle between color coded traces and black traces') colorfyAction.triggered.connect(lambda: self.toggleTraceColors(colorfyAction.isChecked())) viewMenu.addAction(colorfyAction) def printme(self): print('doing stuff') def closeEvent(self, event): """Override default behavior when closing the main window""" self.isclosed = True def retranslateUi(self, MainWindow): """Set window title and other miscellaneous""" MainWindow.setWindowTitle(_translate(__version__, __version__, None)) # ------------- Episode plotting utilities -------------------------------- def updateEpisodes(self, episodes=None, index=[]): """First compare episodes with self.episodes and index with self.index Only update the difference in the two sets""" if not isinstance(episodes, dict) or not isinstance(self.episodes, dict): bool_old_episode = False else: bool_old_episode = self.episodes['Name'] == episodes['Name'] index_insert = list(set(index) - set(self.index)) index_remove = list(set(self.index) - set(index)) if bool_old_episode and not index_insert and not index_remove: # same episode, same index return elif not bool_old_episode: # new item / cell index_insert = index index_remove = [] self.episodes = episodes self.episodes['Data'] = [[]] * len(self.episodes['Dirs']) self._loaded_array = [] # update index self.index += index_insert for a in index_remove: self.index.remove(a) # Insert new episodes for i in index_insert: self.episodes['Data'][i] = NeuroData(dataFile=self.episodes['Dirs'][i], old=True, infoOnly=False, getTime=True) self._loaded_array.append(i) # call self.drawPlot self.drawEpisode(self.episodes['Data'][i], info=(self.episodes['Name'], self.episodes['Epi'][i])) # Remove episodes for j in index_remove: self.removeEpisode(info=(self.episodes['Name'], self.episodes['Epi'][j])) def drawEpisode(self, zData, info=None, pen=None): """Draw plot from 1 zData""" # Set up pen color if self.options['colorfy']: availableColors = list(colors) for c in self._usedColors: availableColors.remove(c) pen = availableColors[0] self._usedColors.append(pen) elif pen is None: pen = self.options['theme']['pen'] # Loop through all the subplots for n, l in enumerate(self.options['layout']): # get viewbox p = self.graphicsView.getItem(row=l[2], col=l[3]) if p is None: p = self.graphicsView.addPlot(row=l[2], col=l[3]) # Make sure later viewboxes are linked in time domain if n>0: p.setXLink(self.graphicsView.getItem(row=0, col=0)) # put an identifier on the trace if isinstance(info, tuple): pname = info[0]+'.'+info[1]+'.'+l[0]+'.'+l[1] else: pname = None p.plot(x=zData.Time, y=getattr(zData, l[0])[l[1]], pen=pen, name=pname) def removeEpisode(self, info=None): if not info: return for l in self.options['layout']: # get viewbox p1 = self.graphicsView.getItem(row=l[2], col=l[3]) pname = info[0]+'.'+info[1]+'.'+l[0]+'.'+l[1] remove_index = [] for k, a in enumerate(p1.listDataItems()): if a.name() == pname: # matching p1.removeItem(a) remove_index.append(k) # recover the colors if remove_index and self.options['colorfy']: for r in remove_index: del self._usedColors[r] # ----------------------- Layout utilities -------------------------------- def setLayout(self): return # ----------------------- Option utilities ---------------------------------- def toggleTraceColors(self, checked): """Change traces from black to color coded""" # if already painted in color, paint in default pen again if not checked: self.options['colorfy'] = False self._usedColors = [] # reset used colors else: self.options['colorfy'] = True for l in self.options['layout']: # get viewbox p = self.graphicsView.getItem(row=l[2], col=l[3]) for k, a in enumerate(p.listDataItems()): if not checked: pen = self.options['theme']['pen'] else: pen = colors[k%len(colors)] if pen not in self._usedColors: self._usedColors.append(pen) pen = pg.mkPen(pen) a.setPen(pen) def setDisplayTheme(self, theme='whiteboard'): self.options['theme'] = {'blackboard':{'background':'k', 'pen':'w'}, \ 'whiteboard':{'background':'w', 'pen':'k'}\ }.get(theme) self.graphicsView.setBackground(self.options['theme']['background'])
class Ui_MainWindow(QMainWindow): def __init__(self): super(Ui_MainWindow, self).__init__() self.traindata = [] self.numberofclasses = 0 self.trueTestDataLabels = [] self.labeltestdata = [] self.testData = [] def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: self.close() if e.key() == Qt.Key_Delete: self.w1.clear() classes = [] i = 0 while i < 20: classes.append([]) i += 1 for i in self.traindata: classes[i[1]].append(np.asarray(i[0])) i = 0 for j in classes: myS = pg.ScatterPlotItem(size=10, pen=pg.mkPen(colors[i]), brush=pg.mkBrush(255, 255, 255, 120)) myspots = [] if (len(j)): for k in j: myspots.append({'pos': k, 'data': i}) i += 1 myS.addPoints(myspots) self.w1.addItem(myS) def setupUi(self): #MainWindow.setObjectName("MainWindow") ## MainWindow.setFixedSize self.setMinimumSize(QtCore.QSize(754, 603)) self.setMaximumSize(QtCore.QSize(754, 603)) self.centralwidget = QtWidgets.QWidget() self.centralwidget.setObjectName("centralwidget") self.graphicsView = GraphicsLayoutWidget(self.centralwidget) self.graphicsView.setGeometry(QtCore.QRect(10, 80, 741, 541)) self.graphicsView.setObjectName("graphicsView") self.widget = QtWidgets.QWidget(self.centralwidget) self.widget.setGeometry(QtCore.QRect(10, 10, 740, 62)) self.widget.setObjectName("widget") self.gridLayout = QtWidgets.QGridLayout(self.widget) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setObjectName("gridLayout") self.loadIrisButton = QtWidgets.QPushButton(self.widget) self.loadIrisButton.setObjectName("loadIrisButton") self.gridLayout.addWidget(self.loadIrisButton, 0, 0, 1, 2) self.checkDateButton = QtWidgets.QPushButton(self.widget) self.checkDateButton.setObjectName("checkDateButton") self.gridLayout.addWidget(self.checkDateButton, 0, 4, 1, 3) self.generateButton = QtWidgets.QPushButton(self.widget) self.generateButton.setObjectName("generateButton") self.gridLayout.addWidget(self.generateButton, 1, 0, 1, 1) self.label_3 = QtWidgets.QLabel(self.widget) self.label_3.setObjectName("label_3") self.gridLayout.addWidget(self.label_3, 1, 1, 1, 1) self.spinBoxClasses = QtWidgets.QSpinBox(self.widget) self.spinBoxClasses.setMinimum(2) self.spinBoxClasses.setMaximum(8) self.spinBoxClasses.setObjectName("spinBoxClasses") self.gridLayout.addWidget(self.spinBoxClasses, 1, 2, 1, 1) self.label_2 = QtWidgets.QLabel(self.widget) self.label_2.setObjectName("label_2") self.gridLayout.addWidget(self.label_2, 1, 3, 1, 1) self.spinBoxElements = QtWidgets.QSpinBox(self.widget) self.spinBoxElements.setMinimum(1) self.spinBoxElements.setProperty("value", 20) self.spinBoxElements.setObjectName("spinBoxElements") self.gridLayout.addWidget(self.spinBoxElements, 1, 4, 1, 1) self.label = QtWidgets.QLabel(self.widget) self.label.setObjectName("label") self.gridLayout.addWidget(self.label, 1, 5, 1, 1) self.spinBoxK = QtWidgets.QSpinBox(self.widget) self.spinBoxK.setMinimum(3) self.spinBoxK.setSingleStep(2) self.spinBoxK.setObjectName("spinBoxK") self.gridLayout.addWidget(self.spinBoxK, 1, 6, 1, 1) self.retranslateUi() QtCore.QMetaObject.connectSlotsByName(self) self.w1 = self.graphicsView.addPlot() self.w1.scene().sigMouseClicked.connect(self.onClick) self.generateButton.clicked.connect(self.generateDate) self.loadIrisButton.clicked.connect(self.loadIris) self.checkDateButton.clicked.connect(self.checkTest) self.setCentralWidget(self.centralwidget) def retranslateUi(self): _translate = QtCore.QCoreApplication.translate # MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.loadIrisButton.setText( _translate("MainWindow", "Загрузить данные с рисом")) self.checkDateButton.setText( _translate("MainWindow", "Проверить тестовую выборку")) self.generateButton.setText( _translate("MainWindow", "Сгенерировать выборку")) self.label_3.setText(_translate("MainWindow", "Кол-во классов")) self.label_2.setText(_translate("MainWindow", "Кол-во элементов")) self.label.setText(_translate("MainWindow", "Кол-во соседей(K)")) def onClick(self, event): if len(self.traindata) == 0: return 1 vb = self.w1.vb mousePoint = vb.mapSceneToView(event.scenePos()) testdata = [[mousePoint.x(), mousePoint.y()]] testDataLabels = classifyKNN(self.traindata, testdata, self.spinBoxK.value(), self.numberofclasses) myS = pg.ScatterPlotItem(size=10, pen=pg.mkPen(colors[testDataLabels[0]]), brush=pg.mkBrush(255, 255, 255, 120)) myspots = [] myspots.append({ 'pos': np.asarray([mousePoint.x(), mousePoint.y()]), 'data': testDataLabels[0] }) myS.addPoints(myspots) self.w1.addItem(myS) self.traindata.append([[mousePoint.x(), mousePoint.y()], testDataLabels[0]]) print(self.traindata) print(mousePoint) def loadIris(self): with open('train', 'rb') as fp: train = pickle.load(fp) with open('labels', 'rb') as fp: labels = pickle.load(fp) self.w1.clear() self.numberofclasses = 3 self.traindata = [] n = 0 for i in train: self.traindata.append([]) self.traindata[n].append(i.tolist()) self.traindata[n].append(labels[n]) n += 1 # testDataLabels = classifyKNN(trainData, testData, 5, 2) trainData, self.trueTestDataLabels = splitTrainTest( self.traindata, 0.33) self.traindata = trainData self.testData = [ self.trueTestDataLabels[i][0] for i in range(len(self.trueTestDataLabels)) ] self.labeltestdata = classifyKNN(trainData, self.testData, self.spinBoxK.value(), self.numberofclasses) classes = [] i = 0 while i < 20: classes.append([]) i += 1 for i in self.traindata: classes[i[1]].append(np.asarray(i[0])) i = 0 for j in classes: myS = pg.ScatterPlotItem(size=10, pen=pg.mkPen(colors[i]), brush=pg.mkBrush(255, 255, 255, 120)) myspots = [] if (len(j)): for k in j: myspots.append({'pos': k, 'data': i}) i += 1 myS.addPoints(myspots) self.w1.addItem(myS) def checkTest(self): if len(self.traindata) == 0: return 1 x = sum([ int(self.labeltestdata[i] == self.trueTestDataLabels[i][1]) for i in range(len(self.trueTestDataLabels)) ]) / float(len(self.trueTestDataLabels)) self.labeltestdata = classifyKNN(self.traindata, self.testData, self.spinBoxK.value(), self.numberofclasses) classes = [] i = 0 while i < 20: classes.append([]) i += 1 for i in self.trueTestDataLabels: classes[i[1]].append(np.asarray(i[0])) i = 0 for j in classes: myS = pg.ScatterPlotItem(size=10, pen=pg.mkPen(colors[i]), brush=pg.mkBrush(255, 255, 255, 120)) myspots = [] if (len(j)): for k in j: myspots.append({'pos': k, 'data': i}) i += 1 myS.addPoints(myspots) self.w1.addItem(myS) dialog = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Information, "Точность классификации ", str(x), buttons=QtWidgets.QMessageBox.Ok, parent=None) result = dialog.exec_() def changeK(self, i): self.spinBoxK.setSingleStep(i) self.spinBoxK.setMinimum(i + 1) self.spinBoxK.setProperty("value", i + 1) def generateDate(self): self.w1.clear() data = generateData(self.spinBoxElements.value(), self.spinBoxClasses.value()) self.numberofclasses = self.spinBoxClasses.value() trainData, self.trueTestDataLabels = splitTrainTest(data, 0.33) self.traindata = trainData self.testData = [ self.trueTestDataLabels[i][0] for i in range(len(self.trueTestDataLabels)) ] self.labeltestdata = classifyKNN(trainData, self.testData, self.spinBoxK.value(), self.numberofclasses) classes = [] i = 0 while i < 20: classes.append([]) i += 1 for i in trainData: classes[i[1]].append(np.asarray(i[0])) i = 0 for j in classes: myS = pg.ScatterPlotItem(size=10, pen=pg.mkPen(colors[i]), brush=pg.mkBrush(255, 255, 255, 120)) myspots = [] if (len(j)): for k in j: myspots.append({'pos': k, 'data': i}) i += 1 myS.addPoints(myspots) self.w1.addItem(myS)
class StockGraph(): def __init__(self, numofplot=2, name=None, stockInfo=None): self.gridContainer = None self.dir = None self.construct_gridlayout() if numofplot < 0: print("numofplot must be greater or equal than 0") return -1 if name != None and len(name) > numofplot: print("Pls Checking numofplot") return -1 #X-axis data self.dataX = None self.dataY = None self.name = name self.stockInfo = stockInfo self.graph = GraphicsLayoutWidget() self.graph.setObjectName("stock UI") self.label = pg.LabelItem(justify='right') self.graph.addItem(self.label) self.date_axis = TimeAxisItem(orientation='bottom') self.date_axis1 = TimeAxisItem(orientation='bottom') self.p1 = self.graph.addPlot(row=1, col=0, axisItems={'bottom': self.date_axis1}) #p1 zoom in/out, move viewbox can auto scaling Y, Important! self.p1.vb.sigXRangeChanged.connect(self.setYRange) self.p2 = self.graph.addPlot(row=2, col=0, axisItems={'bottom': self.date_axis}) #p2 zoom in/out, move viewbox can auto scaling Y. Important! self.p2.vb.sigXRangeChanged.connect(self.setYRange) # self.p1.showGrid(x=True, y=True, alpha=0.5) self.region = pg.LinearRegionItem() self.region.setZValue(10) # Add the LinearRegionItem to the ViewBox, but tell the ViewBox to exclude this # item when doing auto-range calculations. self.p2.addItem(self.region, ignoreBounds=True) self.p1.setAutoVisible(y=True) #cross hair self.vLine = pg.InfiniteLine(angle=90, movable=False) self.hLine = pg.InfiniteLine(angle=0, movable=False) self.p1.addItem(self.vLine, ignoreBounds=True) self.p1.addItem(self.hLine, ignoreBounds=True) self.vb = self.p1.vb self.proxy = pg.SignalProxy(self.p1.scene().sigMouseMoved, rateLimit=60, slot=self.mouseMoved) #Set PlotDataItem self.numofplot = numofplot self.name = name self.colorStyle = ['r', 'g', 'b', 'y', 'w', 'r'] self.PlotDataItemList = self.setPlot() self.p2_plot = self.p2.plot(name='overview') #set gridContainer layout self.gridContainer.layout.addWidget(self.graph, 0, 0, 10, 1) self.gridContainer.setLayout(self.gridContainer.layout) self.calName = ['10avg', '30avg', '90avg'] self.CalPlotDataItemList = self.setCalPlot() #consttuct graph control Panel self.construct_controlPanel() def construct_gridlayout(self): self.gridContainer = QtWidgets.QWidget() sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHeightForWidth( self.gridContainer.sizePolicy().hasHeightForWidth()) self.gridContainer.setSizePolicy(sizePolicy) self.gridContainer.setFocusPolicy(QtCore.Qt.NoFocus) self.gridContainer.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) self.gridContainer.setObjectName("Graphgrid") self.gridContainer.layout = QtWidgets.QGridLayout() self.gridContainer.setStyleSheet("background-color:black;") def construct_controlPanel(self): self.maxRadioButton = QtWidgets.QCheckBox("Max") self.maxRadioButton.setObjectName("maxRadioButton") self.gridContainer.layout.addWidget(self.maxRadioButton, 0, 1, 1, 1) self.maxRadioButton.click() self.maxRadioButton.setStyleSheet("color: rgb(0, 255, 0);") self.maxRadioButton.toggled.connect( lambda: self.toggleFunc(self.maxRadioButton, 'high')) self.minRadioButton = QtWidgets.QCheckBox("Min") self.minRadioButton.setObjectName("minRadioButton") self.gridContainer.layout.addWidget(self.minRadioButton, 1, 1, 1, 1) self.minRadioButton.click() self.minRadioButton.setStyleSheet("color: rgb(255, 255, 255);") self.minRadioButton.toggled.connect( lambda: self.toggleFunc(self.minRadioButton, 'low')) self.closeRadioButton = QtWidgets.QCheckBox("Close") self.closeRadioButton.setObjectName("closeRadioButton") self.gridContainer.layout.addWidget(self.closeRadioButton, 2, 1, 1, 1) self.closeRadioButton.click() self.closeRadioButton.setStyleSheet("color: rgb(255,0,0);") self.closeRadioButton.toggled.connect( lambda: self.toggleFunc(self.closeRadioButton, 'close')) self.avg10RadioButton = QtWidgets.QCheckBox("10 AVG") self.avg10RadioButton.setObjectName("avg10RadioButton") self.gridContainer.layout.addWidget(self.avg10RadioButton, 3, 1, 1, 1) self.avg10RadioButton.click() self.avg10RadioButton.setStyleSheet("color: rgb(255,255,0);") self.avg10RadioButton.toggled.connect( lambda: self.toggleFunc(self.avg10RadioButton, '10avg')) self.GetButton = QtWidgets.QPushButton("Advance") self.GetButton.setObjectName("Advance") self.GetButton.clicked.connect(self.Analysis) self.GetButton.setStyleSheet("color: rgb(255, 255, 255);") self.gridContainer.layout.addWidget(self.GetButton, 4, 1, 1, 1) def update_p1_tick(self, minX, maxX, interval=60): if self.dataX != None: #0 - minX lowNum = int(minX / interval) #maxX - length HighNum = int((len(self.dataX) - 1 - maxX) / interval) plotPoint = [(minX - interval * i) for i in range(1, lowNum + 1)] + [minX] if (maxX - minX) > interval: plotPoint.append(int((maxX + minX) / 2)) plotPoint = plotPoint + [maxX] + [(maxX + interval * i) for i in range(1, HighNum + 1)] p1_tick = ['' for i in range(0, len(self.dataX))] p1_tick = dict(enumerate(p1_tick)) for index in plotPoint: p1_tick[index] = self.dataX[index] self.date_axis1.setTicks([list(p1_tick.items())[::1]]) def update(self): self.region.setZValue(10) minX, maxX = self.region.getRegion() self.p1.setXRange(minX, maxX, padding=0) if (maxX < len(self.dataX) - 1): self.update_p1_tick(int(minX) + 1, int(maxX)) def updateRegion(self, window, viewRange): rgn = viewRange[0] self.region.setRegion(rgn) def mouseMoved(self, evt): pos = evt[ 0] ## using signal proxy turns original arguments into a tuple if self.p1.sceneBoundingRect().contains(pos): mousePoint = self.vb.mapSceneToView(pos) index = int(mousePoint.x()) if index > 0 and index < len(self.dataX): idx = int(mousePoint.x()) self.label.setText( "<span style='font-size: 12pt'>x=%s, <span style='color: red'>收盤價=%0.1f</span>, <span style='color: green'>最高價=%0.1f</span> <span style='color: white'>最低價=%0.1f</span>" % (self.dataX[idx], self.dataY['close'][idx], self.dataY['high'][idx], self.dataY['low'][idx])) self.vLine.setPos(mousePoint.x()) self.hLine.setPos(mousePoint.y()) def setYRange(self, plotitem): plotitem.enableAutoRange(axis='y') plotitem.setAutoVisible(y=True) def setPlot(self): PlotDataItemList = [] for i in range(0, self.numofplot): PlotDataItemList.append( self.p1.plot(pen=self.colorStyle[i], name=self.name[i])) return PlotDataItemList def setCalPlot(self): CalPlotDataItemList = [] for i in range(0, 3): CalPlotDataItemList.append( self.p1.plot(pen=self.colorStyle[i + 3], name=self.calName[i])) return CalPlotDataItemList def setData(self, dataX, dataYDict): #create numpy arrays #make the numbers large to show that the xrange shows data from 10000 to all the way 0 self.dataX = dataX self.dataY = dataYDict ticks = dict(enumerate(dataX)) '''set X-value of P2 and P1''' self.date_axis.setTicks( [list(ticks.items())[::160], list(ticks.items())[::1]]) self.date_axis1.setTicks( [list(ticks.items())[::160], list(ticks.items())[::1]]) '''set Y-value and Plot''' for dataY, PlotDataItem in zip(dataYDict.values(), self.PlotDataItemList): PlotDataItem.setData(y=dataY) #do not show label #self.p1.getAxis('bottom').showLabel(False) # self.date_axis.linkToView(self.p1.vb) '''set overview data''' self.p2_plot.setData(x=list(ticks.keys()), y=dataYDict[self.name[0]], pen="w") #set data view range self.p2.vb.setLimits(xMin=0, xMax=len(dataYDict[self.name[0]])) self.region.sigRegionChanged.connect(self.update) # print (self.p2.vb.viewRange()) # print (self.p1.vb) # self.p1.sigRangeChanged.connect(self.updateRegion) self.region.setRegion([0, len(dataYDict[self.name[0]])]) #calculte Data avg10 = self.moving_average(dataYDict[self.name[0]], 10) self.CalPlotDataItemList[0].setData(y=avg10) #make Max and Min are invisiable by default self.minRadioButton.setChecked(False) self.maxRadioButton.setChecked(False) def toggleFunc(self, rdb, name): plotItem = None for plot in self.PlotDataItemList: if plot.name() == name: plotItem = plot for plot in self.CalPlotDataItemList: if plot.name() == name: plotItem = plot if rdb.isChecked(): self.p1.addItem(plotItem) else: self.p1.removeItem(plotItem) def setDir(self, dir): self.dir = dir def Analysis(self): d = Dialog(self.dataY, self.dataX, self.dir, self.stockInfo) d.exec() def ret_GraphicsLayoutWidget(self): return self.gridContainer @staticmethod def removeEvent(self): return def moving_average(self, data, days): result = [] NanList = [np.nan for i in range(0, days - 1)] data = data[:] for _ in range(len(data) - days + 1): result.append(round(sum(data[-days:]) / days, 2)) data.pop() result = result[::-1] return NanList + result
class astraPlotWidget(QWidget): twissplotLayout = [ { 'name': 'sigma_x', 'range': [0, 1], 'scale': 1e3 }, { 'name': 'sigma_y', 'range': [0, 1], 'scale': 1e3 }, { 'name': 'kinetic_energy', 'range': [0, 250], 'scale': 1e-6 }, 'next_row', { 'name': 'sigma_p', 'range': [0, 0.015], 'scale': 1e6 }, { 'name': 'sigma_z', 'range': [0, 0.6], 'scale': 1e3 }, { 'name': 'enx', 'range': [0.5, 1.5], 'scale': 1e6 }, 'next_row', { 'name': 'eny', 'range': [0.5, 1.5], 'scale': 1e6 }, { 'name': 'beta_x', 'range': [0, 150], 'scale': 1 }, { 'name': 'beta_y', 'range': [0, 150], 'scale': 1 }, ] def __init__(self, directory='.', **kwargs): super(astraPlotWidget, self).__init__(**kwargs) self.beam = raf.beam() self.twiss = rtf.twiss() self.directory = directory ''' twissPlotWidget ''' self.twissPlotView = GraphicsView(useOpenGL=True) self.twissPlotWidget = GraphicsLayout() self.twissPlotView.setCentralItem(self.twissPlotWidget) self.latticePlotData = imageio.imread( os.path.dirname(os.path.abspath(__file__)) + '/lattice_plot.png') self.latticePlots = {} self.twissPlots = {} i = -1 for entry in self.twissplotLayout: if entry == 'next_row': self.twissPlotWidget.nextRow() else: i += 1 p = self.twissPlotWidget.addPlot(title=entry['name']) p.showGrid(x=True, y=True) vb = p.vb vb.setYRange(*entry['range']) latticePlot = ImageItem(self.latticePlotData) latticePlot.setOpts(axisOrder='row-major') vb.addItem(latticePlot) latticePlot.setZValue(-1) # make sure this image is on top # latticePlot.setOpacity(0.5) self.twissPlots[entry['name']] = p.plot( pen=mkPen('b', width=3)) self.latticePlots[p.vb] = latticePlot p.vb.sigRangeChanged.connect(self.scaleLattice) ''' beamPlotWidget ''' self.beamPlotWidget = QWidget() self.beamPlotLayout = QVBoxLayout() self.beamPlotWidget.setLayout(self.beamPlotLayout) # # self.beamPlotChoice = # self.beamPlotAxisWidget = QWidget() self.beamPlotAxisWidget.setMaximumHeight(100) Form = self.beamPlotAxisWidget self.beamPlotXAxisDict = OrderedDict() self.beamPlotXAxisDict['x'] = {'scale': 1e3, 'axis': 'x [mm]'} self.beamPlotXAxisDict['y'] = {'scale': 1e3, 'axis': 'y [mm]'} self.beamPlotXAxisDict['z'] = { 'scale': 1e6, 'axis': 'z [micron]', 'norm': True } self.beamPlotXAxisDict['t'] = { 'scale': 1e12, 'axis': 't [ps]', 'norm': True } self.beamPlotXAxisDict['cpx'] = {'scale': 1e3, 'axis': 'cpx [keV]'} self.beamPlotXAxisDict['cpy'] = {'scale': 1e3, 'axis': 'cpy [keV]'} self.beamPlotXAxisDict['BetaGamma'] = { 'scale': 0.511, 'axis': 'cp [MeV]' } # Form.setObjectName(("Form")) # Form.resize(874, 212) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(Form.sizePolicy().hasHeightForWidth()) Form.setSizePolicy(sizePolicy) self.horizontalLayout = QHBoxLayout(Form) self.horizontalLayout.setObjectName("horizontalLayout") self.beamPlotXAxisCombo = QComboBox(Form) self.beamPlotXAxisCombo.addItems(list(self.beamPlotXAxisDict.keys())) self.beamPlotXAxisCombo.setCurrentIndex(2) self.horizontalLayout.addWidget(self.beamPlotXAxisCombo) self.beamPlotYAxisCombo = QComboBox(Form) self.beamPlotYAxisCombo.addItems(list(self.beamPlotXAxisDict.keys())) self.beamPlotYAxisCombo.setCurrentIndex(6) self.horizontalLayout.addWidget(self.beamPlotYAxisCombo) self.groupBox = QGroupBox(Form) self.groupBox.setObjectName("groupBox") self.formLayout = QFormLayout(self.groupBox) self.formLayout.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow) self.formLayout.setObjectName("formLayout") self.chooseSliceWidth = QRadioButton(self.groupBox) self.chooseSliceWidth.setObjectName(("chooseSliceWidth")) self.formLayout.setWidget(0, QFormLayout.LabelRole, self.chooseSliceWidth) self.sliceWidth = QDoubleSpinBox(self.groupBox) self.sliceWidth.setDecimals(6) self.sliceWidth.setObjectName("sliceWidth") self.formLayout.setWidget(0, QFormLayout.FieldRole, self.sliceWidth) self.chooseSliceNumber = QRadioButton(self.groupBox) self.chooseSliceNumber.setChecked(True) self.chooseSliceNumber.setObjectName("chooseSliceNumber") self.formLayout.setWidget(1, QFormLayout.LabelRole, self.chooseSliceNumber) self.sliceNumber = QSpinBox(self.groupBox) self.sliceNumber.setObjectName(("sliceNumber")) self.formLayout.setWidget(1, QFormLayout.FieldRole, self.sliceNumber) self.horizontalLayout.addWidget(self.groupBox) self.chooseSliceWidth.setText(_translate("Form", "Slice Width", None)) self.chooseSliceNumber.setText( _translate("Form", "Number of Slices", None)) self.sliceWidth.setRange(1e-6, 1) self.sliceWidth.setSingleStep(0.00001) self.histogramWidth = 0.0005 self.sliceWidth.setValue(self.histogramWidth) # self.sliceNumber = QSpinBox() self.sliceNumber.setRange(10, 10000) self.sliceNumber.setSingleStep(10) self.histogramBins = 100 self.sliceNumber.setValue(self.histogramBins) # self.beamPlotXAxisCombo = QComboBox() # self.beamPlotAxisLayout = QHBoxLayout() # self.beamPlotAxisWidget.setLayout(self.beamPlotAxisLayout) # self.beamPlotAxisLayout.addWidget(self.beamPlotXAxisCombo) # self.beamPlotAxisLayout.addWidget(self.beamPlotYAxisCombo) # self.beamPlotAxisLayout.addWidget(self.beamPlotNumberBins) self.beamPlotXAxisCombo.currentIndexChanged.connect(self.plotDataBeam) self.beamPlotYAxisCombo.currentIndexChanged.connect(self.plotDataBeam) self.chooseSliceNumber.toggled.connect(self.plotDataBeam) self.sliceNumber.valueChanged.connect(self.plotDataBeam) self.sliceWidth.valueChanged.connect(self.plotDataBeam) # self.beamPlotXAxisCombo.setCurrentIndex(2) # self.beamPlotYAxisCombo.setCurrentIndex(5) self.canvasWidget = QWidget() l = QVBoxLayout(self.canvasWidget) self.sc = MyStaticMplCanvas(self.canvasWidget, width=1, height=1, dpi=150) l.addWidget(self.sc) self.beamPlotLayout.addWidget(self.beamPlotAxisWidget) self.beamPlotLayout.addWidget(self.canvasWidget) ''' slicePlotWidget ''' self.sliceParams = [ { 'name': 'slice_normalized_horizontal_emittance', 'units': 'm-rad', 'text': 'enx' }, { 'name': 'slice_normalized_vertical_emittance', 'units': 'm-rad', 'text': 'eny' }, { 'name': 'slice_peak_current', 'units': 'A', 'text': 'PeakI' }, { 'name': 'slice_relative_momentum_spread', 'units': '%', 'text': 'sigma-p' }, { 'name': 'slice_beta_x', 'units': 'm', 'text': 'beta_x' }, { 'name': 'slice_beta_y', 'units': 'm', 'text': 'beta_y' }, ] self.slicePlotWidget = QWidget() self.slicePlotLayout = QVBoxLayout() self.slicePlotWidget.setLayout(self.slicePlotLayout) # self.slicePlotView = GraphicsView(useOpenGL=True) self.slicePlotWidgetGraphicsLayout = GraphicsLayoutWidget() # self.slicePlots = {} self.slicePlotCheckbox = {} self.curve = {} self.sliceaxis = {} self.slicePlotCheckboxWidget = QWidget() self.slicePlotCheckboxLayout = QVBoxLayout() self.slicePlotCheckboxWidget.setLayout(self.slicePlotCheckboxLayout) self.slicePlot = self.slicePlotWidgetGraphicsLayout.addPlot( title='Slice', row=0, col=50) self.slicePlot.showAxis('left', False) self.slicePlot.showGrid(x=True, y=True) i = -1 colors = ['b', 'r', 'g', 'k', 'y', 'm', 'c'] for param in self.sliceParams: i += 1 axis = AxisItem("left") labelStyle = {'color': '#' + colorStr(mkColor(colors[i]))[0:-2]} axis.setLabel(text=param['text'], units=param['units'], **labelStyle) viewbox = ViewBox() axis.linkToView(viewbox) viewbox.setXLink(self.slicePlot.vb) self.sliceaxis[param['name']] = [axis, viewbox] self.curve[param['name']] = PlotDataItem(pen=colors[i], symbol='+') viewbox.addItem(self.curve[param['name']]) col = self.findFirstEmptyColumnInGraphicsLayout() self.slicePlotWidgetGraphicsLayout.ci.addItem(axis, row=0, col=col, rowspan=1, colspan=1) self.slicePlotWidgetGraphicsLayout.ci.addItem(viewbox, row=0, col=50) p.showGrid(x=True, y=True) # self.slicePlots[param] = self.slicePlot.plot(pen=colors[i], symbol='+') self.slicePlotCheckbox[param['name']] = QCheckBox(param['text']) self.slicePlotCheckboxLayout.addWidget( self.slicePlotCheckbox[param['name']]) self.slicePlotCheckbox[param['name']].stateChanged.connect( self.plotDataSlice) # self.slicePlotView.setCentralItem(self.slicePlotWidgetGraphicsLayout) self.slicePlotSliceWidthWidget = QSpinBox() self.slicePlotSliceWidthWidget.setMaximum(500) self.slicePlotSliceWidthWidget.setValue(100) self.slicePlotSliceWidthWidget.setSingleStep(10) self.slicePlotSliceWidthWidget.setSuffix(" slices") self.slicePlotSliceWidthWidget.setSpecialValueText('Automatic') self.slicePlotAxisWidget = QWidget() self.slicePlotAxisLayout = QHBoxLayout() self.slicePlotAxisWidget.setLayout(self.slicePlotAxisLayout) self.slicePlotAxisLayout.addWidget(self.slicePlotCheckboxWidget) self.slicePlotAxisLayout.addWidget(self.slicePlotSliceWidthWidget) # self.slicePlotXAxisCombo.currentIndexChanged.connect(self.plotDataSlice) self.slicePlotSliceWidthWidget.valueChanged.connect( self.changeSliceLength) # self.beamPlotXAxisCombo.setCurrentIndex(2) # self.beamPlotYAxisCombo.setCurrentIndex(5) self.slicePlotLayout.addWidget(self.slicePlotAxisWidget) self.slicePlotLayout.addWidget(self.slicePlotWidgetGraphicsLayout) self.layout = QVBoxLayout() self.setLayout(self.layout) self.tabWidget = QTabWidget() self.folderButton = QPushButton('Select Directory') self.folderLineEdit = QLineEdit() self.folderLineEdit.setReadOnly(True) self.folderLineEdit.setText(self.directory) self.reloadButton = QPushButton() self.reloadButton.setIcon(qApp.style().standardIcon( QStyle.SP_BrowserReload)) self.folderWidget = QGroupBox() self.folderLayout = QHBoxLayout() self.folderLayout.addWidget(self.folderButton) self.folderLayout.addWidget(self.folderLineEdit) self.folderLayout.addWidget(self.reloadButton) self.folderWidget.setLayout(self.folderLayout) self.folderWidget.setMaximumWidth(800) self.reloadButton.clicked.connect( lambda: self.changeDirectory(self.directory)) self.folderButton.clicked.connect(self.changeDirectory) self.fileSelector = QComboBox() self.fileSelector.currentIndexChanged.connect(self.updateScreenCombo) self.screenSelector = QComboBox() self.screenSelector.currentIndexChanged.connect(self.changeScreen) self.beamWidget = QGroupBox() self.beamLayout = QHBoxLayout() self.beamLayout.addWidget(self.fileSelector) self.beamLayout.addWidget(self.screenSelector) self.beamWidget.setLayout(self.beamLayout) self.beamWidget.setMaximumWidth(800) self.beamWidget.setVisible(False) self.folderBeamWidget = QWidget() self.folderBeamLayout = QHBoxLayout() self.folderBeamLayout.setAlignment(Qt.AlignLeft) self.folderBeamWidget.setLayout(self.folderBeamLayout) self.folderBeamLayout.addWidget(self.folderWidget) self.folderBeamLayout.addWidget(self.beamWidget) self.tabWidget.addTab(self.twissPlotView, 'Twiss Plots') self.tabWidget.addTab(self.beamPlotWidget, 'Beam Plots') self.tabWidget.addTab(self.slicePlotWidget, 'Slice Beam Plots') # self.log = lw.loggerWidget() # self.log.addLogger(logger) # sys.stdout = lw.redirectLogger(self.log, 'stdout') # self.tabWidget.addTab(self.log,'Log') self.tabWidget.currentChanged.connect(self.changeTab) self.layout.addWidget(self.folderBeamWidget) self.layout.addWidget(self.tabWidget) self.plotType = 'Twiss' self.changeDirectory(self.directory) def findFirstEmptyColumnInGraphicsLayout(self): rowsfilled = list( self.slicePlotWidgetGraphicsLayout.ci.rows.get(0, {}).keys()) for i in range(49): if not i in rowsfilled: return i def changeTab(self, i): if self.tabWidget.tabText(i) == 'Beam Plots': self.plotType = 'Beam' self.beamWidget.setVisible(True) elif self.tabWidget.tabText(i) == 'Slice Beam Plots': self.plotType = 'Slice' self.beamWidget.setVisible(True) else: self.plotType = 'Twiss' self.beamWidget.setVisible(False) self.loadDataFile() def changeDirectory(self, directory=None): self.screenSelector.currentIndexChanged.disconnect(self.changeScreen) self.fileSelector.currentIndexChanged.disconnect( self.updateScreenCombo) if directory == None or directory == False: self.directory = str( QFileDialog.getExistingDirectory(self, "Select Directory", self.directory, QFileDialog.ShowDirsOnly)) else: self.directory = directory self.folderLineEdit.setText(self.directory) self.currentFileText = self.fileSelector.currentText() self.currentScreenText = self.screenSelector.currentText() self.getScreenFiles() self.updateFileCombo() self.updateScreenCombo() self.loadDataFile() self.screenSelector.currentIndexChanged.connect(self.changeScreen) self.fileSelector.currentIndexChanged.connect(self.updateScreenCombo) self.changeScreen(self.screenSelector.currentIndex()) def getSposition(self, file): file = h5py.File(self.directory + '/' + file + '.hdf5', "r") zpos = file.get('/Parameters/Starting_Position')[2] if abs(zpos) < 0.01: print(zpos, file) return zpos def getScreenFiles(self): self.screenpositions = {} files = glob.glob(self.directory + '/*.hdf5') filenames = [ '-'.join(os.path.basename(f).split('-')[:2]) for f in files ] # print 'filenames = ', filenames runnumber = ['001' for f in filenames] # print 'runnumber = ', runnumber for f, r in list(set(zip(filenames, runnumber))): files = glob.glob(self.directory + '/' + f + '*.hdf5') screennames = sorted( [os.path.basename(s).split('.')[0] for s in files], key=lambda x: self.getSposition(x)) screenpositions = [self.getSposition(s) for s in screennames] # print 'screenpositions = ', screenpositions self.screenpositions[f] = { 'screenpositions': screenpositions, 'screennames': screennames, 'run': r } def updateFileCombo(self): self.fileSelector.clear() i = -1 screenfirstpos = [] for f in self.screenpositions: if len(self.screenpositions[f]['screenpositions']) > 0: screenfirstpos.append( [f, min(self.screenpositions[f]['screenpositions'])]) screenfirstpos = np.array(screenfirstpos) # print 'screenfirstpos = ', screenfirstpos sortedscreennames = sorted(screenfirstpos, key=lambda x: float(x[1])) print('sortedscreennames = ', sortedscreennames) for f in sortedscreennames: self.fileSelector.addItem(f[0]) i += 1 if f[0] == self.currentFileText: self.fileSelector.setCurrentIndex(i) def changeScreen(self, i): run = self.screenpositions[str(self.fileSelector.currentText())]['run'] self.beamFileName = str(self.screenpositions[str( self.fileSelector.currentText())]['screennames'][ self.screenSelector.currentIndex()]) + '.hdf5' print('beamFileName = ', self.beamFileName) self.loadDataFile() def updateScreenCombo(self): self.screenSelector.clear() i = -1 for i, s in enumerate(self.screenpositions[str( self.fileSelector.currentText())]['screennames']): self.screenSelector.addItem( str(s) + ' (' + str(self.screenpositions[str( self.fileSelector.currentText())]['screenpositions'][i]) + ')') i += 1 if s == self.currentScreenText: self.screenSelector.setCurrentIndex(i) def loadDataFile(self): if self.plotType == 'Twiss': files = sorted(glob.glob(self.directory + "/*Xemit*")) self.twiss.read_astra_emit_files(files) files = sorted(glob.glob(self.directory + "/*.flr")) self.twiss.read_elegant_twiss_files(files, reset=False) self.plotDataTwiss() elif self.plotType == 'Beam' or self.plotType == 'Slice': if hasattr( self, 'beamFileName') and os.path.isfile(self.directory + '/' + self.beamFileName): # starttime = time.time() self.beam.read_HDF5_beam_file(self.directory + '/' + self.beamFileName) # print 'reading file took ', time.time()-starttime, 's' # print 'Read file: ', self.beamFileName if self.plotType == 'Beam': self.plotDataBeam() else: self.changeSliceLength() # self.plotDataSlice() def plotDataTwiss(self): for entry in self.twissplotLayout: if entry == 'next_row': pass else: x = self.twiss['z'] y = self.twiss[entry['name']] * entry['scale'] xy = np.transpose(np.array([x, y])) x, y = np.transpose(xy[np.argsort(xy[:, 0])]) self.twissPlots[entry['name']].setData(x=x, y=y, pen=mkPen('b', width=3)) def plotDataBeam(self): xdict = self.beamPlotXAxisDict[str( self.beamPlotXAxisCombo.currentText())] ydict = self.beamPlotXAxisDict[str( self.beamPlotYAxisCombo.currentText())] x = xdict['scale'] * getattr( self.beam, str(self.beamPlotXAxisCombo.currentText())) if 'norm' in xdict and xdict['norm'] == True: x = x - np.mean(x) y = ydict['scale'] * getattr( self.beam, str(self.beamPlotYAxisCombo.currentText())) if 'norm' in ydict and ydict['norm'] == True: y = y - np.mean(y) if self.chooseSliceWidth.isChecked(): slices = np.arange(min(x), max(x) + self.sliceWidth.value(), self.sliceWidth.value()) self.sliceNumber.setValue(len(slices)) self.sc.plothist(x, y, [slices, len(slices)], xLabel=xdict['axis'], yLabel=ydict['axis']) else: self.sliceWidth.setValue( int(1e6 * ((max(x) - min(x)) / self.sliceNumber.value())) / 1e6) self.sc.plothist(x, y, self.sliceNumber.value(), xLabel=xdict['axis'], yLabel=ydict['axis']) def changeSliceLength(self): self.beam.slices = self.slicePlotSliceWidthWidget.value() self.beam.bin_time() self.plotDataSlice() def plotDataSlice(self): for param in self.sliceParams: if self.slicePlotCheckbox[param['name']].isChecked(): exponent = np.floor(np.log10(np.abs(self.beam.slice_length))) x = 10**(12) * np.array( (self.beam.slice_bins - np.mean(self.beam.slice_bins))) self.slicePlot.setRange(xRange=[min(x), max(x)]) # self.plot.setRange(xRange=[-0.5,1.5]) y = getattr(self.beam, param['name']) self.curve[param['name']].setData(x=x, y=y) self.sliceaxis[param['name']][0].setVisible(True) # currentrange = self.sliceaxis[param['name']][0].range # print 'currentrange = ', currentrange # self.sliceaxis[param['name']][0].setRange(0, currentrange[1]) else: # pass self.curve[param['name']].setData(x=[], y=[]) self.sliceaxis[param['name']][0].setVisible(False) self.sliceaxis[param['name']][1].autoRange() currentrange = self.sliceaxis[param['name']][1].viewRange() self.sliceaxis[param['name']][1].setYRange(0, currentrange[1][1]) def scaleLattice(self, vb, range): yrange = range[1] scaleY = 0.05 * abs(yrange[1] - yrange[0]) rect = QRectF(0, yrange[0] + 2 * scaleY, 49.2778, 4 * scaleY) self.latticePlots[vb].setRect(rect)
class mainWindow(QMainWindow): # Metodo constructor de la clase def __init__(self): #Inicia el objeto QMainWindow QMainWindow.__init__(self) #carga la configuracion del archivo .ui en el objeto loadUi("mainWindowPPG.ui", self) # Loads everything about mainWindowPPG configuration self.setupUI() # Shared variables, initial values self.queue = Queue(N_SAMPLES) self.dataR = deque([], maxlen=N_SAMPLES) self.dataIR = deque([], maxlen=N_SAMPLES) self.TIME = deque([], maxlen=N_SAMPLES) self._plt = None self._timer_plot = None self.plot_colors = ['#0072bd', '#d95319'] # configures self._configure_plot() self._configure_timers() self._configure_signals() # Loads everything about mainWindowPPG configuration def setupUI(self): """ Configures everything about the mainWindow """ self.plt = GraphicsLayoutWidget( self.centralwidget) # Bringing my plot wiindow as plt self.plt.setAutoFillBackground(False) self.plt.setStyleSheet("border: 0px;") self.plt.setFrameShape(QtWidgets.QFrame.StyledPanel) self.plt.setFrameShadow(QtWidgets.QFrame.Plain) self.plt.setLineWidth(0) self.Layout_graphs.addWidget(self.plt, 0, 0, 1, 1) # Set the plotting squared graph def _configure_plot(self): """ Configures specific elements of the PyQtGraph plots. :return: """ self.plt.setBackground(background=None) self.plt.setAntialiasing(True) self._plt = self.plt.addPlot(row=1, col=1) self._plt.setLabel('bottom', "Time", "s") pass def _configure_timers(self): """ Configures specific elements of the QTimers. :return: """ self._timer_plot = QtCore.QTimer( self) # gives _timer_plot the attribute of QtCore.QTimer self._timer_plot.timeout.connect( self._update_plot) # connects with _update_plot method pass def _update_plot(self): """ Updates and redraws the graphics in the plot. This function us connected to the timeout signal of a QTimer. :return: """ # Spo2 signal parameters f = 2 amp1 = 0.5 # amplitud for Sine signal zeroDes1 = 0.5413 # Desplacement from zero for Sine signal amp2 = 0.5 # amplitud for Cosine signal zeroDes2 = 1.5413 # Desplacement from zero for Cosine signal # generate the time tsignal = time() - self.timestamp # Sine signal function sR = zeroDes1 + amp1 * 0.8 * np.sin(2 * np.pi * tsignal * 3 * f) # Cosine signal function sIR = zeroDes2 + amp2 * 0.8 * np.cos(2 * np.pi * tsignal * 3 * f) # put the data generate (time & signal) into queue self.queue.put([tsignal, sR, sIR]) # get the data generate into queue data = self.queue.get(True, 1) # store data into variables self.TIME.append(data[0]) self.dataR.append(data[1]) self.dataIR.append(data[2]) # Draw new data self._plt.clear() self._plt.plot(x=list(self.TIME)[-PLOT_UPDATE_POINTS:], y=list(self.dataR)[-PLOT_UPDATE_POINTS:], pen=self.plot_colors[1]) self._plt.plot(x=list(self.TIME)[-PLOT_UPDATE_POINTS:], y=list(self.dataIR)[-PLOT_UPDATE_POINTS:], pen=self.plot_colors[0]) def _configure_signals(self): """ Configures the connections between signals and UI elements. :return: """ self.startButton.clicked.connect(self.start) self.stopButton.clicked.connect(self.stop) def start(self): """ Starts the acquisition of the selected serial port. This function is connected to the clicked signal of the Start button. :return: """ self.timestamp = time() self._timer_plot.start(16) def stop(self): """ Stops the acquisition of the selected serial port. This function is connected to the clicked signal of the Stop button. :return: """ self._timer_plot.stop() # stop the Qt timer self.reset_buffers() # Go to reset the vector containing values def reset_buffers(self): self.dataR.clear() self.dataIR.clear() self.TIME.clear()
class MainWindow(QWidget): _icon = "./docs/20190702211158.jpg" _size_of_x = 800 _size_of_y = 450 _size_of_profile_x = 300 _size_of_profile_y = 300 def __init__(self, user): super(MainWindow, self).__init__() # user info self.user_account_name = "UniversalVoyage" self.user_name = "UniversalVoyage" self.user_id = "3118113030" self.user_gender = "男" self.user_room = "413" self.user_enter_date = "2020-10-25" self.user_unique = "not defined" self.profile = "./docs/20190702211158.jpg" self._get_user_info(user) self.profile = self._get_user_profile(self.user_unique) self.ip_address = "not defined" self.port = "not defined" # make directories for user self._make_user_dir() # set ICON self.Icon = QIcon(self._icon) # set sub-window self.acquire_win = None self.data_manager_win = None self.data_sync_win = None self.log_win = None self.getIP_win = None # set label self.gender = QLabel(self) self.ID = QLabel(self) self.username = QLabel(self) self.EnterDate = QLabel(self) self.Profile = QLabel(self) self.HeartRate = QLabel(self) self.BloodPressure = QLabel(self) self.RespirationRate = QLabel(self) self.ECG = QLabel(self) self.SpO2 = QLabel(self) self.PulseWave = QLabel(self) self.Respiration = QLabel(self) self.Video = QLabel(self) # set data graph pg.setConfigOption('background', '#f0f0f0') pg.setConfigOption('foreground', 'd') pg.setConfigOptions(antialias=True) self.central_widget = QtWidgets.QWidget(self) self.ECG_graph = GraphicsLayoutWidget(self) self.Pulse_graph = GraphicsLayoutWidget(self) self.RESP_graph = GraphicsLayoutWidget(self) # fake data # data = np.loadtxt("./docs/data/yuhang4131130301/ECG/filtered/data332_Channel1_dec.txt") # data2 = np.loadtxt("./docs/data/yuhang4131130301/ECG/filtered/data312_Channel1_dec.txt") # print(data.shape) # print(data2.shape) # self.ECG_graph.addPlot(y=data, pen=pg.mkPen(color='b', width=2)) # self.Pulse_graph.addPlot(y=data, pen=pg.mkPen(color='b', width=2)) # self.RESP_graph.addPlot(y=data2, pen=pg.mkPen(color='b', width=2)) self.valueOfHeartRate = QLabel() self.valueOfBloodPressure = QLabel() self.valueOfRespRate = QLabel() self.valueOfSpO2 = QLabel() # set button self.Acquire = QPushButton() self.CheckAndManage = QPushButton() self.Synchronize = QPushButton() self.Log = QPushButton() self.VideoSaving = QPushButton() self.Pause = QPushButton() self.Stop = QPushButton() self.ChangeIP = QPushButton() # set layout self.vertical_layout = QVBoxLayout() self.horizon_top_layout = QHBoxLayout() self.vertical_top_left_info_layout = QVBoxLayout() self.horizon_top_left_button_layout = QHBoxLayout() self.horizon_top_left_profile = QHBoxLayout() self.vertical_top_left_layout = QVBoxLayout() self.horizon_top_right_layout = QHBoxLayout() self.vertical_right_top_left_layout = QVBoxLayout() self.vertical_bottom_layout = QVBoxLayout() self.horizon_bottom_top_layout_value = QHBoxLayout() self.horizon_bottom_left_layout_ECG = QHBoxLayout() self.horizon_bottom_left_layout_PW = QHBoxLayout() self.horizon_bottom_left_layout_RESP = QHBoxLayout() self.video_thread = CameraHandler(self.Video, self.user_name, self.user_unique) self.video_thread.signal.connect(self._slot_video_saving) # add item self._add_label() self._add_button() # set layout self._set_ui() def _set_ui(self): """ set the graph layout :return: none """ self.setLayout(self.vertical_layout) self.setWindowTitle("欢迎使用!" + self.user_name) # desktop = QtWidgets.QApplication.desktop() # self._size_of_x = desktop.width() # self._size_of_y = desktop.height() self.setWindowIcon(self.Icon) # self.resize(self._size_of_x, self._size_of_y) # print(self._size_of_x.__str__() + " " + self._size_of_y.__str__()) self.setWindowState(Qt.WindowMaximized) # print(self.height()) print(self.geometry().width(), self.geometry().height()) # self.setFixedWidth(26) # self.setFixedHeight(650) # self.setFixedSize(self.width(), self.height()) # set left-top-mid # self.vertical_left_top_right_layout.addStretch(0) self.vertical_top_left_info_layout.addWidget(self.username) self.vertical_top_left_info_layout.addWidget(self.gender) self.vertical_top_left_info_layout.addWidget(self.ID) self.vertical_top_left_info_layout.addWidget(self.EnterDate) # set left-top-right self.horizon_top_left_button_layout.addWidget(self.Acquire) # self.horizon_top_left_button_layout.addStretch(0) self.horizon_top_left_button_layout.addWidget(self.CheckAndManage) # self.horizon_top_left_button_layout.addStretch(0) self.horizon_top_left_button_layout.addWidget(self.Synchronize) # self.horizon_top_left_button_layout.addStretch(0) self.horizon_top_left_button_layout.addWidget(self.ChangeIP) # self.horizon_top_left_button_layout.addStretch(0) self.horizon_top_left_button_layout.addWidget(self.Log) self.horizon_top_left_button_layout.addStretch(0) # set left-top self.horizon_top_left_profile.addWidget(self.Profile, alignment=Qt.AlignBottom) self.horizon_top_left_profile.addLayout( self.vertical_top_left_info_layout) self.horizon_top_left_profile.addStretch(0) self.vertical_top_left_layout.addLayout(self.horizon_top_left_profile) self.vertical_top_left_layout.addLayout( self.horizon_top_left_button_layout) # set top-right self.vertical_right_top_left_layout.addWidget(self.VideoSaving) # self.vertical_right_top_left_layout.addStretch(0) self.vertical_right_top_left_layout.addWidget(self.Pause) # self.vertical_right_top_left_layout.addStretch(0) self.vertical_right_top_left_layout.addWidget(self.Stop) self.horizon_top_right_layout.addLayout( self.vertical_right_top_left_layout) self.horizon_top_right_layout.addWidget(self.Video) # set top self.horizon_top_layout.addLayout(self.vertical_top_left_layout) self.horizon_top_layout.addLayout(self.horizon_top_right_layout) # set bottom-left self.horizon_bottom_top_layout_value.addWidget(self.HeartRate) self.horizon_bottom_top_layout_value.addWidget(self.valueOfHeartRate) self.horizon_bottom_top_layout_value.addStretch(0) self.horizon_bottom_top_layout_value.addWidget(self.BloodPressure) self.horizon_bottom_top_layout_value.addWidget( self.valueOfBloodPressure) self.horizon_bottom_top_layout_value.addStretch(0) self.horizon_bottom_top_layout_value.addWidget(self.RespirationRate) self.horizon_bottom_top_layout_value.addWidget(self.valueOfRespRate) self.horizon_bottom_top_layout_value.addStretch(0) self.horizon_bottom_top_layout_value.addWidget(self.SpO2) self.horizon_bottom_top_layout_value.addWidget(self.valueOfSpO2) self.horizon_bottom_top_layout_value.addStretch(0) # self.vertical_bottom_layout.addLayout(self.horizon_bottom_top_layout_value) self.horizon_bottom_left_layout_ECG.addWidget(self.ECG) self.horizon_bottom_left_layout_ECG.addWidget(self.ECG_graph) # self.horizon_bottom_left_layout_ECG.addStretch(0) self.vertical_bottom_layout.addLayout( self.horizon_bottom_left_layout_ECG) self.horizon_bottom_left_layout_PW.addWidget(self.PulseWave) self.horizon_bottom_left_layout_PW.addWidget(self.Pulse_graph) # self.horizon_bottom_left_layout_PW.addStretch(0) self.vertical_bottom_layout.addLayout( self.horizon_bottom_left_layout_PW) self.horizon_bottom_left_layout_RESP.addWidget(self.Respiration) self.horizon_bottom_left_layout_RESP.addWidget(self.RESP_graph) # self.horizon_bottom_left_layout_RESP.addStretch(0) self.vertical_bottom_layout.addLayout( self.horizon_bottom_left_layout_RESP) # set the whole layout self.vertical_layout.addLayout(self.horizon_top_layout) # self.vertical_layout.addStretch(0) self.vertical_layout.addLayout(self.horizon_bottom_top_layout_value) # self.vertical_layout.addStretch(0) self.vertical_layout.addLayout(self.vertical_bottom_layout) def _add_button(self): """ set the button to operate the video and the other common function :return: none """ # set the font of button font_of_button = QFont() font_of_button.setFamily('Times') font_of_button.setPixelSize(22) self.Acquire.setFont(font_of_button) self.CheckAndManage.setFont(font_of_button) self.Synchronize.setFont(font_of_button) self.ChangeIP.setFont(font_of_button) self.Log.setFont(font_of_button) self.VideoSaving.setFont(font_of_button) self.Pause.setFont(font_of_button) self.Stop.setFont(font_of_button) self.Acquire.setText("数据采集") self.CheckAndManage.setText("查看与管理") self.Synchronize.setText("数据同步") self.ChangeIP.setText("修改IP") self.Log.setText("查看报告") self.VideoSaving.setText("保存") self.Pause.setText("开始") self.Stop.setText("暂停") self.Acquire.setFixedSize(165, 100) self.CheckAndManage.setFixedSize(165, 100) self.Synchronize.setFixedSize(165, 100) self.ChangeIP.setFixedSize(165, 100) self.Log.setFixedSize(165, 100) self.VideoSaving.setFixedSize(100, 100) self.Pause.setFixedSize(100, 100) self.Stop.setFixedSize(100, 100) self.Acquire.clicked.connect(self._slot_acquire) self.CheckAndManage.clicked.connect(self._slot_data_manager) self.Synchronize.clicked.connect(self._slot_get_ip) self.Log.clicked.connect(self._slot_log_check) self.VideoSaving.clicked.connect(self._slot_video_saving) self.Pause.clicked.connect(self._slot_video_start) self.ChangeIP.clicked.connect(self._slot_change_ip) def _add_label(self): """ labels contain the tips and user's information :return: none """ font_of_profile = QFont() font_of_profile.setFamily('Times') font_of_profile.setPixelSize(55) font_of_info = QFont() font_of_info.setFamily('Times') font_of_info.setPixelSize(35) self.Profile.setFont(font_of_profile) self.username.setFont(font_of_profile) self.gender.setFont(font_of_profile) self.ID.setFont(font_of_profile) self.EnterDate.setFont(font_of_profile) self.HeartRate.setFont(font_of_info) self.BloodPressure.setFont(font_of_info) self.RespirationRate.setFont(font_of_info) self.ECG.setFont(font_of_info) self.SpO2.setFont(font_of_info) self.PulseWave.setFont(font_of_info) self.Respiration.setFont(font_of_info) self.valueOfHeartRate.setFont(font_of_info) self.valueOfBloodPressure.setFont(font_of_info) self.valueOfRespRate.setFont(font_of_info) self.valueOfSpO2.setFont(font_of_info) self.valueOfHeartRate.setText("--") self.valueOfBloodPressure.setText("--") self.valueOfRespRate.setText("--") self.valueOfSpO2.setText("--") # set the text color self.HeartRate.setStyleSheet("color:green") self.BloodPressure.setStyleSheet("color:green") self.RespirationRate.setStyleSheet("color:green") self.ECG.setStyleSheet("color:green") self.SpO2.setStyleSheet("color:green") self.PulseWave.setStyleSheet("color:green") self.Respiration.setStyleSheet("color:green") self.valueOfHeartRate.setStyleSheet("color:green") self.valueOfBloodPressure.setStyleSheet("color:green") self.valueOfRespRate.setStyleSheet("color:green") self.valueOfSpO2.setStyleSheet("color:green") # this will be replaced by the user's image later self.Profile.setPixmap( QPixmap(self.profile).scaled(self._size_of_profile_x, self._size_of_profile_y)) self.username.setText("用户姓名:" + self.user_name) self.gender.setText("性别:" + self.user_gender) self.ID.setText("身份编号:" + self.user_unique) self.EnterDate.setText("入园日期:" + self.user_enter_date) # this will be replaced by the video preview later self.Video.setFixedSize(720, 400) self.Video.setPixmap((QPixmap("./docs/20191012094812.jpg"))) self.HeartRate.setText("心率:") self.BloodPressure.setText("血压:") self.RespirationRate.setText("呼吸率:") self.ECG.setText("心电:") self.SpO2.setText("血氧:") self.PulseWave.setText("脉搏:") self.Respiration.setText("呼吸:") def _get_user_info(self, user): """ get the user's information :param user: a list contains the user's information :return: none """ if len(user) == 0: return self.user_account_name = user[0] self.user_name = user[2] self.user_id = user[3] if user[4] == "male": self.gender = "男" else: self.gender = "女" self.user_room = user[5] date = user[-2] self.user_enter_date = date[:4] + "-" + date[4:6] + "-" + date[-2:] self.user_unique = user[-1] # print(self.user_unique) def _get_user_profile(self, unique): """ set the user's profile search the profile in the database by user's unique id. :param unique: the user's unique id :return: the path that stored the user's profile """ if unique == "not defined": # print(unique) return self._icon db = pymysql.connect(host='localhost', user='******', password='******', db='user') cursor = db.cursor() result = None sql = "SELECT * FROM PROFILE WHERE unique_id='%s';" % unique try: cursor.execute(sql) result = cursor.fetchall() except Exception as e: print(e.__str__()) # print(len(result)) if len(result) == 0: return self.profile return result[0][-1] def _slot_acquire(self): """ open the BLE managing window :return: none """ self.acquire_win = BLE(self.user_unique) self.acquire_win.signal.connect(self._update_data) # self.acquire_win = BLEwithBleak() self.acquire_win.show() def _update_data(self): """ update the recently acquired data :return: none """ day = str(time.strftime("%Y%m%d", time.localtime())) # set database db = None # cursor = None try: db = pymysql.connect(host='localhost', user='******', password='******', db='user') # cursor = db.cursor() except Exception as e: print("database connection wrong" + e.__str__()) result = None try: cursor = db.cursor() sql = "select * from USERDATA where (unique_id='%s' and date='%s') order by data_number" % \ (self.user_unique, day) cursor.execute(sql) result = cursor.fetchall() except Exception as e: print("select data wrong" + e.__str__()) # //-get the data to display # //-by the way, this part of code is definite a piece of shit. # //-however, I cannot find a more decent way to go. mark_ecg = False mark_resp = False mark_pulse = False mark_hr = False mark_respr = False mark_spo2 = False mark_bp = False ecg_new = None resp_new = None pulse_new = None hr_new = None respr_new = None spo2_new = None bp_new = None for i in range(len(result)): if result[i][5] == "ECG" and mark_ecg is not True: mark_ecg = True ecg_new = np.loadtxt(result[i][6]) if result[i][5] == "RESP" and mark_resp is not True: mark_resp = True resp_new = np.loadtxt(result[i][6]) if result[i][5] == "PULSE" and mark_pulse is not True: mark_pulse = True pulse_new = np.loadtxt(result[i][6]) if result[i][5] == "HR" and mark_hr is not True: mark_hr = True hr_new = result[i][6] if result[i][5] == "RESPR" and mark_respr is not True: mark_respr = True respr_new = result[i][6] if result[i][5] == "SPO2" and mark_spo2 is not True: mark_spo2 = True spo2_new = result[i][6] if result[i][5] == "BP" and mark_bp is not True: mark_bp = True bp_new = result[i][6] if mark_ecg: self.ECG_graph.addPlot(y=ecg_new, pen=pg.mkPen(color='b', width=2)) if mark_pulse: self.Pulse_graph.addPlot(y=pulse_new, pen=pg.mkPen(color='b', width=2)) if mark_resp: self.RESP_graph.addPlot(y=resp_new, pen=pg.mkPen(color='b', width=2)) if mark_hr: self.valueOfHeartRate.setText(hr_new) if mark_bp: self.valueOfBloodPressure.setText(bp_new) if mark_spo2: self.valueOfSpO2.setText(spo2_new) if mark_respr: self.valueOfRespRate.setText(respr_new) # //-THE shit is over. def _slot_data_manager(self): """ open the Data manager window :return: none """ # print(self.user_unique) self.data_manager_win = DataManager(self.user_unique) self.data_manager_win.show() def _slot_data_sync(self): """ open the data synchronizing window :return: none """ self.data_sync_win = Synchronize(self.user_unique, self.ip_address, self.port) self.data_sync_win.show() def _slot_change_ip(self): """ change the IP address, if the wrong IP was input. :return: none """ self.getIP_win = GetIP() self.getIP_win.signal.connect(self._slot_set_ip) self.getIP_win.show() def _slot_get_ip(self): """ get the server's ip address :return: none """ if self.ip_address == "not defined" and self.port == "not defined": self.getIP_win = GetIP() self.getIP_win.signal.connect(self._slot_set_ip) self.getIP_win.show() else: self._slot_data_sync() def _slot_set_ip(self, message): """ set the ip address :return: none """ self.ip_address = message['ip'] self.port = message['port'] print("ip: " + self.ip_address + " port: " + self.port) self._slot_data_sync() def _slot_log_check(self): """ open the log manager window :return: none """ self.log_win = LogManager(self.user_unique) self.log_win.show() def _slot_video_saving(self): """ save the video and stop the thread. :return: none """ if not self.video_thread.setter(): QMessageBox.information(self, '保存成功!', '视频已保存!', QMessageBox.Ok) else: QMessageBox.information(self, '保存失败!', '视频未保存!', QMessageBox.Ok) def _slot_video_start(self): """ start the video recording. :return: none """ if self.video_thread.working: # print(1) self.video_thread.start() else: # print(2) self.video_thread.setter() self.video_thread.start() def _make_user_dir(self): """ make the data directories for user :return: none """ if self.user_unique == "not defined": return data = "./docs/data/" path = data + self.user_name + self.user_unique + "/" # user's own dir ecg = path + "ECG/" # ECG ecg_original = ecg + "original/" ecg_filtered = ecg + "filtered/" resp = path + "RESP/" # respiration resp_original = resp + "original/" resp_filtered = resp + "filtered/" pulse = path + "PULSE/" # pulse wave pulse_original = pulse + "original/" pulse_filtered = pulse + "filtered/" video = path + "VIDEO/" # video log = path + "LOG" if not os.path.exists(path): try: os.mkdir(path) except Exception as e: print(e.__str__()) if not os.path.exists(ecg): try: os.mkdir(ecg) except Exception as e: print(e.__str__()) if not os.path.exists(ecg_original): try: os.mkdir(ecg_original) except Exception as e: print(e.__str__()) if not os.path.exists(ecg_filtered): try: os.mkdir(ecg_filtered) except Exception as e: print(e.__str__()) if not os.path.exists(resp): try: os.mkdir(resp) except Exception as e: print(e.__str__()) if not os.path.exists(resp_original): try: os.mkdir(resp_original) except Exception as e: print(e.__str__()) if not os.path.exists(resp_filtered): try: os.mkdir(resp_filtered) except Exception as e: print(e.__str__()) if not os.path.exists(pulse): try: os.mkdir(pulse) except Exception as e: print(e) if not os.path.exists(pulse_original): try: os.mkdir(pulse_original) except Exception as e: print(e.__str__()) if not os.path.exists(pulse_filtered): try: os.mkdir(pulse_filtered) except Exception as e: print(e.__str__()) if not os.path.exists(video): try: os.mkdir(video) except Exception as e: print(e.__str__()) if not os.path.exists(log): try: os.mkdir(log) except Exception as e: print(e.__str__()) else: return def closeEvent(self, event): """ handle the main window closing event :param event: the main window closing event :return: none """ question = QMessageBox() question.setWindowTitle("退出") question.setText("确认要退出吗?") question.setIcon(QMessageBox.Question) question.setStandardButtons(QMessageBox.Yes | QMessageBox.No) question.setDefaultButton(QMessageBox.No) yes = question.button(QMessageBox.Yes) no = question.button(QMessageBox.No) yes.setText("确定") no.setText("取消") question.exec_() # //-when the main window is about to close, ask user to choose operation. if question.clickedButton() == yes: event.accept() else: event.ignore()
class Aditi(QMainWindow): def __init__(self): QMainWindow.__init__(self) # title self.setWindowTitle("Aditi") self.setDockOptions(QMainWindow.VerticalTabs | QMainWindow.AnimatedDocks) #self.showMaximized() # model self.rawfiles_by_short_path = {} self.xic_by_rawfile_short_path = {} self.tic_by_rawfile_short_path = {} self.spec_by_rawfile_short_path = {} self.inf_line_tic_item = None self.curr_scan_id_by_short_path = {} # menu self.file_menu = self.menuBar().addMenu('&File') #self.file_menu.setTearOffEnabled(False) open_action = QAction("&Open...", self) open_action.setToolTip("Open a rawfile") open_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_O)) self.file_menu.addAction(open_action) open_action.triggered.connect(self.show_open_dialog) exit_action = QAction("&Exit", self) exit_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_Q)) self.file_menu.addAction(exit_action) exit_action.triggered.connect(self.quit) self.tab_widget = QTabWidget(self) # spectrum plot Widget self.graphics_layout_widget = GraphicsLayoutWidget(parent=self.tab_widget) self.graphics_layout_widget.keyPressEvent = self.handle_key_press_event self.graphics_layout_widget.useOpenGL(False) self.graphics_layout_widget.setAntialiasing(False) self.plot_widget_tic = self.graphics_layout_widget.addPlot(title="TIC(s)", labels={'left': "Intensity", 'bottom': "Retention Time (sec)"}) self.plot_widget_tic.showGrid(x=True, y=True) self.graphics_layout_widget.nextRow() self.plot_widget_spectrum = self.graphics_layout_widget.addPlot(title="Spectrum", labels={'left': "Intensity", 'bottom': "m/z"}) self.plot_widget_spectrum.showGrid(x=True, y=True) # finally add tab self.tab_widget.addTab(self.graphics_layout_widget, "Spectrum") # Xic plotWidget self.plot_widget_xic = PlotWidget(name="MainPlot", labels={'left': "Intensity", 'bottom': "Retention Time (sec)"}) self.plot_widget_xic.showGrid(x=True, y=True) self.tab_widget.addTab(self.plot_widget_xic, "Xic extraction") self.setCentralWidget(self.tab_widget) self.statusBar().showMessage("Ready") # dock 1 self.rawfile_dock_widget = QDockWidget("Rawfiles") self.rawfile_table_view = QTableView() self.rawfile_table_view.horizontalHeader().setVisible(False) self.rawfile_table_view.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents) self.rawfile_dock_widget.setWidget(self.rawfile_table_view) self.rawfile_model = QStandardItemModel() self.rawfile_model.setHorizontalHeaderLabels(["Rawfiles"]) self.rawfile_table_view.setModel(self.rawfile_model) self.rawfile_model.itemChanged.connect(self.item_changed) self.addDockWidget(0x2, self.rawfile_dock_widget) # xic dock widget extraction parameter self.xic_dock_widget = QDockWidget("Xic extraction") self.xic_widget = XicWidget() self.xic_widget.plotButton.clicked.connect(self.plot) self.xic_dock_widget.setWidget(self.xic_widget) self.addDockWidget(0x2, self.xic_dock_widget) def handle_key_press_event(self, evt): if self.inf_line_tic_item is None: return times = [] if evt.key() == Qt.Key_Left: for rawfile in self.rawfiles_by_short_path.values()[:1]: if not rawfile.is_checked: continue curr_scan_id = self.curr_scan_id_by_short_path[rawfile.short_path] scan_ids = rawfile.reader.rt_by_scan_id_by_ms_level[1].keys() idx = scan_ids.index(curr_scan_id) times.append(rawfile.reader.rt_by_scan_id_by_ms_level[1][scan_ids[idx - 1]]) self.curr_scan_id_by_short_path[rawfile.short_path] = scan_ids[idx - 1] elif evt.key() == Qt.Key_Right: for rawfile in self.rawfiles_by_short_path.values()[:1]: if not rawfile.is_checked: continue curr_scan_id = self.curr_scan_id_by_short_path[rawfile.short_path] scan_ids = rawfile.reader.rt_by_scan_id_by_ms_level[1].keys() idx = scan_ids.index(curr_scan_id) times.append(rawfile.reader.rt_by_scan_id_by_ms_level[1][scan_ids[idx + 1]]) self.curr_scan_id_by_short_path[rawfile.short_path] = scan_ids[idx + 1] self._plot_spectrum() if times: self.inf_line_tic_item.setPos(sum(times) / float(len(times))) def _plot_spectrum(self): self.plot_widget_spectrum.clear() min_mz, max_mz = 1e9, 0 min_int, max_int = 1e10, 0 for rawfile in self.rawfiles_by_short_path.values(): if not rawfile.is_checked: continue scan_id, mzs, intensities = rawfile.reader.get_scan(self.curr_scan_id_by_short_path[rawfile.short_path]) min_mz = min(min_mz, mzs[0]) max_mz = max(max_mz, mzs[-1]) min_int = min(min_int, min(intensities)) max_int = max(max_int, max(intensities)) item = BarGraphItem(x=mzs, height=intensities, width=0.01, pen=rawfile.qcolor, brush=rawfile.qcolor) self.plot_widget_spectrum.addItem(item) self.plot_widget_spectrum.setLimits(xMin=min_mz, xMax=max_mz, yMin=min_int, yMax=max_int) def plot_spectrum(self, ev): #clear if ev.button() == Qt.RightButton: return self.plot_widget_spectrum.clear() vb = self.plot_widget_tic.vb mouse_point = vb.mapSceneToView(ev.scenePos()) t = mouse_point.x() if self.inf_line_tic_item is None: self.inf_line_tic_item = InfiniteLine(pos=t, angle=90) self.plot_widget_tic.addItem(self.inf_line_tic_item) self.inf_line_tic_item.setMovable(True) else: self.inf_line_tic_item.setPos(t) min_mz, max_mz = 1e9, 0 min_int, max_int = 1e10, 0 for rawfile in self.rawfiles_by_short_path.values(): if not rawfile.is_checked: continue scan_id, mzs, intensities = rawfile.reader.get_scan_for_time(t) self.curr_scan_id_by_short_path[rawfile.short_path] = scan_id min_mz = min(min_mz, mzs[0]) max_mz = max(max_mz, mzs[-1]) min_int = min(min_int, min(intensities)) max_int = max(max_int, max(intensities)) item = BarGraphItem(x=mzs, height=intensities, width=0.01, pen=rawfile.qcolor, brush=rawfile.qcolor) self.plot_widget_spectrum.addItem(item) self.plot_widget_spectrum.setLimits(xMin=min_mz, xMax=max_mz, yMin=min_int, yMax=max_int) def item_changed(self, item): print "item changed", item.text() s = item.text() if item.checkState(): self.rawfiles_by_short_path[s].is_checked = True else: self.rawfiles_by_short_path[s].is_checked = False #self.qApp.emit(SIGNAL('redraw()')) self.update_plot_() def show_open_dialog(self): files = QFileDialog(self).getOpenFileNames() if files: preload = Preloader(files, self) preload.loaded.connect(self.update_rawfile_model) preload.start() def update_rawfile_model(self, obj): files, r = obj[0], obj[1] n = len(files) not_database = [] min_time, max_time = 1e9, 0 min_int, max_int = 1e9, 0 for i, f in enumerate(files): i_f = float(i) c = WithoutBlank.get_color(i_f / n, asQColor=True) c_ = WithoutBlank.get_color(i_f / n, asQColor=True) filename = f.split("\\")[-1] abs_path = str(f.replace("\\", "\\\\")) if r[i]: rawfile = Rawfile(abs_path, c, filename) self.rawfiles_by_short_path[filename] = rawfile #[MzDBReader(abs_path), c, True] self.rawfile_model.appendRow(Aditi.get_coloured_root_item(filename, c, c_)) times, intensities = rawfile.reader.get_tic() min_time = min(min_time, min(times)) max_time = max(max_time, max(times)) min_int = min(min_int, min(intensities)) max_int = max(max_int, max(intensities)) self.plot_widget_tic.plot(times, intensities, pen=mkPen(color=rawfile.qcolor, width=1.3)) else: not_database.append(str(filename)) self.plot_widget_tic.setLimits(xMin=min_time, xMax=max_time, yMin=min_int, yMax=max_int) self.plot_widget_tic.scene().sigMouseClicked.connect(self.plot_spectrum) if not_database: v = "\n".join(not_database) QMessageBox.information(self, "Error", "The following files are not valid sqlite database:\n" + v) @staticmethod def get_coloured_root_item(filepath, color, colorr): root = QStandardItem(filepath) gradient = QLinearGradient(-100, -100, 100, 100) gradient.setColorAt(0.7, colorr) gradient.setColorAt(1, color) root.setBackground(QBrush(gradient)) root.setEditable(False) root.setCheckState(Qt.Checked) root.setCheckable(True) return root def quit(self): res = QMessageBox.warning(self, "Exiting...", "Are you sure ?", QMessageBox.Ok | QMessageBox.Cancel) if res == QMessageBox.Cancel: return QtGui.qApp.quit() def plot(self): #clear pw self.plot_widget_xic.clear() # check sample checked checked_files = [rawfile for rawfile in self.rawfiles_by_short_path.values() if rawfile.is_checked] mz = self.xic_widget.mzSpinBox.value() mz_tol = self.xic_widget.mzTolSpinBox.value() mz_diff = mz * mz_tol / 1e6 min_mz, max_mz = mz - mz_diff, mz + mz_diff #Thread implementation not as fast # args = [(data[0], min_mz, max_mz, data[2]) for data in checked_files] # extractor_thread = Extractor(args, self) # extractor_thread.extracted.connect(self._plot) # extractor_thread.start() min_time_val, max_time_val = 10000, 0 min_int_val, max_int_val = 1e9, 0 for rawfile in checked_files: t1 = time.clock() times, intensities = rawfile.reader.get_xic(min_mz, max_mz) print "elapsed: ", time.clock() - t1 # min_time_val = min(min_time_val, times[0]) # max_time_val = max(max_time_val, times[-1]) # min_int_val = min(min_int_val, min(intensities)) # max_int_val = max(max_int_val, max(intensities)) item = self.plot_widget_xic.plot(times, intensities, pen=mkPen(color=rawfile.qcolor, width=1.3)) item.curve.setClickable(True) def on_curve_clicked(): if not rawfile.is_highlighted: item.setPen(mkPen(color=rawfile.qcolor, width=4)) rawfile.is_highlighted = True else: item.setPen(mkPen(color=rawfile.qcolor, width=2)) rawfile.is_highlighted = False item.sigClicked.connect(on_curve_clicked) #item.sigHovered = on_curve_clicked self.xic_by_rawfile_short_path[rawfile.short_path] = item self.plot_widget_xic.setTitle(title="Xic@" + str(mz)) #self.plot_widget_xic.setLimits(xMin=min_time_val, xMax=max_time_val, yMin=min_int_val, yMax=max_int_val) def update_plot_(self): for rawfile in self.rawfiles_by_short_path.viewvalues(): if rawfile.is_checked: try: self.plot_widget_xic.addItem(self.xic_by_rawfile_short_path[rawfile.short_path]) except KeyError: mz = self.xic_widget.mzSpinBox.value() mz_tol = self.xic_widget.mzTolSpinBox.value() mz_diff = mz * mz_tol / 1e6 min_mz, max_mz = mz - mz_diff, mz + mz_diff times, intensities = rawfile.reader.get_xic(min_mz, max_mz) item = self.plot_widget_xic.plot(times, intensities, pen=mkPen(color=rawfile.qcolor, width=2)) self.xic_by_rawfile_short_path[rawfile.short_path] = item else: try: #self.plot_widget_xic.removeItem(self.xic_by_rawfile_short_path[rawfile.short_path]) self.xic_by_rawfile_short_path[rawfile.short_path].hide() except KeyError: pass
class AttributeViewer(QWidget): """ Show a scatter plot of two attributes from a set of localizations. init ---- locs_path : str, path to a CSV with localization data max_spots : int, the maximum number of spots to plot. It's often too costly to render more than 30000 spots or so gui_size : int parent : root QWidget """ def __init__(self, locs_path, max_spots=10000, gui_size=600, parent=None): super(AttributeViewer, self).__init__(parent=parent) self.locs_path = locs_path self.max_spots = max_spots self.gui_size = gui_size self.initData() self.initUI() def initData(self): """ Load the spots data. """ # Load the locs dataframe self.locs = pd.read_csv(self.locs_path).sort_values(by='frame') # If too many spots, truncate the dataframe if len(self.locs) > self.max_spots: print("Truncating dataframe to %d spots" % self.max_spots) self.locs = self.locs[:self.max_spots] else: print("Plotting %d spots" % len(self.locs)) # List of available attributes to display dtypes = [ 'float64', 'float', 'int64', 'int32', 'uint16', 'uint8', 'int' ] self.parameters = [c for c in self.locs.columns if \ self.locs[c].dtype in dtypes] # Generate colormap self.n_colors = 1000 self.cmap = cm.get_cmap('viridis', self.n_colors) self.cmap_hex = np.array([mpl_colors.rgb2hex(self.cmap(i)[:3]) \ for i in range(self.n_colors)]) def initUI(self): """ Initialize the user interface. """ # Main window self.win = QWidget() L = QGridLayout(self.win) self.win.resize(self.gui_size * 1.8, self.gui_size) # Two subwindows: one on the left for the scatter plot # and one on the right for widgets self.win_left = QWidget(self.win) self.win_right = QWidget(self.win) L.addWidget(self.win_left, 0, 0, 1, 3) L.addWidget(self.win_right, 0, 3, 1, 1) L_left = QGridLayout(self.win_left) L_right = QGridLayout(self.win_right) # GraphicsLayoutWidget, to organize scatter plot and # associated items self.graphicsLayoutWidget = GraphicsLayoutWidget(parent=self.win_left) # PlotItem, to contain the ScatterPlotItem self.plotItem = self.graphicsLayoutWidget.addPlot() L_left.addWidget(self.graphicsLayoutWidget, 0, 0) # ScatterPlotItem, core data display self.scatterPlotItem = ScatterPlotItem(symbol='o', brush=None, pxMode=True, pen={ 'color': '#FFFFFF', 'width': 4.0 }, size=4.0) self.plotItem.addItem(self.scatterPlotItem) ## WIDGETS widget_align = Qt.AlignTop # Select parameter to map to the x-axis self.M_par_0 = LabeledQComboBox(self.parameters, "x-parameter", init_value="x", parent=self.win_right) L_right.addWidget(self.M_par_0, 0, 0, alignment=widget_align) self.M_par_0.assign_callback(self.M_par_callback) # Select parameter to map to the y-axis self.M_par_1 = LabeledQComboBox(self.parameters, "y-parameter", init_value="y", parent=self.win_right) L_right.addWidget(self.M_par_1, 1, 0, alignment=widget_align) self.M_par_1.assign_callback(self.M_par_callback) # Select which attribute to color the localizations by options = self.parameters + ["density"] self.M_color_by = LabeledQComboBox(options, "Color by", init_value="density", parent=self.win_right) L_right.addWidget(self.M_color_by, 0, 1, alignment=widget_align) self.M_color_by.assign_callback(self.M_color_by_callback) # Select the size of the window to use when computing # localization density window_size_options = [ str(j) for j in [3, 5, 7, 9, 11, 13, 15, 19, 23, 31, 41, 61, 81, 101] ] self.M_density_window = LabeledQComboBox(window_size_options, "Density window", init_value="7", parent=self.win_right) L_right.addWidget(self.M_density_window, 1, 1, alignment=widget_align) self.M_density_window.assign_callback(self.M_density_window_callback) # Button to induce a simpler representation that can handle # more spots self.simple_mode = False self.B_simple = QPushButton("Simple scatter", parent=self.win_right) L_right.addWidget(self.B_simple, 2, 0, alignment=widget_align) self.B_simple.clicked.connect(self.B_simple_callback) # Button to toggle log color scaling self.log_scale_mode = True self.B_log = QPushButton("Log color scale", parent=self.win_right) self.B_log.clicked.connect(self.B_log_callback) L_right.addWidget(self.B_log, 2, 1, alignment=widget_align) # Empty widgets to manipulate the layout n_rows = 15 for j in range(3, n_rows): q = QWidget(self.win_right) L_right.addWidget(q, j, 0) # Show the main window self.update_scatter() self.win.show() ## CORE FUNCTIONS def get_pars(self): """ Get the current attributes mapped to the x and y axes of the scatter plot. returns ------- (str: x attribute, str: y attribute) """ return self.M_par_0.currentText(), self.M_par_1.currentText() def update_scatter(self, rescale=True): """ Update the scatter plot. args ---- rescale : change axis limits """ cx, cy = self.get_pars() # In the special case of plotting x vs y, make sure # that the aspect ratio is right if ((cx == 'x') and (cy == 'y')) or ((cx == 'y') and (cy == 'x')): self.plotItem.setAspectLocked(lock=True) else: self.plotItem.setAspectLocked(lock=False) # Update the scatter plots if self.simple_mode: self.scatter_simple(cx, cy) else: self.scatter_color(cx, cy) # Set axis labels labelStyle = {'font-size': '18pt'} self.plotItem.setLabel('bottom', text=cx, **labelStyle) self.plotItem.setLabel('left', text=cy, **labelStyle) # Change axis limits if rescale: self.plotItem.autoBtnClicked() def scatter_color(self, cx, cy): """ Load the current set of data into a new scatter plot, coloring by the current "color by" attribute. args ---- cx, cy : str, columns in self.locs """ self.scatterPlotItem.setData(size=4.0, brush=None) color_attrib = self.M_color_by.currentText() if color_attrib == 'density': densities, spots = self.make_density(cx, cy) else: spots = self.make_attrib_colors(color_attrib) self.scatterPlotItem.setData(spots=spots) def scatter_simple(self, cx, cy): """ A simpler way of representing the data, using black and white only. args ---- cx, cy : str, columns in self.locs """ self.scatterPlotItem.setData(self.locs[cx], self.locs[cy], pen=pg.mkPen(None), brush=pg.mkBrush(255, 255, 255, 10), size=10) def make_density(self, c0, c1): """ Get the normalized density of points along the (c0, c1) axis in the set of localizations. args ---- c0, c1 : str, columns in self.locs returns ------- ( 1D ndarray, the density of each point; dict, argument to pass to ScatterPlotItem.setData ) """ # Get the current density window size w = int(self.M_density_window.currentText()) # Format the desired two attributes as ndarray for # fast indexing data = np.asarray(self.locs[[c0, c1]]) # Each of the attributes could have very different # magnitudes, so scale the distances relative to the # difference between the 5th and 95th percentiles for # each attribute. # Special case: x and y get the same scaling if ((c0 == 'x') and (c1 == 'y')) or ((c0 == 'y') and (c1 == 'x')): ybinsize = 1.0 xbinsize = 1.0 else: norm = 400.0 ybinsize = (np.percentile(self.locs[c0], 95) - \ np.percentile(self.locs[c0], 5)) / norm xbinsize = (np.percentile(self.locs[c1], 95) - \ np.percentile(self.locs[c1], 5)) / norm # Create the binning scheme from these bin sizes ybinedges = np.arange(np.percentile(self.locs[c0], 0.1), np.percentile(self.locs[c0], 99.9), ybinsize) xbinedges = np.arange(np.percentile(self.locs[c1], 0.1), np.percentile(self.locs[c1], 99.9), xbinsize) # Bin the data H, _yedges, _xedges = np.histogram2d(self.locs[c0], self.locs[c1], bins=(ybinedges, xbinedges)) # Count the number of points in the neighborhood # of each point density = uniform_filter(H, w) # Digitize the data according to the binning scheme # X_int = ((data - np.array([ybinedges.min(), xbinedges.min()])) / \ # np.array([ybinsize, xbinsize])).astype('int64') # data_y_int = X_int[:,0] # data_x_int = X_int[:,1] data_y_int = np.digitize(data[:, 0], ybinedges) data_x_int = np.digitize(data[:, 1], xbinedges) # Determine which data points fall within the binning # scheme inside = (data_y_int>=0) & (data_x_int>=0) & \ (data_y_int<(len(ybinedges)-1)) & \ (data_x_int<(len(xbinedges)-1)) data_y_int_inside = data_y_int[inside] data_x_int_inside = data_x_int[inside] # Retrieve the densities for each point point_densities = np.empty(data.shape[0], dtype=density.dtype) point_densities[inside] = density[data_y_int_inside, data_x_int_inside] # Set points outside the binning scheme to density 1 point_densities[~inside] = 1.0 # Rescale a little point_densities = point_densities * (w**2) point_densities[point_densities <= 0] = 0.001 # Log-scale if self.log_scale_mode: point_densities = np.log(point_densities) / np.log(2.0) point_densities[point_densities < 0.0] = 0.0 # Rescale the point densities into color indices R = (point_densities * (self.n_colors - 1) / point_densities.max()).astype(np.int64) R[~inside] = 0 spot_colors = self.cmap_hex[R] # Format the plotting spot dict spots = [{'pos': data[i,:], 'pen': {'color': spot_colors[i], 'width': 3.0}} \ for i in range(data.shape[0])] return point_densities, spots def make_attrib_colors(self, attrib): """ Generate a spot format in which the color of each spot is keyed to a particular attribute, with appropriate rescaling for the different magnitudes of each attribute. args ---- attrib : str, a column in self.locs returns ------- dict, parameters to pass to ScatterPlotItem.setData """ # Current axis attributes c0, c1 = self.get_pars() # Sort by ascending attribute self.locs = self.locs.sort_values(by=attrib) XY = np.asarray(self.locs[[c0, c1]]) Z = np.asarray(self.locs[attrib]) # Filter out unsanitary values sanitary = (~np.isnan(Z)) & (~np.isinf(Z)) if (~sanitary).any(): print("Filtering out unsanitary values in %s" % attrib) XY = XY[sanitary, :] Z = Z[sanitary] # Log scale if self.log_scale_mode: Z[Z <= 0.0] = 0.001 Z = np.log(Z) / np.log(2.0) # Bin localizations by their relative value in # the color attribute norm = 400.0 try: binsize = (np.percentile(Z, 95) - np.percentile(Z, 5)) / norm binedges = np.arange(np.percentile(Z, 0.01), np.percentile(Z, 99.9), binsize) Z[Z < binedges.min()] = binedges.min() Z[Z >= binedges.max()] = binedges.max() - binsize assignments = np.digitize(Z, bins=binedges).astype('float64') except ValueError: print("Can't generate a color scale for %s; " \ "try turning off log scale" % attrib) return [] # Scale into the available color indices spot_colors = self.cmap_hex[((assignments * (self.n_colors-1)) / \ assignments.max()).astype(np.int64)] # Generate the argument to ScatterPlotItem.setData spots = [{'pos': XY[i,:], 'pen': {'color': spot_colors[i], 'width': 3.0}} \ for i in range(XY.shape[0])] return spots ## WIDGET CALLBACKS def M_par_callback(self): """ Change the attribute mapped to the axes. """ self.update_scatter(rescale=True) def M_color_by_callback(self): """ Change which attribute is used to generate the color scheme for the localizations. """ self.update_scatter(rescale=False) def M_density_window_callback(self): """ Change the size of the window used to determine the local density of each localization in the current plane. """ if self.M_color_by.currentText() == "density": self.update_scatter(rescale=False) def B_simple_callback(self): """ Change into simple plotting mode, which uses less memory to render the plot but doesn't support color. """ self.simple_mode = not self.simple_mode self.update_scatter(rescale=False) def B_log_callback(self): """ Toggle between log and linear scales for the color map. """ self.log_scale_mode = not self.log_scale_mode print("Log scale: ", self.log_scale_mode) self.update_scatter(rescale=False)
class MainUI(object): def __init__(self, MainWindow, data_path): MainWindow.setWindowTitle('Tracking demo') MainWindow.resize(1000, 700) # data path self.gt_path = data_path self.path = data_path # Dataset Selection self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.groupBox = QtWidgets.QGroupBox(self.centralwidget) self.groupBox.setGeometry(QtCore.QRect(10, 10, 150, 200)) self.groupBox.setObjectName("groupBox") self.groupBox_legend = QtWidgets.QGroupBox(self.centralwidget) self.groupBox_legend.setGeometry(QtCore.QRect(10, 220, 200, 300)) self.groupBox_legend.setObjectName("groupBox_legend") # self.legend_label = QtWidgets.QLabel() self.legend_label = QtWidgets.QLabel(self.groupBox_legend) self.legend_label.setGeometry(QtCore.QRect(10, 20, 95, 20)) self.legend_label.setText("Ground Trut ----") self.legend_label.setStyleSheet( " color: rgba(255, 0, 0); font-size: 10pt; font-weight: 300;") self.legend_label2 = QtWidgets.QLabel(self.groupBox_legend) self.legend_label2.setText("Tracking Result ----") self.legend_label2.setStyleSheet( " color: rgba(0,255, 0); font-size: 10pt; font-weight: 300;") self.radBtn_1 = QtWidgets.QRadioButton(self.groupBox) self.radBtn_1.setGeometry(QtCore.QRect(10, 20, 95, 20)) self.radBtn_1.setObjectName("panda_radBtn") self.radBtn_1.toggled.connect(self.setDataset) self.radBtn_2 = QtWidgets.QRadioButton(self.groupBox) self.radBtn_2.setGeometry(QtCore.QRect(10, 40, 95, 20)) self.radBtn_2.setObjectName("tiger_radBtn") self.radBtn_2.toggled.connect(self.setDataset) self.radBtn_3 = QtWidgets.QRadioButton(self.groupBox) self.radBtn_3.setGeometry(QtCore.QRect(10, 60, 95, 20)) self.radBtn_3.setObjectName("panda_radBtn") self.radBtn_3.toggled.connect(self.setDataset) self.radBtn_4 = QtWidgets.QRadioButton(self.groupBox) self.radBtn_4.setGeometry(QtCore.QRect(10, 80, 95, 20)) self.radBtn_4.setObjectName("tiger_radBtn") self.radBtn_4.toggled.connect(self.setDataset) self.radBtn_5 = QtWidgets.QRadioButton(self.groupBox) self.radBtn_5.setGeometry(QtCore.QRect(10, 100, 95, 20)) self.radBtn_5.setObjectName("panda_radBtn") self.radBtn_5.toggled.connect(self.setDataset) self.model_pulldown = QtGui.QComboBox(self.groupBox) self.model_pulldown.setGeometry(QtCore.QRect(15, 125, 93, 28)) self.model_pulldown.setObjectName("model_pulldown") # self.model_pulldown.addItem("Select") self.model_pulldown.addItem("KCF") self.model_pulldown.addItem("MDNet") self.model_pulldown.addItem("SiamFC") self.img_root = self.path["KCF"] self.model_pulldown.activated.connect(self.setModel) self.display_Btn = QtWidgets.QPushButton(self.groupBox) self.display_Btn.setGeometry(QtCore.QRect(15, 155, 93, 28)) self.display_Btn.setObjectName("display_Btn") # Set up GraphicsLayoutWidget for images self.graphicsWindow = GraphicsLayoutWidget(self.centralwidget, border=True) self.graphicsWindow.setGeometry(QtCore.QRect(140, 10, 850, 600)) self.graphicsWindow.setObjectName("graphicsWindow") MainWindow.setCentralWidget(self.centralwidget) self.score_box = self.graphicsWindow.addViewBox(0, 0, colspan=100) self.ref_box = self.graphicsWindow.addViewBox(0, 100, colspan=50) self.score_box.invertY( True) # Images usually have their Y-axis pointing downward self.ref_box.invertY(True) self.score_box.setAspectLocked(True) self.ref_box.setAspectLocked(True) # image stuff self.score_map = pg.ImageItem(axisOrder='row-major') self.groundtruth_img = pg.ImageItem(axisOrder='row-major') self.ref_img = pg.ImageItem(axisOrder='row-major') # Set Image placeholders self.score_map.setImage(np.zeros((300, 230, 3))) self.groundtruth_img.setImage(np.zeros((300, 230, 3))) self.ref_img.setImage(np.zeros((300, 230, 3))) self.score_box.addItem(self.score_map) self.ref_box.addItem(self.ref_img) # laybels # Add the Labels to the images font = QtGui.QFont() font.setPointSize(4) # parameter for text display param_dict = {'color': (255, 255, 255), 'anchor': (0, 1)} label_score = pg.TextItem(text='Tracking Result', **param_dict) label_gt = pg.TextItem(text='Tracking Error', **param_dict) label_ref = pg.TextItem(text='Reference Image', **param_dict) font.setPointSize(16) label_score.setFont(font) label_gt.setFont(font) label_ref.setFont(font) label_score.setParentItem(self.score_map) label_gt.setParentItem(self.groundtruth_img) label_ref.setParentItem(self.ref_img) self.score_box.addItem(label_score) self.ref_box.addItem(label_ref) # display buttons self.display_Btn.clicked.connect(self.addImages) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) self.i = 0 self.error = np.zeros((1)) self.updateTime = ptime.time() self.fps = 0 # display error plot self.error_plot = self.graphicsWindow.addPlot(3, 0, colspan=200) self.error_data = np.zeros((3, )) self.curve1 = self.error_plot.plot(self.error_data) MainWindow.show() def exit(self): sys.exit() def setDataset(self): if self.radBtn_1.isChecked(): self.img_disp_path = "bolt1/" self.template_path = "bolt.jpg" self.temp_img = self.load_temp() self.error_plot.removeItem(self.curve1) self.error_data = self.read_error() if self.radBtn_2.isChecked(): self.img_disp_path = "bolt2/" self.template_path = "bolt2.jpg" self.temp_img = self.load_temp() self.error_plot.removeItem(self.curve1) self.error_data = self.read_error() if self.radBtn_3.isChecked(): self.img_disp_path = "football/" self.template_path = "football.jpg" self.temp_img = self.load_temp() self.error_plot.removeItem(self.curve1) self.error_data = self.read_error() if self.radBtn_4.isChecked(): self.img_disp_path = "football1/" self.template_path = "football1.jpg" self.temp_img = self.load_temp() self.error_plot.removeItem(self.curve1) self.error_data = self.read_error() if self.radBtn_5.isChecked(): self.img_disp_path = "mountainbike/" self.template_path = "mountainbike.jpg" self.temp_img = self.load_temp() self.error_plot.removeItem(self.curve1) self.error_data = self.read_error() def setModel(self): if self.model_pulldown.currentText() == "KCF": self.error_plot.removeItem(self.curve1) self.img_root = self.path["KCF"] if self.model_pulldown.currentText() == "MDNet": self.error_plot.removeItem(self.curve1) self.img_root = self.path["MDNet"] if self.model_pulldown.currentText() == "SiamFC": self.error_plot.removeItem(self.curve1) self.img_root = self.path["SiamFC"] def addImages(self, MainWindow): self.i = 0 self.data_set = self.load_data() self.error = np.zeros((1)) self.curve1 = self.error_plot.plot(np.zeros((1, ))) self.error_plot.removeItem(self.curve1) self.curve1 = self.error_plot.plot(np.zeros((1, ))) self.updateData() def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.groupBox.setTitle(_translate("MainWindow", "Select Dataset")) self.radBtn_1.setText(_translate("MainWindow", "Bolt1")) self.radBtn_2.setText(_translate("MainWindow", "Bolt2")) self.radBtn_3.setText(_translate("MainWindow", "football")) self.radBtn_4.setText(_translate("MainWindow", "football1")) self.radBtn_5.setText(_translate("MainWindow", "mountainbike")) self.display_Btn.setText(_translate("MainWindow", "Display!")) def load_temp(self): imagePath = os.path.join(self.img_root + self.template_path) temp = cv2.imread(imagePath) temp = cv2.cvtColor(temp, cv2.COLOR_BGR2RGB) return temp def load_data(self): n_files = len(os.listdir(self.img_root + self.img_disp_path)) - 3 image_set = [] for i in range(1, n_files): imagePath = os.path.join(self.img_root + self.img_disp_path + "%08d.jpg" % i) frame = cv2.imread(imagePath) # 1 for colored imaged frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) image_set.append(frame) return image_set def read_error(self): lineList = [] filePath = os.path.join(self.img_root + self.img_disp_path + "error.txt") with open(filePath, 'r') as file: for line in file: lines = [float(number) for number in line.strip().split()] lineList.append(lines[0]) return np.array(lineList) def updateData(self): self.score_map.setImage(self.data_set[self.i]) self.ref_img.setImage(self.temp_img) self.i = (self.i + 1) % len(self.data_set) now = ptime.time() fps2 = 1.0 / (now - self.updateTime) self.updateTime = now self.fps = self.fps * 0.9 + fps2 * 0.1 time.sleep(0.01) QtCore.QTimer.singleShot(100, self.updateData) self.curve1.setData(self.error_data[0:self.i])
class Ui_MainWindow(object): def variables(self): self.N_ = 'n' self.FECHA_ = 'fecha' self.HORA_ = 'hora' self.TEMPERATURA_ = 'Temp1' self.TEMPERATURA2_ = 'Temp2' self.TEMPERATURA3_ = 'Temp3' self.TEMPERATURA4_ = 'Temp4' def setupUi(self, MainWindow): try: base_path = sys._MEIPASS except Exception: base_path = os.path.abspath(".") MainWindow.setObjectName("MainWindow") MainWindow.resize(1500, 900) #MainWindow.setStyleSheet("background-color: blue;") self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.pushButtonAbrir = QtWidgets.QPushButton(self.centralwidget) self.pushButtonAbrir.setGeometry(QtCore.QRect(800, 25, 300, 42)) self.pushButtonAbrir.setObjectName("pushButtonAbrir") #Label Nombre Empresa self.label_nom_empre = QtWidgets.QLabel(self.centralwidget) self.label_nom_empre.setGeometry(QtCore.QRect(220, 20, 125, 20)) self.label_nom_empre.setObjectName("label_nom_empresa") #self.label_nom_empre.setFont(QtGui.QFont("Times", 22, QtGui.QFont.Bold)) #Label Código self.label_cod = QtWidgets.QLabel(self.centralwidget) self.label_cod.setGeometry(QtCore.QRect(250, 50, 50, 20)) self.label_cod.setObjectName("label_cod") #self.label_cod.setFont(QtGui.QFont("Times", 22, QtGui.QFont.Bold)) #Caja de Texto Nombre Empresa self.line_nom_empre = QtWidgets.QLineEdit(self.centralwidget) self.line_nom_empre.resize(200, 32) self.line_nom_empre.move(360, 10) #Caja de Texto Codigo self.line_cod = QtWidgets.QLineEdit(self.centralwidget) self.line_cod.resize(200, 32) self.line_cod.move(360, 45) var_x = 200 var_y = 830 #Labels Sensores self.label_sensor1 = QtWidgets.QLabel(self.centralwidget) self.label_sensor1.setGeometry( QtCore.QRect(var_x + 220, var_y, 150, 20)) self.label_sensor1.setObjectName("label_sensor1") self.label_sensor1.setFont(QtGui.QFont("Times", 22, QtGui.QFont.Bold)) self.label_sensor1.setStyleSheet('color: blue') self.label_sensor2 = QtWidgets.QLabel(self.centralwidget) self.label_sensor2.setGeometry( QtCore.QRect(var_x + 380, var_y, 150, 20)) self.label_sensor2.setObjectName("label_sensor2") self.label_sensor2.setFont(QtGui.QFont("Times", 22, QtGui.QFont.Bold)) self.label_sensor2.setStyleSheet('color: yellow') self.label_sensor3 = QtWidgets.QLabel(self.centralwidget) self.label_sensor3.setGeometry( QtCore.QRect(var_x + 540, var_y, 150, 20)) self.label_sensor3.setObjectName("label_sensor3") self.label_sensor3.setFont(QtGui.QFont("Times", 22, QtGui.QFont.Bold)) self.label_sensor3.setStyleSheet('color: red') self.label_sensor4 = QtWidgets.QLabel(self.centralwidget) self.label_sensor4.setGeometry( QtCore.QRect(var_x + 700, var_y, 150, 20)) self.label_sensor4.setObjectName("label_sensor4") self.label_sensor4.setFont(QtGui.QFont("Times", 22, QtGui.QFont.Bold)) self.label_sensor4.setStyleSheet('color: green') self.label_promedio = QtWidgets.QLabel(self.centralwidget) self.label_promedio.setGeometry( QtCore.QRect(var_x + 860, var_y, 150, 20)) self.label_promedio.setObjectName("label_promedio") self.label_promedio.setFont(QtGui.QFont("Times", 22, QtGui.QFont.Bold)) self.label_promedio.setStyleSheet('color: brown') self.graphicsView = GraphicsLayoutWidget(self.centralwidget) self.graphicsView.setGeometry(QtCore.QRect(100, 100, 1300, 700)) self.graphicsView.setObjectName("graphicsView") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 100, 22)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.pushButtonAbrir.clicked.connect(self.mybutton_clicked) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def mybutton_clicked(self, MainWindow): try: msg = QMessageBox() msg.setWindowTitle("Alerta") if self.line_nom_empre.text() == '' or self.line_cod.text() == '': msg.setText("Por favor ingreso los campos requeridos") x = msg.exec_() else: #Nombre de encabezados del archivo CSV self.variables() filename = QtWidgets.QFileDialog.getOpenFileName() if filename[0] != '': dirReport = os.path.dirname(filename[0]) df = pandas.read_csv(filename[0]) #Graficar valores const = df['Hora'][0] tiempo_aux = [] format = '%H:%M:%S' promedio = [] for index, row in df.iterrows(): diff = (datetime.strptime(str(row['Hora']), format) - datetime.strptime(str(const), format)) / 60 total_minu = round(diff.total_seconds(), 1) tiempo_aux.append(total_minu) var_promedio = (row['Temp1'] + row['Temp2'] + row['Temp3'] + row['Temp4']) / 4 promedio.append(var_promedio) x = tiempo_aux y = df[self.TEMPERATURA_] y2 = df[self.TEMPERATURA2_] y3 = df[self.TEMPERATURA3_] y4 = df[self.TEMPERATURA4_] y5 = promedio self.graphicsView.plot(x, y, pen='#2196F3') self.graphicsView.plot(x, y2, pen='#eff321') self.graphicsView.plot(x, y3, pen='#f32121') self.graphicsView.plot(x, y4, pen='#21f340') self.graphicsView.plot(x, y5, pen='#b97d33') self.graphicsView.setLabel( "bottom", "X = Tiempo (Minutos) / Y = Grados (Centigrados)") #Generar reporte self.generatedReport(df, dirReport) else: msg.setText("Por favor seleccionar el archivo CSV") x = msg.exec_() except Exception as e: msg.setText("Por favor seleccione el archivo correcto") x = msg.exec_() print(e) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "TEMPERATURA")) MainWindow.setWindowIcon(QtGui.QIcon('ico.png')) self.pushButtonAbrir.setText( _translate("MainWindow", "Abrir archivo y generar reporte")) self.graphicsView = self.graphicsView.addPlot(row=1, col=1) self.label_cod.setText(_translate("MainWindow", "Código:")) self.label_nom_empre.setText( _translate("MainWindow", "Nombre de Empresa:")) self.label_sensor1.setText( _translate("MainWindow", "--- Sensor #1 ---")) self.label_sensor2.setText( _translate("MainWindow", "--- Sensor #2 ---")) self.label_sensor3.setText( _translate("MainWindow", "--- Sensor #3 ---")) self.label_sensor4.setText( _translate("MainWindow", "--- Sensor #4 ---")) self.label_promedio.setText( _translate("MainWindow", "--- Promedio ---")) def generatedReport(self, df, dirReport): #Valores de cajas de texto nom_empre = self.line_nom_empre.text() codigo_text = self.line_cod.text() #Image #pdfmetrics.registerFont(TTFont('chsFont', 'STHeiti Light.ttc')) stylesheet = getSampleStyleSheet() elements = [] try: base_path = sys._MEIPASS except Exception: base_path = os.path.abspath(".") fecha = str(datetime.today().strftime('%Y-%m-%d')) address = "Reporte_" + fecha + "_.pdf" path = os.path.join(dirReport, address) path2 = os.path.join(base_path, "cap.jpeg") doc = SimpleDocTemplate(path) #Imagen elements.append(Image(path2, width=1 * inch, height=1 * inch)) #Titulo elements.append( Paragraph('<font >REPORTE DE TEMPERATURA</font>', stylesheet['Title'])) #Descripcion elements.append( Paragraph('<font >DATOS GENERALES</font>', stylesheet['BodyText'])) elements.append( Paragraph( '<font >Empresa: ' + nom_empre + '</font> <font > Código: ' + codigo_text + '</font>', stylesheet['BodyText'])) elements.append( Paragraph('<font >Fecha: ' + fecha + '</font>', stylesheet['BodyText'])) elements.append(Paragraph('<font ></font>', stylesheet['BodyText'])) #Descripcion Ejes elements.append( Paragraph('<font >DESCRIPCIÓN GRÁFICO</font>', stylesheet['BodyText'])) elements.append( Paragraph( '<font > Eje Y = Grados Centigrados / Eje X = Tiempo Minutos</font>', stylesheet['BodyText'])) elements.append( Paragraph( '<font color=blue> -- Sensor #1 --</font> <font color=yellow>-- Sensor #2 --</font> <font color=red>-- Sensor #3 --</font> <font color=green>-- Sensor #4 --</font> <font color=brown>-- Promedio --</font>', stylesheet['BodyText'])) elements.append(Spacer(1, 1 * inch)) #Datos para el Gráfico lista_temp1 = [] lista_temp2 = [] lista_temp3 = [] lista_temp4 = [] lista_total = [] promedio_ = [] data_table = [] cabecera = [] cabecera.append('No') cabecera.append('Fecha') cabecera.append('Hora') cabecera.append('Temp 1') cabecera.append('Temp 2') cabecera.append('Temp 3') cabecera.append('Temp 4') cabecera.append('Tiempo / Minutos') cabecera.append('Promedio') data_table.append(cabecera) const = df['Hora'][0] format = '%H:%M:%S' for index, row in df.iterrows(): diff = (datetime.strptime(str(row['Hora']), format) - datetime.strptime(str(const), format)) / 60 total_minu = round(diff.total_seconds(), 1) var_promedio = (row['Temp1'] + row['Temp2'] + row['Temp3'] + row['Temp4']) / 4 round_promedio = round(var_promedio, 2) c_1 = (total_minu, row['Temp1']) c_2 = (total_minu, row['Temp2']) c_3 = (total_minu, row['Temp3']) c_4 = (total_minu, row['Temp4']) c_5 = (total_minu, round_promedio) lista_temp1.append(c_1) lista_temp2.append(c_2) lista_temp3.append(c_3) lista_temp4.append(c_4) promedio_.append(c_5) array_aux = [] array_aux.append(row['n']) array_aux.append(row['Fecha']) array_aux.append(row['Hora']) array_aux.append(row['Temp1']) array_aux.append(row['Temp2']) array_aux.append(row['Temp3']) array_aux.append(row['Temp4']) array_aux.append(total_minu) array_aux.append(round_promedio) data_table.append(array_aux) lista_total.append(lista_temp1) lista_total.append(lista_temp2) lista_total.append(lista_temp3) lista_total.append(lista_temp4) lista_total.append(promedio_) elements.append(Spacer(1, 1 * inch)) elements.append(Spacer(1, 1 * inch)) drawing = Drawing(400, 200) lp = LinePlot() lp.x = 100 lp.y = 100 lp.height = 300 lp.width = 300 lp.data = lista_total lp.joinedLines = 1 #lp.lineLabelFormat = '%2.0f' lp.strokeColor = colors.black lp.xValueAxis.valueMin = 0 lp.xValueAxis.valueMax = 100 lp.xValueAxis.valueStep = 10 #lp.xValueAxis.valueSteps =listHora_aux lp.xValueAxis.labelTextFormat = '%2.1f' lp.yValueAxis.valueMin = 0 lp.yValueAxis.valueMax = 180 lp.yValueAxis.valueStep = 5 lp.lines[0].strokeColor = colors.blue lp.lines[1].strokeColor = colors.yellow lp.lines[2].strokeColor = colors.red lp.lines[3].strokeColor = colors.green lp.lines[4].strokeColor = colors.brown drawing.add(lp) elements.append(drawing) #Tabla elements.append( Paragraph('<font >DESCRIPCIÓN TABLA</font>', stylesheet['BodyText'])) elements.append(Paragraph('<font ></font>', stylesheet['BodyText'])) style_table = TableStyle([ ('BACKGROUND', (0, 0), (8, 0), colors.green), ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke), ('ALIGN', (0, 0), (8, 1000000), 'CENTER'), ('FONTNAME', (0, 0), (-1, 0), 'Courier-Bold') ]) table = Table(data_table) table.setStyle(style_table) elements.append(table) elements.append(Spacer(1, 1 * inch)) elements.append(Spacer(1, 1 * inch)) #Firma #elements.append(Paragraph('<font >Hola</font>', stylesheet['Title'])) elements.append(Spacer(1, 1 * inch)) doc.build(elements) msg = QMessageBox() msg.setWindowTitle("Alerta") msg.setText("Correcta Generación de Reporte !!!") x = msg.exec_()
class Dialog(QtGui.QDialog): def __init__(self, dataY=None, dataX=None, dir=None, stockInfo=None, parent=None): super(Dialog, self).__init__(parent) self.resize(800, 800) self.gridContainer = None self.gridContainer = QtWidgets.QWidget(self) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHeightForWidth( self.gridContainer.sizePolicy().hasHeightForWidth()) self.gridContainer.setSizePolicy(sizePolicy) self.gridContainer.setFocusPolicy(QtCore.Qt.NoFocus) self.gridContainer.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) self.gridContainer.setObjectName("Graphgrid") self.gridContainer.layout = QtWidgets.QGridLayout() self.dir = dir self.stockInfo = stockInfo self.dataX = dataX self.dataY = dataY self.rasingRange = [] self.failingRange = [] # setup Plot self.graph = None self.PlotDataItemList = None self.PlotLocalMaximaData = None self.PlotLocalMinimaData = None self.p1 = None self.colorStyle = ['r', 'g', 'y', 'b', 'w', 'o'] self.setupGraph() self.gridContainer.layout.addWidget(self.graph, 0, 0, 10, 10) self.TableDAT = Concat_Table_With_IDX(self.dir, self.stockInfo.code) print(self.dir, self.stockInfo.code) self.initUI() self.proxy = pg.SignalProxy(self.p1.scene().sigMouseMoved, rateLimit=60, slot=self.mouseMoved) def initUI(self): #check box self.AVGRadioButton = QtWidgets.QCheckBox("AVG") self.AVGRadioButton.setObjectName("avgRadioButton") self.gridContainer.layout.addWidget(self.AVGRadioButton, 0, 11, 1, 1) self.AVGRadioButton.setStyleSheet("color: rgb(0, 255, 0);") self.AVGRadioButton.toggled.connect( lambda: self.toggleFunc(self.AVGRadioButton, 'avg')) self.AVGRadioButton.click() self.LPFRadioButton = QtWidgets.QCheckBox("LPF") self.LPFRadioButton.setObjectName("avgRadioButton") self.gridContainer.layout.addWidget(self.LPFRadioButton, 1, 11, 1, 1) self.LPFRadioButton.setStyleSheet("color: rgb(255,0,0);") self.LPFRadioButton.toggled.connect( lambda: self.toggleFunc(self.LPFRadioButton, 'lpf')) self.LPFRadioButton.click() #set Data self.PlotDataItemList = self.setPlot() self.setData(self.dataX, self.dataY) #set avg slide self.avgSld = QtWidgets.QSlider(QtCore.Qt.Horizontal, self) self.avgSld.setRange(5, 120) self.avgSld.setFocusPolicy(QtCore.Qt.NoFocus) # it seems not work #self.avgSld.setPageStep(5) # self.avgSld.setTickInterval(5) # self.avgSld.setSingleStep(5) self.avgSld.valueChanged.connect(self.updateAvg) self.gridContainer.layout.addWidget(self.avgSld, 11, 1, 1, 2) self.avg = functionAnalysis.moving_average(self.dataY['close'], self.avgSld.value()) self.AvgEdit = QtWidgets.QLabel('5日線') self.AvgEdit.setObjectName("avg") self.gridContainer.layout.addWidget(self.AvgEdit, 11, 0, 1, 1) self.OrderLabel = QtWidgets.QLabel('Order') self.OrderLabel.setObjectName("orderLabel") self.gridContainer.layout.addWidget(self.OrderLabel, 12, 0, 1, 1) self.OrderEdit = QtWidgets.QLineEdit("2") self.OrderEdit.setObjectName("orderEdit") self.gridContainer.layout.addWidget(self.OrderEdit, 12, 1, 1, 1) self.CutoffEdit = QtWidgets.QLabel("Cutoff : 2") self.CutoffEdit.setObjectName("Cutoff") self.gridContainer.layout.addWidget(self.CutoffEdit, 12, 3, 1, 1) self.cutoffSld = QtWidgets.QSlider(QtCore.Qt.Horizontal, self) self.cutoffSld.setRange(2, 60) self.cutoffSld.setFocusPolicy(QtCore.Qt.NoFocus) self.smoothData = functionAnalysis.butterworth_filter( self.dataY['close'], self.cutoffSld.value(), len(self.dataY['close']) / 2, 2) self.cutoffSld.valueChanged.connect(self.updateLPF) self.cutoffSld.setValue(5) self.gridContainer.layout.addWidget(self.cutoffSld, 12, 4, 1, 10) self.PlotDataItemList[1].setData(y=self.avg) self.PlotDataItemList[2].setData(y=self.smoothData) self.gridContainer.setLayout(self.gridContainer.layout) #make AVG is invisiable by default self.AVGRadioButton.setChecked(False) self.tableView = QtWidgets.QTableView() self.TableDAT = self.TableDAT.round(2) #Temporary, we delete 1st level colums, for showing columns in TableView self.TableDAT.columns = self.TableDAT.columns.droplevel(0) self.model = PandaModel.DataFrameModel(self.TableDAT) self.tableView.setModel(self.model) #Resize cell size to self.tableView.resizeColumnsToContents() self.gridContainer.layout.addWidget(self.tableView, 13, 0, 1, 10) def setupGraph(self): self.date_axis = TimeAxisItem(orientation='bottom') self.graph = GraphicsLayoutWidget() self.graph.setObjectName("Graph UI") self.date_axis = TimeAxisItem(orientation='bottom') self.label = pg.LabelItem(justify='right') self.graph.addItem(self.label) self.p1 = self.graph.addPlot(row=1, col=0, axisItems={'bottom': self.date_axis}) #p1 zoom in/out, move viewbox can auto scaling Y, Important! self.p1.vb.sigXRangeChanged.connect(self.setYRange) self.PlotDataItemList = self.setPlot() self.PlotLocalMaximaData = pg.ScatterPlotItem(pen='r', brush='b', symbol='d', pxMode=True, size=10) self.PlotLocalMinimaData = pg.ScatterPlotItem(pen='g', brush='b', symbol='t', pxMode=True, size=10) # self.p1.addItem(self.PlotLocalMaximaData) # self.p1.addItem(self.PlotLocalMinimaData) # def showEvent(self, event): # geom = self.frameGeometry() # geom.moveCenter(QtGui.QCursor.pos()) # self.setGeometry(geom) # super(Dialog, self).showEvent(event) def setPlot(self): PlotDataItemList = [] self.name = ['close', 'avg', 'lpf'] for i in range(0, 3): PlotDataItemList.append( self.p1.plot(pen=self.colorStyle[i], name=self.name[i])) return PlotDataItemList def setYRange(self, plotitem): plotitem.enableAutoRange(axis='y') plotitem.setAutoVisible(y=True) def setData(self, dataX, dataY): ticks = dict(enumerate(dataX)) '''set X-value''' self.date_axis.setTicks( [list(ticks.items())[::120], list(ticks.items())[::1]]) self.PlotDataItemList[0].setData(y=dataY['close']) def updateAvg(self, value): self.AvgEdit.setText(str(value) + '日線') self.avg = functionAnalysis.moving_average(self.dataY['close'], self.avgSld.value()) self.PlotDataItemList[1].setData(y=self.avg) def updateLPF(self, value): self.CutoffEdit.setText("Cutoff : " + str(value)) self.smoothData = functionAnalysis.butterworth_filter( self.dataY['close'], self.cutoffSld.value(), len(self.dataY['close']) / 2, int(self.OrderEdit.text())) self.PlotDataItemList[2].setData(y=self.smoothData) maxidx, minidx = functionAnalysis.getlocalMaxMin( self.smoothData, True, True) #Split Range sortRange = [] lastRoundIdx = 0 for idxMax, idxMin in zip(maxidx, minidx): if idxMax > idxMin: sortRange.append([lastRoundIdx, idxMin]) sortRange.append([idxMin, idxMax]) lastRoundIdx = idxMax else: sortRange.append([lastRoundIdx, idxMax]) sortRange.append([idxMax, idxMin]) lastRoundIdx = idxMin sortRange.append([ maxidx[-1], -1 ]) if maxidx[-1] > minidx[-1] else sortRange.append([minidx[-1], -1]) self.PlotLocalMaximaData.setData( x=maxidx, y=[self.dataY['close'][i] for i in maxidx]) self.PlotLocalMinimaData.setData( x=minidx, y=[self.dataY['close'][i] for i in minidx]) def keyPressEvent(self, event): if event.key() == QtCore.Qt.Key_Escape: self.hide() event.accept() else: super(Dialog, self).keyPressEvent(event) def toggleFunc(self, rdb, name): plotItem = None for plot in self.PlotDataItemList: if plot.name() == name: plotItem = plot if rdb.isChecked(): self.p1.addItem(plotItem) else: self.p1.removeItem(plotItem) def mouseMoved(self, evt): pos = evt[ 0] ## using signal proxy turns original arguments into a tuple if self.p1.sceneBoundingRect().contains(pos): mousePoint = self.p1.vb.mapSceneToView(pos) index = int(mousePoint.x()) if index > 0 and index < len(self.dataX): idx = int(mousePoint.x()) self.label.setText( "<span style='font-size: 12pt'>x=%s, <span style='color: red'>收盤價=%0.1f</span>" % (self.dataX[idx], self.dataY['close'][idx]))
class centralWidget(QtWidgets.QWidget): def __init__(self, timeData, voltsData): super(centralWidget, self).__init__() # first generating the widgets of the tab self.generateUiWidgets() # initializing important variables for plotting self.timeData = timeData self.originalVoltsData = voltsData self.editedVoltsData = voltsData self.plot = None # original Plot self.plot1 = None # plot After Editing self.xRangeStack = [] self.yRangeStack = [] self.sampleTime = timeData[1] - timeData[0] yrange = voltsData[len(voltsData) - 1] - voltsData[0] self.scrollStep_x = 100 * self.sampleTime self.scrollStep_y = yrange / 10 # sliders values for i in range(1, 11): setattr(self, "_value" + str(i), 1) # self._value[1-10] = 1 #Pallete of spectrogram *viridis as deafult self.RGB_Pallete_1 = (0, 182, 188, 255) self.RGB_Pallete_2 = (246, 111, 0, 255) self.RGB_Pallete_3 = (75, 0, 113, 255) #set labels text ft = fourierTransform(self.originalVoltsData, int(1 / self.sampleTime)) ranges = ft.rangesOfFrequancy for i in range(10): getattr(getattr(self, "label" + str(i + 1)), "setText")(str(ranges[i][0] / 1000) + " Khz : \n" + str(ranges[i][1] / 1000) + " Khz") self.HorizontalLabel1.setText("Set Minimun Frequancy") self.HorizontalLabel2.setText("Set Maximum Frequancy") # values of range of spectrogram self.minFreqOfSpectrogram = 0 self.maxFreqOfSpectrogram = ranges[-1][1] self.horizontalSlider1.setMinimum(self.minFreqOfSpectrogram) self.horizontalSlider1.setMaximum(self.maxFreqOfSpectrogram) self.horizontalSlider1.setTickInterval(self.maxFreqOfSpectrogram / 10) self.horizontalSlider2.setMinimum(self.minFreqOfSpectrogram) self.horizontalSlider2.setMaximum(self.maxFreqOfSpectrogram) self.horizontalSlider2.setSliderPosition(self.maxFreqOfSpectrogram) self.horizontalSlider2.setTickInterval(self.maxFreqOfSpectrogram / 10) self.SpectrogramViewer.clear() self.drawSpectrogram() self.xRangeOfSignal = None # [from , to] self.yRangeOfSignal = None #start plotting the data self.startPlotting() # get range of view of the plots self.xRangeOfSignal = [0.0, list(self.timeData)[-1]] # [from , to] self.yRangeOfSignal = self.plot.viewRange()[1] def startPlotting(self): # plot original signal self.plot = self.OriginalSignalViewer.addPlot() self.plot.plot(self.timeData, self.originalVoltsData) # plot data After Editing self.plot1 = self.EditedSignalViewer.addPlot() self.plot1.plot(self.timeData, self.editedVoltsData) # range edit self.plot.setXRange(0.0, list(self.timeData)[-1], 0) self.plot1.setXRange(0.0, list(self.timeData)[-1], 0) def minSliderOfSpectrogram(self, value): self.minFreqOfSpectrogram = value self.SpectrogramViewer.clear() self.drawSpectrogram() def maxSliderOfSpectrogram(self, value): self.maxFreqOfSpectrogram = value self.SpectrogramViewer.clear() self.drawSpectrogram() def drawSpectrogram(self, minFreq=1, maxFreq=1): minFreq_Slider = self.minFreqOfSpectrogram maxFreq_Slider = self.maxFreqOfSpectrogram freq = 1 / self.sampleTime ft = fourierTransform(self.editedVoltsData, int(freq)) ft.deleteRangeOfFrequancy(0, minFreq_Slider) ft.deleteRangeOfFrequancy(maxFreq_Slider, int(freq / 2)) realsAfterEdit = ft.fn_InverceFourier(ft.data_fft) frequancyArr, timeArr, Sxx = signal.spectrogram( np.array(realsAfterEdit), freq) pyqtgraph.setConfigOptions(imageAxisOrder='row-major') win = self.SpectrogramViewer p1 = win.addPlot() img = pyqtgraph.ImageItem() p1.addItem(img) hist = pyqtgraph.HistogramLUTItem() hist.setImageItem(img) win.addItem(hist) hist.setLevels(np.min(Sxx), np.max(Sxx)) hist.gradient.restoreState({ 'mode': 'rgb', 'ticks': [(0.5, self.RGB_Pallete_1), (1.0, self.RGB_Pallete_2), (0.0, self.RGB_Pallete_3)] }) img.setImage(Sxx) img.scale(timeArr[-1] / np.size(Sxx, axis=1), frequancyArr[-1] / np.size(Sxx, axis=0)) p1.setLimits(xMin=0, xMax=timeArr[-1], yMin=0, yMax=frequancyArr[-1]) p1.setLabel('bottom', "Time", units='s') p1.setLabel('left', "Frequency", units='Hz') def generateUiWidgets(self): font = QtGui.QFont() font.setFamily("Arial Unicode MS") font.setPointSize(10) font.setBold(False) font.setItalic(False) font.setUnderline(False) font.setWeight(50) font.setStrikeOut(False) font.setKerning(True) self.setFont(font) self.setTabletTracking(False) self.gridLayout_6 = QtWidgets.QGridLayout(self) self.gridLayout_6.setObjectName("gridLayout_6") self.gridLayout_4 = QtWidgets.QGridLayout() self.gridLayout_4.setObjectName("gridLayout_4") self.SpectrogramGroupBox = QtWidgets.QGroupBox(self) font = QtGui.QFont() font.setFamily("Arial Unicode MS") font.setPointSize(10) font.setBold(True) font.setWeight(75) self.SpectrogramGroupBox.setFont(font) self.SpectrogramGroupBox.setStyleSheet( "border-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 0, 0, 255), stop:1 rgba(255, 255, 255, 255));" ) self.SpectrogramGroupBox.setObjectName("SpectrogramGroupBox") self.gridLayout_2 = QtWidgets.QGridLayout(self.SpectrogramGroupBox) self.gridLayout_2.setObjectName("gridLayout_2") self.horizontalSlider2 = QtWidgets.QSlider(self.SpectrogramGroupBox) font = QtGui.QFont() font.setPointSize(7) self.horizontalSlider2.setFont(font) self.horizontalSlider2.setCursor( QtGui.QCursor(QtCore.Qt.ClosedHandCursor)) self.horizontalSlider2.setOrientation(QtCore.Qt.Horizontal) self.horizontalSlider2.setTickPosition(QtWidgets.QSlider.TicksBelow) self.horizontalSlider2.setTickInterval(1) self.horizontalSlider2.setObjectName("horizontalSlider2") self.gridLayout_2.addWidget(self.horizontalSlider2, 3, 0, 1, 1) self.SpectrogramViewer = GraphicsLayoutWidget(self.SpectrogramGroupBox) self.SpectrogramViewer.viewport().setProperty( "cursor", QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.SpectrogramViewer.setStyleSheet("background-color:rgb(0,0,0)") self.SpectrogramViewer.setObjectName("SpectrogramViewer") self.gridLayout_2.addWidget(self.SpectrogramViewer, 0, 0, 1, 1) self.horizontalSlider1 = QtWidgets.QSlider(self.SpectrogramGroupBox) self.horizontalSlider1.setCursor( QtGui.QCursor(QtCore.Qt.ClosedHandCursor)) self.horizontalSlider1.setOrientation(QtCore.Qt.Horizontal) self.horizontalSlider1.setTickPosition(QtWidgets.QSlider.TicksBelow) self.horizontalSlider1.setTickInterval(1) self.horizontalSlider1.setObjectName("horizontalSlider1") self.gridLayout_2.addWidget(self.horizontalSlider1, 1, 0, 1, 1) self.HorizontalLabel1 = QtWidgets.QLabel(self.SpectrogramGroupBox) font = QtGui.QFont() font.setPointSize(7) self.HorizontalLabel1.setFont(font) self.HorizontalLabel1.setAlignment(QtCore.Qt.AlignCenter) self.HorizontalLabel1.setObjectName("HorizontalLabel1") self.gridLayout_2.addWidget(self.HorizontalLabel1, 2, 0, 1, 1) self.HorizontalLabel2 = QtWidgets.QLabel(self.SpectrogramGroupBox) self.HorizontalLabel2.setAlignment(QtCore.Qt.AlignCenter) self.HorizontalLabel2.setObjectName("HorizontalLabel2") self.gridLayout_2.addWidget(self.HorizontalLabel2, 4, 0, 1, 1) self.gridLayout_4.addWidget(self.SpectrogramGroupBox, 0, 1, 3, 1) self.OriginalSignalGroupbox = QtWidgets.QGroupBox(self) font = QtGui.QFont() font.setFamily("Arial Unicode MS") font.setPointSize(10) font.setBold(True) font.setWeight(75) self.OriginalSignalGroupbox.setFont(font) self.OriginalSignalGroupbox.setObjectName("OriginalSignalGroupbox") self.gridLayout_5 = QtWidgets.QGridLayout(self.OriginalSignalGroupbox) self.gridLayout_5.setObjectName("gridLayout_5") self.OriginalSignalViewer = GraphicsLayoutWidget( self.OriginalSignalGroupbox) self.OriginalSignalViewer.viewport().setProperty( "cursor", QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.OriginalSignalViewer.setStyleSheet( "background-color: rgb(0, 0, 0);") self.OriginalSignalViewer.setObjectName("OriginalSignalViewer") self.gridLayout_5.addWidget(self.OriginalSignalViewer, 0, 0, 1, 1) self.gridLayout_4.addWidget(self.OriginalSignalGroupbox, 0, 0, 1, 1) self.EditedSignalGroupBox = QtWidgets.QGroupBox(self) font = QtGui.QFont() font.setFamily("Arial Unicode MS") font.setPointSize(10) font.setBold(True) font.setWeight(75) self.EditedSignalGroupBox.setFont(font) self.EditedSignalGroupBox.setObjectName("EditedSignalGroupBox") self.gridLayout_3 = QtWidgets.QGridLayout(self.EditedSignalGroupBox) self.gridLayout_3.setObjectName("gridLayout_3") self.EditedSignalViewer = GraphicsLayoutWidget( self.EditedSignalGroupBox) self.EditedSignalViewer.viewport().setProperty( "cursor", QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.EditedSignalViewer.setStyleSheet("background-color:rgb(0,0,0)") self.EditedSignalViewer.setObjectName("EditedSignalViewer") self.gridLayout_3.addWidget(self.EditedSignalViewer, 0, 0, 1, 1) self.gridLayout_4.addWidget(self.EditedSignalGroupBox, 2, 0, 1, 1) self.SignalEditorGroupBox = QtWidgets.QGroupBox(self) font = QtGui.QFont() font.setFamily("Arial Unicode MS") font.setPointSize(10) font.setBold(True) font.setWeight(75) self.SignalEditorGroupBox.setFont(font) self.SignalEditorGroupBox.setObjectName("SignalEditorGroupBox") self.gridLayout = QtWidgets.QGridLayout(self.SignalEditorGroupBox) self.gridLayout.setObjectName("gridLayout") self.gridLayout_7 = QtWidgets.QGridLayout() self.gridLayout_7.setObjectName("gridLayout_7") # add 10 labels for 10 sliders for i in range(10): setattr( self, "label" + str(i + 1), QtWidgets.QLabel(self.SignalEditorGroupBox) ) # self.label[1-10] = QtWidgets.QLabel(self.SignalEditorGroupBox) font = QtGui.QFont() font.setPointSize(5) font.setBold(False) font.setWeight(50) getattr(getattr(self, "label" + str(i + 1)), "setFont")(font) #self.label1.setFont(font) getattr(getattr(self, "label" + str(i + 1)), "setObjectName")( "label" + str(i + 1)) #self.label[1-10].setObjectName("label[1-10]") getattr(getattr(self, "gridLayout_7"), "addWidget")( getattr(self, "label" + str(i + 1)), 0, i, 1, 1) #self.gridLayout_7.addWidget(self.label1, 0, 0, 1, 1) self.gridLayout.addLayout(self.gridLayout_7, 1, 0, 1, 10) # add 10 sliders to gui for i in range(10): setattr( self, "slider" + str(i + 1), Slider(parent=self.SignalEditorGroupBox, objectName="Slider" + str(i + 1))) Slid = getattr(self, "slider" + str(i + 1)) getattr(getattr(self, "gridLayout"), "addWidget")(Slid, 0, i, 1, 1) # link slider to the trigger function Slid.valueChanged.connect(lambda v: self.fn_sliderValue(v)) self.gridLayout_4.addWidget(self.SignalEditorGroupBox, 1, 0, 1, 1) self.gridLayout_6.addLayout(self.gridLayout_4, 0, 0, 1, 1) self.horizontalSlider1.valueChanged[int].connect( self.minSliderOfSpectrogram) self.horizontalSlider2.valueChanged[int].connect( self.maxSliderOfSpectrogram) QtCore.QMetaObject.connectSlotsByName(self) def fn_sliderValue(self, value): objectName = str(self.sender().objectName()) sliderNumber = re.search("[0-9]+", objectName).group() setattr(self, "_value" + sliderNumber, value) self.process() def process(self): #(freq,complex_data,reals,time,np.abs(complex_data)) ft = fourierTransform( list(self.originalVoltsData).copy(), 1 / self.sampleTime) complex_data = ft.gain(self._value1, self._value2, self._value3, self._value4, self._value5, self._value6, self._value7, self._value8, self._value9, self._value10) reals = ft.fn_InverceFourier(complex_data) #update Plot self.EditedSignalViewer.clear() self.plot1 = self.EditedSignalViewer.addPlot() self.plot1.plot(self.timeData, reals) self.plot1.setXRange(self.xRangeOfSignal[0], self.xRangeOfSignal[1], 0) self.plot1.setYRange(self.yRangeOfSignal[0], self.yRangeOfSignal[1], 0) self.editedVoltsData = np.array(reals) # update spectrogram self.SpectrogramViewer.clear() self.drawSpectrogram() def playSound(self): ft = fourierTransform( list(self.editedVoltsData).copy(), 1 / self.sampleTime) complex_data = ft.gain(self._value1, self._value2, self._value3, self._value4, self._value5, self._value6, self._value7, self._value8, self._value9, self._value10) reals = ft.fn_InverceFourier(complex_data) sound = soundfileUtility() sound.fn_CreateSoundFile(list(reals), int(1 / self.sampleTime)) sound.fn_PlaySoundFile()
class astraPlotWidget(QWidget): twissplotLayout = [ { 'name': 'sigma_x', 'range': [0, 1], 'scale': 1e3 }, { 'name': 'sigma_y', 'range': [0, 1], 'scale': 1e3 }, { 'name': 'kinetic_energy', 'range': [0, 250], 'scale': 1e-6 }, 'next_row', { 'name': 'sigma_p', 'range': [0, 0.015], 'scale': 1e6 }, { 'name': 'sigma_z', 'range': [0, 0.6], 'scale': 1e3 }, { 'name': 'enx', 'range': [0.5, 1.5], 'scale': 1e6 }, 'next_row', { 'name': 'eny', 'range': [0.5, 1.5], 'scale': 1e6 }, { 'name': 'beta_x', 'range': [0, 150], 'scale': 1 }, { 'name': 'beta_y', 'range': [0, 150], 'scale': 1 }, ] def __init__(self, directory='.', **kwargs): super(astraPlotWidget, self).__init__(**kwargs) self.beam = raf.beam() self.twiss = rtf.twiss() self.directory = directory ''' twissPlotWidget ''' self.twissPlotView = GraphicsView(useOpenGL=True) self.twissPlotWidget = GraphicsLayout() self.twissPlotView.setCentralItem(self.twissPlotWidget) self.latticePlotData = imageio.imread('lattice_plot.png') self.latticePlots = {} self.twissPlots = {} i = -1 for entry in self.twissplotLayout: if entry == 'next_row': self.twissPlotWidget.nextRow() else: i += 1 p = self.twissPlotWidget.addPlot(title=entry['name']) p.showGrid(x=True, y=True) vb = p.vb vb.setYRange(*entry['range']) latticePlot = ImageItem(self.latticePlotData) latticePlot.setOpts(axisOrder='row-major') vb.addItem(latticePlot) latticePlot.setZValue(-1) # make sure this image is on top # latticePlot.setOpacity(0.5) self.twissPlots[entry['name']] = p.plot( pen=mkPen('b', width=3)) self.latticePlots[p.vb] = latticePlot p.vb.sigRangeChanged.connect(self.scaleLattice) ''' beamPlotWidget ''' self.beamPlotWidget = QWidget() self.beamPlotLayout = QVBoxLayout() self.item = ImageItem() self.beamPlotWidget.setLayout(self.beamPlotLayout) self.beamPlotView = ImageView(imageItem=self.item) self.rainbow = rainbow() self.item.setLookupTable(self.rainbow) self.item.setLevels([0, 1]) # self.beamPlotWidgetGraphicsLayout = GraphicsLayout() # p = self.beamPlotWidgetGraphicsLayout.addPlot(title='beam') # p.showGrid(x=True, y=True) # self.beamPlot = p.plot(pen=None, symbol='+') # self.beamPlotView.setCentralItem(self.beamPlotWidgetGraphicsLayout) self.beamPlotXAxisCombo = QComboBox() self.beamPlotXAxisCombo.addItems( ['x', 'y', 'zn', 'cpx', 'cpy', 'BetaGamma']) self.beamPlotYAxisCombo = QComboBox() self.beamPlotYAxisCombo.addItems( ['x', 'y', 'zn', 'cpx', 'cpy', 'BetaGamma']) self.beamPlotNumberBins = QSpinBox() self.beamPlotNumberBins.setRange(10, 500) self.beamPlotNumberBins.setSingleStep(10) self.histogramBins = 100 self.beamPlotNumberBins.setValue(self.histogramBins) self.beamPlotAxisWidget = QWidget() self.beamPlotAxisLayout = QHBoxLayout() self.beamPlotAxisWidget.setLayout(self.beamPlotAxisLayout) self.beamPlotAxisLayout.addWidget(self.beamPlotXAxisCombo) self.beamPlotAxisLayout.addWidget(self.beamPlotYAxisCombo) self.beamPlotAxisLayout.addWidget(self.beamPlotNumberBins) self.beamPlotXAxisCombo.currentIndexChanged.connect(self.plotDataBeam) self.beamPlotYAxisCombo.currentIndexChanged.connect(self.plotDataBeam) self.beamPlotNumberBins.valueChanged.connect(self.plotDataBeam) # self.beamPlotXAxisCombo.setCurrentIndex(2) # self.beamPlotYAxisCombo.setCurrentIndex(5) self.beamPlotLayout.addWidget(self.beamPlotAxisWidget) self.beamPlotLayout.addWidget(self.beamPlotView) ''' slicePlotWidget ''' self.sliceParams = [ { 'name': 'slice_normalized_horizontal_emittance', 'units': 'm-rad', 'text': 'enx' }, { 'name': 'slice_normalized_vertical_emittance', 'units': 'm-rad', 'text': 'eny' }, { 'name': 'slice_peak_current', 'units': 'A', 'text': 'PeakI' }, { 'name': 'slice_relative_momentum_spread', 'units': '%', 'text': 'sigma-p' }, ] self.slicePlotWidget = QWidget() self.slicePlotLayout = QVBoxLayout() self.slicePlotWidget.setLayout(self.slicePlotLayout) # self.slicePlotView = GraphicsView(useOpenGL=True) self.slicePlotWidgetGraphicsLayout = GraphicsLayoutWidget() # self.slicePlots = {} self.slicePlotCheckbox = {} self.curve = {} self.sliceaxis = {} self.slicePlotCheckboxWidget = QWidget() self.slicePlotCheckboxLayout = QVBoxLayout() self.slicePlotCheckboxWidget.setLayout(self.slicePlotCheckboxLayout) self.slicePlot = self.slicePlotWidgetGraphicsLayout.addPlot( title='Slice', row=0, col=50) self.slicePlot.showAxis('left', False) self.slicePlot.showGrid(x=True, y=True) i = -1 colors = ['b', 'r', 'g', 'k'] for param in self.sliceParams: i += 1 axis = AxisItem("left") labelStyle = {'color': '#' + colorStr(mkColor(colors[i]))[0:-2]} axis.setLabel(text=param['text'], units=param['units'], **labelStyle) viewbox = ViewBox() axis.linkToView(viewbox) viewbox.setXLink(self.slicePlot.vb) self.sliceaxis[param['name']] = [axis, viewbox] self.curve[param['name']] = PlotDataItem(pen=colors[i], symbol='+') viewbox.addItem(self.curve[param['name']]) col = self.findFirstEmptyColumnInGraphicsLayout() self.slicePlotWidgetGraphicsLayout.ci.addItem(axis, row=0, col=col, rowspan=1, colspan=1) self.slicePlotWidgetGraphicsLayout.ci.addItem(viewbox, row=0, col=50) p.showGrid(x=True, y=True) # self.slicePlots[param] = self.slicePlot.plot(pen=colors[i], symbol='+') self.slicePlotCheckbox[param['name']] = QCheckBox(param['text']) self.slicePlotCheckboxLayout.addWidget( self.slicePlotCheckbox[param['name']]) self.slicePlotCheckbox[param['name']].stateChanged.connect( self.plotDataSlice) # self.slicePlotView.setCentralItem(self.slicePlotWidgetGraphicsLayout) self.slicePlotSliceWidthWidget = QSpinBox() self.slicePlotSliceWidthWidget.setMaximum(1000) self.slicePlotSliceWidthWidget.setValue(100) self.slicePlotSliceWidthWidget.setSingleStep(10) self.slicePlotSliceWidthWidget.setSuffix("fs") self.slicePlotSliceWidthWidget.setSpecialValueText('Automatic') self.slicePlotAxisWidget = QWidget() self.slicePlotAxisLayout = QHBoxLayout() self.slicePlotAxisWidget.setLayout(self.slicePlotAxisLayout) self.slicePlotAxisLayout.addWidget(self.slicePlotCheckboxWidget) self.slicePlotAxisLayout.addWidget(self.slicePlotSliceWidthWidget) # self.slicePlotXAxisCombo.currentIndexChanged.connect(self.plotDataSlice) self.slicePlotSliceWidthWidget.valueChanged.connect( self.changeSliceLength) # self.beamPlotXAxisCombo.setCurrentIndex(2) # self.beamPlotYAxisCombo.setCurrentIndex(5) self.slicePlotLayout.addWidget(self.slicePlotAxisWidget) self.slicePlotLayout.addWidget(self.slicePlotWidgetGraphicsLayout) self.layout = QVBoxLayout() self.setLayout(self.layout) self.tabWidget = QTabWidget() self.folderButton = QPushButton('Select Directory') self.folderLineEdit = QLineEdit() self.folderLineEdit.setReadOnly(True) self.folderLineEdit.setText(self.directory) self.reloadButton = QPushButton() self.reloadButton.setIcon(qApp.style().standardIcon( QStyle.SP_BrowserReload)) self.folderWidget = QGroupBox() self.folderLayout = QHBoxLayout() self.folderLayout.addWidget(self.folderButton) self.folderLayout.addWidget(self.folderLineEdit) self.folderLayout.addWidget(self.reloadButton) self.folderWidget.setLayout(self.folderLayout) self.folderWidget.setMaximumWidth(800) self.reloadButton.clicked.connect( lambda: self.changeDirectory(self.directory)) self.folderButton.clicked.connect(self.changeDirectory) self.fileSelector = QComboBox() self.fileSelector.currentIndexChanged.connect(self.updateScreenCombo) self.screenSelector = QComboBox() self.screenSelector.currentIndexChanged.connect(self.changeScreen) self.beamWidget = QGroupBox() self.beamLayout = QHBoxLayout() self.beamLayout.addWidget(self.fileSelector) self.beamLayout.addWidget(self.screenSelector) self.beamWidget.setLayout(self.beamLayout) self.beamWidget.setMaximumWidth(800) self.beamWidget.setVisible(False) self.folderBeamWidget = QWidget() self.folderBeamLayout = QHBoxLayout() self.folderBeamLayout.setAlignment(Qt.AlignLeft) self.folderBeamWidget.setLayout(self.folderBeamLayout) self.folderBeamLayout.addWidget(self.folderWidget) self.folderBeamLayout.addWidget(self.beamWidget) self.tabWidget.addTab(self.twissPlotView, 'Twiss Plots') self.tabWidget.addTab(self.beamPlotWidget, 'Beam Plots') self.tabWidget.addTab(self.slicePlotWidget, 'Slice Beam Plots') self.tabWidget.currentChanged.connect(self.changeTab) self.layout.addWidget(self.folderBeamWidget) self.layout.addWidget(self.tabWidget) self.plotType = 'Twiss' self.changeDirectory(self.directory) def findFirstEmptyColumnInGraphicsLayout(self): rowsfilled = self.slicePlotWidgetGraphicsLayout.ci.rows.get(0, {}).keys() for i in range(49): if not i in rowsfilled: return i def changeTab(self, i): if self.tabWidget.tabText(i) == 'Beam Plots': self.plotType = 'Beam' self.beamWidget.setVisible(True) elif self.tabWidget.tabText(i) == 'Slice Beam Plots': self.plotType = 'Slice' self.beamWidget.setVisible(True) else: self.plotType = 'Twiss' self.beamWidget.setVisible(False) self.loadDataFile() def changeDirectory(self, directory=None): if directory == None or directory == False: self.directory = str( QFileDialog.getExistingDirectory(self, "Select Directory", self.directory, QFileDialog.ShowDirsOnly)) else: self.directory = directory self.folderLineEdit.setText(self.directory) self.currentFileText = self.fileSelector.currentText() self.currentScreenText = self.screenSelector.currentText() self.getScreenFiles() self.updateFileCombo() self.updateScreenCombo() self.loadDataFile() def getScreenFiles(self): self.screenpositions = {} files = glob.glob(self.directory + '/*.????.???') filenames = [ '.'.join(os.path.basename(f).split('.')[:-2]) for f in files ] print 'filenames = ', filenames runnumber = [os.path.basename(f).split('.')[-1] for f in files] for f, r in list(set(zip(filenames, runnumber))): files = glob.glob(self.directory + '/' + f + '.????.???') screenpositions = [ re.search(f + '\.(\d\d\d\d)\.\d\d\d', s).group(1) for s in files ] print 'screenpositions = ', screenpositions self.screenpositions[f] = { 'screenpositions': sorted(screenpositions), 'run': r } def updateFileCombo(self): self.fileSelector.clear() i = -1 screenfirstpos = [] for f in self.screenpositions: screenfirstpos.append( [f, min(self.screenpositions[f]['screenpositions'])]) screenfirstpos = np.array(screenfirstpos) sortedscreennames = screenfirstpos[np.argsort( np.array(screenfirstpos)[:, 1])] print 'sortedscreennames = ', sortedscreennames for f in sortedscreennames: self.fileSelector.addItem(f[0]) i += 1 if f[0] == self.currentFileText: self.fileSelector.setCurrentIndex(i) def changeScreen(self, i): run = self.screenpositions[str(self.fileSelector.currentText())]['run'] self.beamFileName = str(self.fileSelector.currentText()) + '.' + str( self.screenSelector.currentText()) + '.' + str(run) # print 'beamFileName = ', self.beamFileName self.loadDataFile() def updateScreenCombo(self): self.screenSelector.clear() i = -1 for s in self.screenpositions[str( self.fileSelector.currentText())]['screenpositions']: self.screenSelector.addItem(s) i += 1 if s == self.currentScreenText: self.screenSelector.setCurrentIndex(i) def loadDataFile(self): if self.plotType == 'Twiss': files = sorted(glob.glob(self.directory + "/*Xemit*")) self.twiss.read_astra_emit_files(files) self.plotDataTwiss() elif self.plotType == 'Beam' or self.plotType == 'Slice': if hasattr( self, 'beamFileName') and os.path.isfile(self.directory + '/' + self.beamFileName): # starttime = time.time() self.beam.read_astra_beam_file(self.directory + '/' + self.beamFileName) # print 'reading file took ', time.time()-starttime, 's' # print 'Read file: ', self.beamFileName if self.plotType == 'Beam': self.plotDataBeam() else: self.beam.bin_time() self.plotDataSlice() def plotDataTwiss(self): for entry in self.twissplotLayout: if entry == 'next_row': pass else: x = self.twiss['z'] y = self.twiss[entry['name']] * entry['scale'] xy = np.transpose(np.array([x, y])) x, y = np.transpose(xy[np.argsort(xy[:, 0])]) self.twissPlots[entry['name']].setData(x=x, y=y, pen=mkPen('b', width=3)) def plotDataBeam(self): self.histogramBins = self.beamPlotNumberBins.value() x = getattr(self.beam, str(self.beamPlotXAxisCombo.currentText())) y = getattr(self.beam, str(self.beamPlotYAxisCombo.currentText())) h, xedges, yedges = np.histogram2d(x, y, self.histogramBins, normed=True) x0 = xedges[0] y0 = yedges[0] xscale = (xedges[-1] - xedges[0]) / len(xedges) yscale = (yedges[-1] - yedges[0]) / len(yedges) self.item.setImage(h) self.item.setLookupTable(self.rainbow) # self.item.setLevels([0,1]) def changeSliceLength(self): self.beam.slice_length = self.slicePlotSliceWidthWidget.value() * 1e-15 self.beam.bin_time() self.plotDataSlice() def plotDataSlice(self): for param in self.sliceParams: if self.slicePlotCheckbox[param['name']].isChecked(): x = self.beam.slice_bins self.slicePlot.setRange(xRange=[min(x), max(x)]) # self.plot.setRange(xRange=[-0.5,1.5]) y = getattr(self.beam, param['name']) self.curve[param['name']].setData(x=x, y=y) self.sliceaxis[param['name']][0].setVisible(True) # currentrange = self.sliceaxis[param['name']][0].range # print 'currentrange = ', currentrange # self.sliceaxis[param['name']][0].setRange(0, currentrange[1]) else: # pass self.curve[param['name']].setData(x=[], y=[]) self.sliceaxis[param['name']][0].setVisible(False) self.sliceaxis[param['name']][1].autoRange() currentrange = self.sliceaxis[param['name']][1].viewRange() self.sliceaxis[param['name']][1].setYRange(0, currentrange[1][1]) def scaleLattice(self, vb, range): yrange = range[1] scaleY = 0.05 * abs(yrange[1] - yrange[0]) rect = QRectF(0, yrange[0] + 2 * scaleY, 49.2778, 4 * scaleY) self.latticePlots[vb].setRect(rect)
class Graphexample(): def __init__(self): self.graph = GraphicsLayoutWidget() self.graph.setObjectName("stock UI") self.label = pg.LabelItem(justify='right') self.graph.addItem(self.label) self.p1 = self.graph.addPlot(row=1, col=0) self.p2 = self.graph.addPlot(row=2, col=0) self.p1.showGrid(x=True, y=True, alpha=0.5) self.region = pg.LinearRegionItem() self.region.setZValue(10) # Add the LinearRegionItem to the ViewBox, but tell the ViewBox to exclude this # item when doing auto-range calculations. self.p2.addItem(self.region, ignoreBounds=True) #pg.dbg() self.p1.setAutoVisible(y=True) #create numpy arrays #make the numbers large to show that the xrange shows data from 10000 to all the way 0 self.data1 = 10000 + 15000 * pg.gaussianFilter( np.random.random(size=10000), 10) + 3000 * np.random.random(size=10000) self.data2 = 15000 + 15000 * pg.gaussianFilter( np.random.random(size=10000), 10) + 3000 * np.random.random(size=10000) self.p1.plot(self.data1, pen="r") self.p1.plot(self.data2, pen="g") self.p2.plot(self.data1, pen="w") self.region.sigRegionChanged.connect(self.update) self.p1.sigRangeChanged.connect(self.updateRegion) self.region.setRegion([1000, 2000]) #cross hair self.vLine = pg.InfiniteLine(angle=90, movable=False) self.hLine = pg.InfiniteLine(angle=0, movable=False) self.p1.addItem(self.vLine, ignoreBounds=True) self.p1.addItem(self.hLine, ignoreBounds=True) self.vb = self.p1.vb self.proxy = pg.SignalProxy(self.p1.scene().sigMouseMoved, rateLimit=60, slot=self.mouseMoved) def update(self): self.region.setZValue(10) minX, maxX = self.region.getRegion() self.p1.setXRange(minX, maxX, padding=0) def updateRegion(self, window, viewRange): rgn = viewRange[0] self.region.setRegion(rgn) def mouseMoved(self, evt): pos = evt[ 0] ## using signal proxy turns original arguments into a tuple if self.p1.sceneBoundingRect().contains(pos): mousePoint = self.vb.mapSceneToView(pos) index = int(mousePoint.x()) if index > 0 and index < len(self.data1): self.label.setText( "<span style='font-size: 12pt'>x=%0.1f, <span style='color: red'>y1=%0.1f</span>, <span style='color: green'>y2=%0.1f</span>" % (mousePoint.x(), self.data1[index], self.data2[index])) self.vLine.setPos(mousePoint.x()) self.hLine.setPos(mousePoint.y()) def ret_GraphicsLayoutWidget(self): return self.graph
class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(1150, 699) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.graphicsView = GraphicsLayoutWidget(self.centralwidget) self.graphicsView.setGeometry(QtCore.QRect(180, 10, 931, 651)) self.graphicsView.setObjectName("graphicsView") self.ts_plots = [ self.graphicsView.addPlot(row=i, col=0, colspan=2, title='Channel %d' % i, labels={'left': 'uV'}) for i in range(1, 9) ] self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setGeometry(QtCore.QRect(10, 500, 131, 41)) self.pushButton.setObjectName("pushButton") self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget) self.pushButton_2.setGeometry(QtCore.QRect(10, 390, 131, 41)) self.pushButton_2.setObjectName("pushButton_2") self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget) self.pushButton_3.setGeometry(QtCore.QRect(10, 60, 141, 41)) self.pushButton_3.setObjectName("pushButton_3") self.lcdNumber = QtWidgets.QLCDNumber(self.centralwidget) self.lcdNumber.setGeometry(QtCore.QRect(20, 250, 111, 61)) self.lcdNumber.setSmallDecimalPoint(True) self.lcdNumber.setDigitCount(3) self.lcdNumber.setSegmentStyle(QtWidgets.QLCDNumber.Flat) self.lcdNumber.setObjectName("lcdNumber") self.label = QtWidgets.QLabel(self.centralwidget) self.label.setGeometry(QtCore.QRect(100, 140, 61, 41)) self.label.setObjectName("label") self.textEdit = QtWidgets.QTextEdit(self.centralwidget) self.textEdit.setGeometry(QtCore.QRect(20, 140, 71, 41)) self.textEdit.setObjectName("textEdit") MainWindow.setCentralWidget(self.centralwidget) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.pushButton.setText(_translate("MainWindow", "SALIR")) self.pushButton_2.setText(_translate("MainWindow", "INICIO")) self.pushButton_3.setText(_translate("MainWindow", "ACTUALIZAR")) self.label.setText(_translate("MainWindow", "SEGUNDOS.")) ################################################################################ def save_data(self, sample): global data data.append([i * SCALE_FACTOR for i in sample.channels_data]) def updater(self): global data, plots, colors t_data = np.array(data[-1250:]).T #transpose data fs = 250 #Hz # Plot a time series of the raw data for j in range(8): self.ts_plots[j].clear() # self.ts_plots[j].plot(t_data[j]) self.ts_plots[j].plot(pen=colors[j]).setData(t_data[j])
class MainWidget(QWidget): def __init__(self): QWidget.__init__(self) # define periodic table widget for element selection self.periodicTableWidget = widgets.PeriodicTableDialog() # initial molecule Zmatrix (can be empty) # self.inp = [] self.inp = [['H'], ['O', 1, 0.9], ['O', 2, 1.4, 1, 105.], ['H', 3, 0.9, 2, 105., 1, 120.]] self.atomList = [] self.highList = [] self.labelList = [] self.fast = False # define & initialize ZMatModel that will contain Zmatrix data self.ZMatModel = QStandardItemModel(len(self.inp), 7, self) self.ZMatTable = QTableView(self) self.ZMatTable.setModel(self.ZMatModel) self.ZMatTable.setFixedWidth(325) #self.ZMatTable.installEventFilter(self) #self.ZMatModel.installEventFilter(self) self.ZMatModel.setHorizontalHeaderLabels(['atom','','bond','','angle','','dihedral']) for j, width in enumerate([40, 22, 65, 22, 65, 22, 65]): self.ZMatTable.setColumnWidth(j, width) # populate the ZMatModel self.populateZMatModel() #define Menu bar menus and their actions self.menuBar = QMenuBar(self) fileMenu = self.menuBar.addMenu('&File') editMenu = self.menuBar.addMenu('&Edit') viewMenu = self.menuBar.addMenu('&View') measureMenu = self.menuBar.addMenu('&Measure') helpMenu = self.menuBar.addMenu('&Help') readZmatAction = QAction('&Read &ZMat', self) readZmatAction.setShortcut('Ctrl+O') readZmatAction.setStatusTip('Read Zmat from file') readZmatAction.triggered.connect(self.readZmat) fileMenu.addAction(readZmatAction) readXYZAction = QAction('&Read &XYZ', self) readXYZAction.setShortcut('Ctrl+Shift+O') readXYZAction.setStatusTip('Read XYZ from file') readXYZAction.triggered.connect(self.readXYZ) fileMenu.addAction(readXYZAction) readGaussianAction = QAction('&Read &Gaussian log', self) readGaussianAction.setShortcut('Ctrl+G') readGaussianAction.setStatusTip('Read Gaussian log file') readGaussianAction.triggered.connect(self.readGaussian) fileMenu.addAction(readGaussianAction) writeZmatAction = QAction('&Write &ZMat', self) writeZmatAction.setShortcut('Ctrl+S') writeZmatAction.setStatusTip('Write Zmat to file') writeZmatAction.triggered.connect(self.writeZmat) fileMenu.addAction(writeZmatAction) writeXYZAction = QAction('&Write &XYZ', self) writeXYZAction.setShortcut('Ctrl+Shift+S') writeXYZAction.setStatusTip('Write XYZ from file') writeXYZAction.triggered.connect(self.writeXYZ) fileMenu.addAction(writeXYZAction) exitAction = QAction('&Exit', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit application') exitAction.triggered.connect(qApp.quit) fileMenu.addAction(exitAction) addRowAction = QAction('&Add &row', self) addRowAction.setShortcut('Ctrl+R') addRowAction.setStatusTip('Add row to ZMatrix') addRowAction.triggered.connect(self.addRow) editMenu.addAction(addRowAction) deleteRowAction = QAction('&Delete &row', self) deleteRowAction.setShortcut('Ctrl+Shift+R') deleteRowAction.setStatusTip('Delete row from ZMatrix') deleteRowAction.triggered.connect(self.deleteRow) editMenu.addAction(deleteRowAction) addAtomAction = QAction('&Add &atom', self) addAtomAction.setShortcut('Ctrl+A') addAtomAction.setStatusTip('Add atom to ZMatrix') addAtomAction.triggered.connect(self.buildB) editMenu.addAction(addAtomAction) drawModeMenu = QMenu('Draw mode', self) viewMenu.addMenu(drawModeMenu) fastDrawAction = QAction('&Fast draw', self) fastDrawAction.triggered.connect(self.fastDraw) normalDrawAction = QAction('&Normal draw', self) normalDrawAction.triggered.connect(self.normalDraw) drawModeMenu.addAction(normalDrawAction) drawModeMenu.addAction(fastDrawAction) clearHighlightsAction = QAction('&Clear selection', self) clearHighlightsAction.setShortcut('Ctrl+C') clearHighlightsAction.setStatusTip('Clear highlighted atoms') clearHighlightsAction.triggered.connect(self.clearHighlights) viewMenu.addAction(clearHighlightsAction) clearLabelsAction = QAction('&Clear labels', self) clearLabelsAction.setShortcut('Ctrl+Alt+C') clearLabelsAction.setStatusTip('Clear labels') clearLabelsAction.triggered.connect(self.clearLabels) viewMenu.addAction(clearLabelsAction) clearUpdateViewAction = QAction('&Clear selection and labels', self) clearUpdateViewAction.setShortcut('Ctrl+Shift+C') clearUpdateViewAction.setStatusTip('Clear highlighted atoms and labels') clearUpdateViewAction.triggered.connect(self.clearUpdateView) viewMenu.addAction(clearUpdateViewAction) self.showGaussAction = QAction('Show &Gaussian geometry optimization', self) self.showGaussAction.setShortcut('Ctrl+G') self.showGaussAction.setStatusTip('Show Gaussian geometry optimization plots for energy, force and displacement.') self.showGaussAction.setEnabled(False) self.showGaussAction.triggered.connect(self.showGauss) viewMenu.addAction(self.showGaussAction) self.showFreqAction = QAction('Show &IR frequency plot', self) self.showFreqAction.setShortcut('Ctrl+I') self.showFreqAction.setStatusTip('Show Gaussian calculated IR frequency plot.') self.showFreqAction.setEnabled(False) self.showFreqAction.triggered.connect(self.showFreq) viewMenu.addAction(self.showFreqAction) measureDistanceAction = QAction('&Measure &distance', self) measureDistanceAction.setShortcut('Ctrl+D') measureDistanceAction.setStatusTip('Measure distance between two atoms') measureDistanceAction.triggered.connect(self.measureDistanceB) measureMenu.addAction(measureDistanceAction) measureAngleAction = QAction('&Measure &angle', self) measureAngleAction.setShortcut('Ctrl+Shift+D') measureAngleAction.setStatusTip('Measure angle between three atoms') measureAngleAction.triggered.connect(self.measureAngleB) measureMenu.addAction(measureAngleAction) aboutAction = QAction('&About', self) aboutAction.setStatusTip('About this program...') aboutAction.triggered.connect(self.about) helpMenu.addAction(aboutAction) aboutQtAction = QAction('&About Qt', self) aboutQtAction.setStatusTip('About Qt...') aboutQtAction.triggered.connect(self.aboutQt) helpMenu.addAction(aboutQtAction) # define GL widget that displays the 3D molecule model self.window = widgets.MyGLView() self.window.installEventFilter(self) self.window.setMinimumSize(500, 500) #self.window.setBackgroundColor((50, 0, 10)) self.updateView() self.gaussianPlot = GraphicsLayoutWidget() self.gaussianPlot.resize(750, 250) self.gaussianPlot.setWindowTitle('Gaussian geometry optimization') #self.gaussianPlot.setAspectLocked(True) #self.gaussianPlot.addLayout(rowspan=3, colspan=1) self.FreqModel = QStandardItemModel(1, 3, self) self.freqTable = QTableView(self) self.freqTable.setModel(self.FreqModel) self.freqTable.setMinimumWidth(240) self.freqTable.installEventFilter(self) self.FreqModel.installEventFilter(self) self.FreqModel.setHorizontalHeaderLabels(['Frequency','IR Intensity','Raman Intensity']) for j, width in enumerate([80, 80, 80]): self.freqTable.setColumnWidth(j, width) self.freqWidget = QWidget() self.freqWidget.setWindowTitle('IR frequency plot & table') self.freqWidget.resize(800, 400) self.freqWidget.layout = QHBoxLayout(self.freqWidget) self.freqWidget.layout.setSpacing(1) self.freqWidget.layout.setContentsMargins(1, 1, 1, 1) self.freqPlot = GraphicsLayoutWidget() self.freqWidget.layout.addWidget(self.freqPlot) self.freqWidget.layout.addWidget(self.freqTable) self.freqTable.clicked.connect(self.freqCellClicked) # define other application parts self.statusBar = QStatusBar(self) self.fileDialog = QFileDialog(self) # define application layout self.layout = QVBoxLayout(self) self.layout.setSpacing(1) self.layout.setContentsMargins(1, 1, 1, 1) self.layout1 = QHBoxLayout() self.layout1.setSpacing(1) self.layout1.addWidget(self.ZMatTable) self.layout1.addWidget(self.window) self.layout.addWidget(self.menuBar) self.layout.addLayout(self.layout1) self.layout.addWidget(self.statusBar) self.adjustSize() self.setWindowTitle('Moldy') iconPath = 'icon.png' icon = QIcon(iconPath) icon.addFile(iconPath, QSize(16, 16)) icon.addFile(iconPath, QSize(24, 24)) icon.addFile(iconPath, QSize(32, 32)) icon.addFile(iconPath, QSize(48, 48)) icon.addFile(iconPath, QSize(256, 256)) self.setWindowIcon(icon) # start monitoring changes in the ZMatModel self.ZMatModel.dataChanged.connect(self.clearUpdateView) # run and show the application def run(self): self.show() self.ZMatTable.clicked.connect(self.ZMatCellClicked) qt_app.instance().aboutToQuit.connect(self.deleteGLwidget) qt_app.exec_() # fill the ZMatModel with initial data from 'self.inp' def populateZMatModel(self): self.ZMatModel.removeRows(0, self.ZMatModel.rowCount()) for i, row in enumerate(self.inp): for j, cell in enumerate(row): item = QStandardItem(str(cell)) self.ZMatModel.setItem(i, j, item) # some cells should not be editable, they are disabled for i in range(min(len(self.inp), 3)): for j in range(2*i+1, 7): self.ZMatModel.setItem(i, j, QStandardItem()) self.ZMatModel.item(i, j).setBackground(QColor(150,150,150)) self.ZMatModel.item(i, j).setFlags(Qt.ItemIsEnabled) def populateFreqModel(self): self.FreqModel.removeRows(0, self.FreqModel.rowCount()) for i, row in enumerate(zip(self.vibfreqs, self.vibirs, self.vibramans)): for j, cell in enumerate(row): item = QStandardItem(str(cell)) self.FreqModel.setItem(i, j, item) # add a row to the bottom of the ZMatModel def addRow(self): # temporarily stop updating the GL window self.ZMatModel.dataChanged.disconnect(self.clearUpdateView) row = self.ZMatModel.rowCount() self.ZMatModel.insertRow(row) # some cells should not be editable if row < 3: for j in range(2*row+1, 7): self.ZMatModel.setItem(row, j, QStandardItem()) self.ZMatModel.item(row, j).setBackground(QColor(150,150,150)) self.ZMatModel.item(row, j).setFlags(Qt.ItemIsEnabled) # restart GL window updating self.ZMatModel.dataChanged.connect(self.clearUpdateView) self.statusBar.clearMessage() self.statusBar.showMessage('Added 1 row.', 3000) # delete the last row of the ZMatModel def deleteRow(self): xyz = [list(vi) for vi in list(v)] atoms = [str(elements[e]) for e in elems] oldLen = self.ZMatModel.rowCount() idxs = sorted(set(idx.row() for idx in self.ZMatTable.selectedIndexes()), reverse=True) newLen = oldLen - len(idxs) if newLen == oldLen: self.ZMatModel.removeRow(self.ZMatModel.rowCount()-1) else: self.ZMatModel.dataChanged.disconnect(self.clearUpdateView) for idx in idxs: self.ZMatModel.removeRow(idx) if idx < 3: for i in range(idx, min(3, newLen)): for j in range(2*i+1, 7): self.ZMatModel.setItem(i, j, QStandardItem()) self.ZMatModel.item(i, j).setBackground(QColor(150,150,150)) self.ZMatModel.item(i, j).setFlags(Qt.ItemIsEnabled) if len(xyz) > idx: xyz.pop(idx) atoms.pop(idx) self.inp = xyz2zmat(xyz, atoms) self.populateZMatModel() for i in reversed(self.highList): self.window.removeItem(i[1]) self.highList = [] self.ZMatModel.dataChanged.connect(self.clearUpdateView) self.updateView() self.statusBar.clearMessage() if idxs: self.statusBar.showMessage('Deleted row(s): '+str([i+1 for i in idxs]), 3000) else: self.statusBar.showMessage('Deleted last row.', 3000) # show the periodic table widget def periodicTable(self): self.statusBar.clearMessage() self.statusBar.showMessage('Select element from periodic table.') self.periodicTableWidget.exec_() selection = self.periodicTableWidget.selection() return selection # import molecule with zmatrix coordinates def readZmat(self): self.ZMatModel.dataChanged.disconnect(self.clearUpdateView) filename = self.fileDialog.getOpenFileName(self, 'Open file', expanduser('~'), '*.zmat;;*.*') self.inp = [] self.populateZMatModel() if filename: with open(filename, 'r') as f: next(f) next(f) for row in f: self.inp.append(row.split()) f.close() self.populateZMatModel() self.ZMatModel.dataChanged.connect(self.clearUpdateView) self.updateView() self.statusBar.clearMessage() self.statusBar.showMessage('Read molecule from '+filename+'.', 5000) self.showGaussAction.setEnabled(False) self.showFreqAction.setEnabled(False) # import molecule with xyz coordinates def readXYZ(self): self.ZMatModel.dataChanged.disconnect(self.clearUpdateView) filename = self.fileDialog.getOpenFileName(self, 'Open file', expanduser('~'), '*.xyz;;*.*') xyz = [] elems = [] self.inp = [] self.populateZMatModel() if filename: with open(filename, 'r') as f: next(f) next(f) for row in f: rs = row.split() if len(rs) == 4: elems.append(rs[0]) xyz.append([float(f) for f in rs[1:]]) f.close() self.inp = xyz2zmat(xyz, elems) self.populateZMatModel() #print(elems) self.ZMatModel.dataChanged.connect(self.clearUpdateView) self.updateView() self.statusBar.clearMessage() self.statusBar.showMessage('Read molecule from '+filename+'.', 5000) self.showGaussAction.setEnabled(False) self.showFreqAction.setEnabled(False) # import Gaussian log file def readGaussian(self): global vsShifted self.ZMatModel.dataChanged.disconnect(self.clearUpdateView) filename = self.fileDialog.getOpenFileName(self, 'Open file', expanduser('~'), '*.log;;*.*') if filename: self.gaussianPlot.clear() self.inp = [] self.populateZMatModel() file = ccopen(filename) data = file.parse().getattributes() self.natom = data['natom'] self.atomnos = data['atomnos'].tolist() self.atomsymbols = [ str(elements[e]) for e in self.atomnos ] self.atomcoords = data['atomcoords'].tolist() self.scfenergies = data['scfenergies'].tolist() self.geovalues = data['geovalues'].T.tolist() self.geotargets = data['geotargets'].tolist() if 'vibfreqs' in data.keys(): self.vibfreqs = data['vibfreqs'] #print(self.vibfreqs) self.vibirs = data['vibirs'] #print(self.vibirs) #print(data.keys()) if 'vibramans' in data.keys(): self.vibramans = data['vibramans'] else: self.vibramans = [''] * len(self.vibirs) self.vibdisps = data['vibdisps'] #print(self.vibdisps) self.inp = xyz2zmat(self.atomcoords[0], self.atomsymbols) self.populateZMatModel() titles = ['SCF Energies', 'RMS & Max Forces', 'RMS & Max Displacements'] for i in range(3): self.gaussianPlot.addPlot(row=1, col=i+1) plot = self.gaussianPlot.getItem(1, i+1) plot.setTitle(title=titles[i]) if i == 0: c = ['c'] x = [0] y = [self.scfenergies] else: c = ['r', 'y'] x = [0, 0] y = [self.geovalues[2*i-2], self.geovalues[2*i-1]] targety = [self.geotargets[2*i-2], self.geotargets[2*i-1]] plot.clear() plot.maxData = plot.plot(y[0], symbol='o', symbolPen=c[0], symbolBrush=c[0], pen=c[0], symbolSize=5, pxMode=True, antialias=True, autoDownsample=False) plot.highlight=plot.plot(x, [ yy[0] for yy in y ], symbol='o', symbolPen='w', symbolBrush=None, pen=None, symbolSize=15, pxMode=True, antialias=True, autoDownsample=False) plot.maxData.sigPointsClicked.connect(self.gausclicked) if i > 0: for j in range(2): plot.addLine(y=np.log10(targety[j]), pen=mkPen((255, 255*j, 0, int(255/2)), width=1)) plot.RMSData=plot.plot(y[1], symbol='o', symbolPen=c[1], symbolBrush=c[1], pen=c[1], symbolSize=5, pxMode=True, antialias=True, autoDownsample=False) plot.RMSData.sigPointsClicked.connect(self.gausclicked) plot.setLogMode(y=True) self.showGauss() self.updateView() self.statusBar.clearMessage() self.statusBar.showMessage('Read molecule from '+filename+'.', 5000) self.ZMatModel.dataChanged.connect(self.clearUpdateView) if self.natom: self.showGaussAction.setEnabled(True) if 'vibfreqs' in data.keys(): self.showFreqAction.setEnabled(True) # populate the FreqModel self.populateFreqModel() self.freqPlot.clear() irPlot = self.freqPlot.addPlot(row=1, col=1) irPlot.clear() minFreq = np.min(self.vibfreqs) maxFreq = np.max(self.vibfreqs) maxInt = np.max(self.vibirs) x = np.sort(np.concatenate([np.linspace(minFreq-100, maxFreq+100, num=1000), self.vibfreqs])) y = x*0 for f,i in zip(self.vibfreqs, self.vibirs): y += lorentzv(x, f, 2*np.pi, i) #xy = np.array([np.concatenate([x, np.array(self.vibfreqs)]), np.concatenate([y, np.array(self.vibirs)])]).T #xysort = xy[xy[:,0].argsort()] irPlot.maxData = irPlot.plot(x, y, antialias=True) markers = ErrorBarItem(x=self.vibfreqs, y=self.vibirs, top=maxInt/30, bottom=None, pen='r') irPlot.addItem(markers) self.showFreq() #self.vibdisps = np.append(self.vibdisps, [np.mean(self.vibdisps, axis=0)], axis=0) maxt = 100 vsShifted = np.array([ [ vs + self.vibdisps[i]*np.sin(t*2*np.pi/maxt)/3 for t in range(maxt) ] for i in range(len(self.vibfreqs)) ]) else: self.showFreqAction.setEnabled(False) self.freqWidget.hide() def showGauss(self): self.gaussianPlot.show() def showFreq(self): self.freqWidget.show() # export Zmatrix to csv def writeZmat(self): zm = model2list(self.ZMatModel) filename = self.fileDialog.getSaveFileName(self, 'Save file', expanduser('~')+'/'+getFormula(list(list(zip(*zm))[0]))+'.zmat', '*.zmat;;*.*') try: filename except NameError: pass else: if filename: writeOutput(zm, filename) self.statusBar.clearMessage() self.statusBar.showMessage('Wrote molecule to '+filename+'.', 5000) # export XYZ coordinates to csv def writeXYZ(self): xyz = [] zm = model2list(self.ZMatModel) for i in range(len(v)): xyz.append(np.round(v[i], 7).tolist()) xyz[i][:0] = zm[i][0] if len(v) > 0: formula = getFormula(list(list(zip(*xyz))[0])) else: formula = 'moldy_output' filename = self.fileDialog.getSaveFileName(self, 'Save file', expanduser('~')+'/'+formula+'.xyz', '*.xyz;;*.*') try: filename except NameError: pass else: if filename: writeOutput(xyz, filename) self.statusBar.clearMessage() self.statusBar.showMessage('Wrote molecule to '+filename+'.', 5000) # redraw the 3D molecule in GL widget def updateView(self): global r global c global v global vs global elems global nelems data = model2list(self.ZMatModel) try: # create a list with element coordinates v = zmat2xyz(data) except (AssertionError, IndexError, ZMError): pass else: # clear the screen before redraw for item in reversed(self.window.items): self.window.removeItem(item) # create a second coordinate list 'vs' that is centered in the GL view self.atomList = [] if len(v) > 0: shift = np.mean(v, axis=0) vs = np.add(v, -shift) elems = [ 1 + next((i for i, sublist in enumerate(colors) if row[0] in sublist), -1) for row in data ] nelems = len(elems) # define molecule radii and colors r = [] c = [] for i in elems: r.append(elements[i].covalent_radius) c.append(colors[i-1][-1]) # draw atoms for i in range(nelems): addAtom(self.window, i, r, vs, c, fast=self.fast) self.atomList.append([i, self.window.items[-1]]) #print(self.atomList) # draw bonds where appropriate combs = list(itertools.combinations(range(nelems), 2)) bonds = [] for i in combs: bonds.append(addBond(self.window, i[0], i[1], r, vs, c, fast=self.fast)) if self.fast: bondedAtoms = set(filter((None).__ne__, flatten(bonds))) for i in set(range(nelems)) - bondedAtoms: addUnbonded(self.window, i, vs, c) self.atomList[i][1]=self.window.items[-1] #print(self.atomList) for i in self.highList: self.window.addItem(i[1]) for i in self.labelList: self.window.addItem(i) if len(v) > 1: maxDim = float('-inf') for dim in v.T: span = max(dim)-min(dim) if span > maxDim: maxDim = span else: maxDim = 2 self.window.setCameraPosition(distance=maxDim*1.5+1) global index index = 0 def updateFreq(self): global vsShifted, index, r, c index += 1 index = index % len(vsShifted[0]) #print(index) #print(vsShifted[index]) for item in reversed(self.window.items): self.window.removeItem(item) for i in range(nelems): addAtom(self.window, i, r, vsShifted[self.freqIndex, index], c, fast=self.fast) self.atomList.append([i, self.window.items[-1]]) combs = itertools.combinations(range(nelems), 2) bonds = [] for i in combs: bonds.append(addBond(self.window, i[0], i[1], r, vsShifted[self.freqIndex, index], c, fast=self.fast)) if self.fast: bondedAtoms = set(filter((None).__ne__, flatten(bonds))) for i in set(range(nelems)) - bondedAtoms: addUnbonded(self.window, i, vsShifted[self.freqIndex, index], c) self.atomList[i][1]=self.window.items[-1] # detect mouse clicks in GL window and process them def eventFilter(self, obj, event): if obj == self.window: if event.type() == event.MouseButtonPress: itms = obj.itemsAt((event.pos().x()-2, event.pos().y()-2, 4, 4)) if len(itms): self.highlight(obj, [itms[0]]) elif len(self.atomList) == 0: self.build() # also do the default click action return super(MainWidget, self).eventFilter(obj, event) def ZMatCellClicked(self): idxs = sorted(set(idx.row() for idx in self.ZMatTable.selectedIndexes()), reverse=True) itms = [] if self.highList: highIdx = list(np.array(self.highList).T[0]) for idx in idxs: if self.highList and idx in highIdx: itms.append(self.highList[highIdx.index(idx)][1]) elif len(self.atomList) > idx: itms.append(self.atomList[idx][1]) self.highlight(self.window, itms) def freqCellClicked(self): global vsShifted self.timer = QTimer() self.timer.setInterval(30) self.timer.timeout.connect(self.updateFreq) idxs = [ idx.row() for idx in self.freqTable.selectedIndexes() ] if len(idxs) == 1: self.freqIndex = idxs[0] self.timer.stop() self.timer.timeout.connect(self.updateFreq) try: self.ZMatModel.dataChanged.disconnect(self.clearUpdateView) except TypeError: pass self.timer.start() if len(idxs) != 1: self.timer.stop() self.freqTable.clearSelection() self.timer.timeout.disconnect(self.updateFreq) self.ZMatModel.dataChanged.connect(self.clearUpdateView) self.clearUpdateView() def gausclicked(self, item, point): itemdata = item.scatter.data points = [ row[7] for row in itemdata ] idx = points.index(point[0]) for i in range(3): if i == 0: x = [idx] y = [self.scfenergies[idx]] else: x = [idx, idx] y = [self.geovalues[2*i-2][idx], self.geovalues[2*i-1][idx]] plot = self.gaussianPlot.getItem(1, i+1) plot.removeItem(plot.highlight) plot.highlight=plot.plot(x, y, symbol='o', symbolPen='w', symbolBrush=None, pen=None, symbolSize=15, pxMode=True, antialias=True, autoDownsample=False) self.ZMatModel.dataChanged.disconnect(self.clearUpdateView) self.inp = [] self.populateZMatModel() self.inp = xyz2zmat(self.atomcoords[min(idx, len(self.atomcoords)-1)], self.atomsymbols) self.populateZMatModel() self.ZMatModel.dataChanged.connect(self.clearUpdateView) self.updateView() def highlight(self, obj, itms): for itm in itms: idx = next((i for i, sublist in enumerate(self.atomList) if itm in sublist), -1) #print(idx) if idx != -1: addAtom(obj, idx, r, vs, c, opt='highlight', fast=self.fast) self.highList.append([idx, obj.items[-1]]) self.ZMatTable.selectRow(idx) idx = next((i for i, sublist in enumerate(self.highList) if itm in sublist), -1) if idx != -1: obj.removeItem(self.highList[idx][1]) self.highList.pop(idx) self.ZMatTable.clearSelection() self.statusBar.clearMessage() if len(self.highList) > 0: idxs = np.asarray(self.highList).T[0] selected = [] for i in idxs: selected.append(str(i+1)+str(elements[elems[i]])) self.statusBar.showMessage('Selected atoms: '+str(selected), 5000) def buildB(self): try: nelems except NameError: self.build() else: if len(self.highList) <= min(nelems, 3): diff = min(nelems, 3) - len(self.highList) if diff != 0: self.statusBar.clearMessage() self.statusBar.showMessage('Please select '+str(diff)+' more atom(s).') else: self.build() else: self.statusBar.clearMessage() self.statusBar.showMessage('Too many atoms selected.') def build(self): selection = self.periodicTable() row = self.ZMatModel.rowCount() self.addRow() self.ZMatModel.dataChanged.disconnect(self.clearUpdateView) newSymbol = selection[1] newData = [newSymbol] if len(self.highList) >= 1: newBond = round(2.1*gmean([ elements[e].covalent_radius for e in [selection[0], elems[self.highList[0][0]]] ]), 4) newData.append(self.highList[0][0]+1) newData.append(newBond) if len(self.highList) >= 2: newAngle = 109.4712 newData.append(self.highList[1][0]+1) newData.append(newAngle) if len(self.highList) == 3: newDihedral = 120. newData.append(self.highList[2][0]+1) newData.append(newDihedral) for j, cell in enumerate(newData): item = QStandardItem(str(cell)) self.ZMatModel.setItem(row, j, item) self.highList = [] self.ZMatModel.dataChanged.connect(self.clearUpdateView) self.updateView() def measureDistanceB(self): sel = len(self.highList) if sel <= 2: if sel < 2: self.statusBar.clearMessage() self.statusBar.showMessage('Please select '+str(2-sel)+' more atom(s).') else: self.measureDistance() else: self.statusBar.clearMessage() self.statusBar.showMessage('Too many atoms selected.') def measureDistance(self): pts = [] for pt in self.highList: pts.append(vs[pt[0]]) pts = np.array(pts) self.clearHighlights() line = gl.GLLinePlotItem(pos=pts, color=(0., 1., 0., 1.), width=3) self.window.addItem(line) self.labelList.append(line) q = pts[1]-pts[0] dist = round(np.sqrt(np.dot(q, q)), 4) self.window.labelPos.append(np.mean(pts[0:2], axis=0)) self.window.labelText.append(str(dist)) self.statusBar.clearMessage() self.statusBar.showMessage('Measured distance: '+str(dist)+' A.', 3000) def measureAngleB(self): sel = len(self.highList) if sel <= 3: if sel < 3: self.statusBar.clearMessage() self.statusBar.showMessage('Please select '+str(3-sel)+' more atom(s).') else: self.measureAngle() else: self.statusBar.clearMessage() self.statusBar.showMessage('Too many atoms selected.') def measureAngle(self): pts = [] for pt in self.highList: pts.append(vs[pt[0]]) pts = np.array(pts) q = pts[1]-pts[0] r = pts[2]-pts[0] q_u = q / np.sqrt(np.dot(q, q)) r_u = r / np.sqrt(np.dot(r, r)) angle = round(degrees(acos(np.dot(q_u, r_u))), 1) srange = np.array([slerp(q, r, t) for t in np.arange(0.0, 13/12, 1/12)]) self.clearHighlights() for i in range(12): mesh = gl.MeshData(np.array([[0,0,0],srange[i],srange[i+1]])) tri = gl.GLMeshItem(meshdata=mesh, smooth=False, computeNormals=False, color=(0.3, 1., 0.3, 0.5), glOptions=('translucent')) tri.translate(pts[0][0], pts[0][1], pts[0][2]) self.window.addItem(tri) self.labelList.append(tri) self.window.labelPos.append(slerp(q, r, 0.5)+pts[0]) self.window.labelText.append(str(angle)) self.statusBar.clearMessage() self.statusBar.showMessage('Measured angle: '+str(angle)+'°', 3000) def clearLabels(self): self.window.labelPos = [] self.window.labelText = [] self.labelList = [] self.updateView() def clearHighlights(self): for item in reversed(self.highList): self.window.removeItem(item[1]) self.highList = [] self.updateView() def clearUpdateView(self): self.window.labelPos = [] self.window.labelText = [] self.labelList = [] for item in reversed(self.highList): self.window.removeItem(item[1]) self.highList = [] self.updateView() #print(self.highList) def fastDraw(self): if not self.fast: self.fast = True self.updateView() def normalDraw(self): if self.fast: self.fast = False self.updateView() def about(self): QMessageBox.about(self, 'About moldy', 'moldy beta 15. 9. 2015') def aboutQt(self): QMessageBox.aboutQt(self, 'About Qt') def deleteGLwidget(self): self.window.setParent(None) del self.window
class Ui_MainWindow(QMainWindow): def __init__(self): super(Ui_MainWindow, self).__init__() self.traindata = [] self.traindata4 = [] self.traindata3 = [] self.numberofclasses = 0 self.trueTestDataLabels = [] self.labeltestdata = [] self.testData = [] self.trueTestDataLabels4 = [] self.labeltestdata4 = [] self.testData4 = [] self.trueTestDataLabels3 = [] self.labeltestdata3 = [] self.testData3 = [] def setupUi(self): self.centralwidget = QtWidgets.QWidget() self.setMinimumSize(QtCore.QSize(1288, 696)) self.setMaximumSize(QtCore.QSize(1288, 696)) self.centralwidget.setObjectName("centralwidget") self.graphicsView = GraphicsLayoutWidget(self.centralwidget) self.graphicsView.setGeometry(QtCore.QRect(10, 80, 751, 321)) self.graphicsView.setObjectName("graphicsView") self.pushButtonExplore = QtWidgets.QPushButton(self.centralwidget) self.pushButtonExplore.setGeometry(QtCore.QRect(12, 402, 337, 27)) self.pushButtonExplore.setObjectName("pushButtonExplore") self.graphicsView_2 = GraphicsLayoutWidget(self.centralwidget) self.graphicsView_2.setGeometry(QtCore.QRect(10, 440, 751, 221)) self.graphicsView_2.setObjectName("graphicsView_2") self.layoutWidget = QtWidgets.QWidget(self.centralwidget) self.layoutWidget.setGeometry(QtCore.QRect(11, 11, 750, 62)) self.layoutWidget.setObjectName("layoutWidget") self.gridLayout = QtWidgets.QGridLayout(self.layoutWidget) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setObjectName("gridLayout") self.pushButtotLoadIris = QtWidgets.QPushButton(self.layoutWidget) self.pushButtotLoadIris.setObjectName("pushButtotLoadIris") self.gridLayout.addWidget(self.pushButtotLoadIris, 0, 0, 1, 2) self.checkBoxSuspended = QtWidgets.QCheckBox(self.layoutWidget) self.checkBoxSuspended.setObjectName("checkBoxSuspended") self.gridLayout.addWidget(self.checkBoxSuspended, 0, 2, 1, 3) self.pushButtonCheckTest = QtWidgets.QPushButton(self.layoutWidget) self.pushButtonCheckTest.setObjectName("pushButtonCheckTest") self.gridLayout.addWidget(self.pushButtonCheckTest, 0, 5, 1, 3) self.pushButtonGenerate = QtWidgets.QPushButton(self.layoutWidget) self.pushButtonGenerate.setObjectName("pushButtonGenerate") self.gridLayout.addWidget(self.pushButtonGenerate, 1, 0, 1, 1) self.label_3 = QtWidgets.QLabel(self.layoutWidget) self.label_3.setObjectName("label_3") self.gridLayout.addWidget(self.label_3, 1, 1, 1, 2) self.spinBoxClasses = QtWidgets.QSpinBox(self.layoutWidget) self.spinBoxClasses.setMinimum(1) self.spinBoxClasses.setMaximum(10) self.spinBoxClasses.setObjectName("spinBoxClasses") self.gridLayout.addWidget(self.spinBoxClasses, 1, 3, 1, 1) self.label_2 = QtWidgets.QLabel(self.layoutWidget) self.label_2.setObjectName("label_2") self.gridLayout.addWidget(self.label_2, 1, 4, 1, 1) self.spinBoxElements = QtWidgets.QSpinBox(self.layoutWidget) self.spinBoxElements.setMinimum(1) self.spinBoxElements.setProperty("value", 20) self.spinBoxElements.setObjectName("spinBoxElements") self.gridLayout.addWidget(self.spinBoxElements, 1, 5, 1, 1) self.label = QtWidgets.QLabel(self.layoutWidget) self.label.setObjectName("label") self.gridLayout.addWidget(self.label, 1, 6, 1, 1) self.spinBoxK = QtWidgets.QSpinBox(self.layoutWidget) self.spinBoxK.setMinimum(3) self.spinBoxK.setSingleStep(2) self.spinBoxK.setObjectName("spinBoxK") self.gridLayout.addWidget(self.spinBoxK, 1, 7, 1, 1) self.graphicsView_3 = GraphicsLayoutWidget(self.centralwidget) self.graphicsView_3.setGeometry(QtCore.QRect(790, 80, 441, 311)) self.graphicsView_3.setObjectName("graphicsView_3") self.pushButtonCompare = QtWidgets.QPushButton(self.centralwidget) self.pushButtonCompare.setGeometry(QtCore.QRect(790, 40, 361, 31)) self.pushButtonCompare.setObjectName("pushButtonCompare") self.retranslateUi() QtCore.QMetaObject.connectSlotsByName(self) self.w1 = self.graphicsView.addPlot() self.w2 = self.graphicsView_2.addPlot() self.w3 = self.graphicsView_3.addPlot() self.legend = self.w2.addLegend() self.legend1 = self.w3.addLegend() self.w1.scene().sigMouseClicked.connect(self.onClick) self.pushButtonGenerate.clicked.connect(self.generateDate) self.pushButtotLoadIris.clicked.connect(self.loadIris) self.pushButtonCheckTest.clicked.connect(self.checkTest) self.pushButtonExplore.clicked.connect(self.explore) self.pushButtonCompare.clicked.connect(self.compareOptions) self.setCentralWidget(self.centralwidget) def retranslateUi(self): _translate = QtCore.QCoreApplication.translate self.pushButtonExplore.setText( _translate("MainWindow", "Исследование влияния k для разных метрик")) self.pushButtotLoadIris.setText( _translate("MainWindow", "Загрузить данные с ирисом")) self.checkBoxSuspended.setText( _translate("MainWindow", "Использовать взвешенный kNN")) self.pushButtonCheckTest.setText( _translate("MainWindow", "Проверить тестовую выборку")) self.pushButtonGenerate.setText( _translate("MainWindow", "Сгенерировать выборку")) self.label_3.setText(_translate("MainWindow", "Кол-во классов")) self.label_2.setText(_translate("MainWindow", "Кол-во элементов")) self.label.setText(_translate("MainWindow", "Кол-во соседей(K)")) self.pushButtonCompare.setText( _translate("MainWindow", "Сравнить точность от 2,3,4 признаков для ириса")) def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: self.close() if e.key() == Qt.Key_Delete: self.w1.clear() classes = [] i = 0 while i < 20: classes.append([]) i += 1 for i in self.traindata: classes[i[1]].append(np.asarray(i[0])) i = 0 for j in classes: myS = pg.ScatterPlotItem(size=10, pen=pg.mkPen(colors[i]), brush=pg.mkBrush(255, 255, 255, 120)) myspots = [] if (len(j)): for k in j: myspots.append({'pos': k, 'data': i}) i += 1 myS.addPoints(myspots) self.w1.addItem(myS) def onClick(self, event): if len(self.traindata) == 0: return 1 vb = self.w1.vb mousePoint = vb.mapSceneToView(event.scenePos()) testdata = [[mousePoint.x(), mousePoint.y()]] testDataLabels = classifyKNN(self.traindata, testdata, self.spinBoxK.value(), self.numberofclasses, self.checkBoxSuspended.isChecked(), 0) myS = pg.ScatterPlotItem(size=10, pen=pg.mkPen(colors[testDataLabels[0]]), brush=pg.mkBrush(255, 255, 255, 120)) myspots = [] myspots.append({ 'pos': np.asarray([mousePoint.x(), mousePoint.y()]), 'data': testDataLabels[0] }) myS.addPoints(myspots) self.w1.addItem(myS) self.traindata.append([[mousePoint.x(), mousePoint.y()], testDataLabels[0]]) print(self.traindata) def loadIris(self): self.w1.clear() self.traindata = [] self.traindata4 = [] self.traindata3 = [] self.trueTestDataLabels = [] self.labeltestdata = [] self.testData = [] self.trueTestDataLabels4 = [] self.labeltestdata4 = [] self.testData4 = [] self.trueTestDataLabels3 = [] self.labeltestdata3 = [] self.testData3 = [] from sklearn.datasets import load_iris train = load_iris().data labels = load_iris().target self.traindata4 = [] n = 0 for i in train: self.traindata4.append([]) self.traindata4[n].append(i.tolist()) self.traindata4[n].append(labels[n]) n += 1 # testDataLabels = classifyKNN(trainData, testData, 5, 2) trainData4, self.trueTestDataLabels4 = splitTrainTest( self.traindata4, 0.33) self.traindata4 = trainData4 self.testData4 = [ self.trueTestDataLabels4[i][0] for i in range(len(self.trueTestDataLabels4)) ] # self.labeltestdata = classifyKNN(trainData, self.testData, self.spinBoxK.value(), self.numberofclasses,self.checkBoxSuspended.isChecked()) for i in trainData4: self.traindata3.append([i[0][:-1], i[1]]) print(self.traindata3) # self.labeltestdata = classifyKNN(trainData, self.testData, self.spinBoxK.value(), self.numberofclasses,self.checkBoxSuspended.isChecked()) for i in self.testData4: self.testData3.append(i[:-1]) print(i[:-1]) for i in self.trueTestDataLabels4: self.trueTestDataLabels3.append([i[0][:-1], i[1]]) classes = [] i = 0 for i in trainData4: self.traindata.append([i[0][:-2], i[1]]) print(self.traindata3) # self.labeltestdata = classifyKNN(trainData, self.testData, self.spinBoxK.value(), self.numberofclasses,self.checkBoxSuspended.isChecked()) for i in self.testData4: self.testData.append(i[:-2]) print(i[:-1]) for i in self.trueTestDataLabels4: self.trueTestDataLabels.append([i[0][:-2], i[1]]) i = 0 while i < 20: classes.append([]) i += 1 for i in self.traindata: classes[i[1]].append(np.asarray(i[0])) i = 0 for j in classes: myS = pg.ScatterPlotItem(size=10, pen=pg.mkPen(colors[i]), brush=pg.mkBrush(255, 255, 255, 120)) myspots = [] if (len(j)): for k in j: myspots.append({'pos': k, 'data': i}) i += 1 myS.addPoints(myspots) self.w1.addItem(myS) self.spinBoxClasses.setValue(3) self.spinBoxK.setValue(4) self.spinBoxK.setSingleStep(3) self.spinBoxElements.setValue(75) self.spinBoxClasses.setValue(3) self.numberofclasses = 3 def checkTest(self): if len(self.traindata) == 0: return 1 print(self.testData) self.labeltestdata = classifyKNN(self.traindata, self.testData, self.spinBoxK.value(), self.numberofclasses, self.checkBoxSuspended.isChecked(), 0) x = sum([ int(self.labeltestdata[i] == self.trueTestDataLabels[i][1]) for i in range(len(self.trueTestDataLabels)) ]) / float(len(self.trueTestDataLabels)) classes = [] i = 0 while i < 20: classes.append([]) i += 1 for i in self.trueTestDataLabels: classes[i[1]].append(np.asarray(i[0])) i = 0 for j in classes: myS = pg.ScatterPlotItem(size=10, pen=pg.mkPen(colors[i]), brush=pg.mkBrush(255, 255, 255, 120)) myspots = [] if (len(j)): for k in j: myspots.append({'pos': k, 'data': i}) i += 1 myS.addPoints(myspots) self.w1.addItem(myS) dialog = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Information, "Точность классификации ", str(x), buttons=QtWidgets.QMessageBox.Ok, parent=None) result = dialog.exec_() def changeK(self, i): self.spinBoxK.setSingleStep(i) self.spinBoxK.setMinimum(i + 1) self.spinBoxK.setProperty("value", i + 1) def generateDate(self): self.w1.clear() data = generateData(self.spinBoxElements.value(), self.spinBoxClasses.value()) self.numberofclasses = self.spinBoxClasses.value() trainData, self.trueTestDataLabels = splitTrainTest(data, 0.33) self.traindata = trainData self.testData = [ self.trueTestDataLabels[i][0] for i in range(len(self.trueTestDataLabels)) ] # self.labeltestdata = classifyKNN(trainData, self.testData, self.spinBoxK.value(), self.numberofclasses,self.checkBoxSuspended.isChecked()) classes = [] i = 0 while i < 20: classes.append([]) i += 1 for i in trainData: classes[i[1]].append(np.asarray(i[0])) i = 0 for j in classes: myS = pg.ScatterPlotItem(size=10, pen=pg.mkPen(colors[i]), brush=pg.mkBrush(255, 255, 255, 120)) myspots = [] if (len(j)): for k in j: myspots.append({'pos': k, 'data': i}) i += 1 myS.addPoints(myspots) self.w1.addItem(myS) def explore(self): if not (self.traindata): return trainData = [] testData = [] trueTestDataLabels = [] msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setWindowTitle("Выбор количества признаков") msg.setText("Privet") twoOptions = msg.addButton('2 признака', QMessageBox.AcceptRole) threeOptions = msg.addButton('3 признака', QMessageBox.AcceptRole) fourOptions = msg.addButton('4 признака', QMessageBox.AcceptRole) msg.exec() if msg.clickedButton() == twoOptions: trainData = self.traindata testData = self.testData trueTestDataLabels = self.trueTestDataLabels elif msg.clickedButton() == threeOptions: trainData = self.traindata3 testData = self.testData3 trueTestDataLabels = self.trueTestDataLabels3 elif msg.clickedButton() == fourOptions: trainData = self.traindata4 testData = self.testData4 trueTestDataLabels = self.trueTestDataLabels4 self.w2.clear() self.legend.scene().removeItem(self.legend) self.legend = self.w2.addLegend((20, 20), (420, 20)) myspots = [] i = self.spinBoxK.value() while i < self.spinBoxElements.value(): labeltestdata = classifyKNN(trainData, testData, i, self.numberofclasses, self.checkBoxSuspended.isChecked(), 0) myspots.append([ i, sum([ int(labeltestdata[i] == trueTestDataLabels[i][1]) for i in range(len(trueTestDataLabels)) ]) / float(len(trueTestDataLabels)) ]) i += self.spinBoxK.singleStep() self.w2.plot( x=[x[0] for x in myspots], y=[y[1] for y in myspots], symbol='o', name="Евклидово расстояние", pen=(0, 0, 255), ) myspots = [] i = self.spinBoxK.value() while i < self.spinBoxElements.value(): labeltestdata = classifyKNN(trainData, testData, i, self.numberofclasses, self.checkBoxSuspended.isChecked(), 1) myspots.append([ i, sum([ int(labeltestdata[i] == trueTestDataLabels[i][1]) for i in range(len(trueTestDataLabels)) ]) / float(len(trueTestDataLabels)) ]) i += self.spinBoxK.singleStep() self.w2.plot(x=[x[0] for x in myspots], y=[y[1] for y in myspots], pen=(255, 0, 0), symbolBrush=(255, 0, 0), symbolPen='w', name="Манхэттенское расстояние") myspots = [] i = self.spinBoxK.value() while i < self.spinBoxElements.value(): labeltestdata = classifyKNN(trainData, testData, i, self.numberofclasses, self.checkBoxSuspended.isChecked(), 2) myspots.append([ i, sum([ int(labeltestdata[i] == trueTestDataLabels[i][1]) for i in range(len(trueTestDataLabels)) ]) / float(len(trueTestDataLabels)) ]) i += self.spinBoxK.singleStep() self.w2.plot(x=[x[0] for x in myspots], y=[y[1] for y in myspots], pen=(0, 255, 0), symbolBrush=(0, 255, 0), symbolPen='g', name="Расстояние Чебышева") self.w2.setLabels(title='Сравнение метрик', left="Точность", bottom="K") self.setMinimumSize(QtCore.QSize(1288, 717)) self.setMaximumSize(QtCore.QSize(1288, 717)) #self.w2.plot(myspots, pen=(200, 200, 200), symbolBrush=(255, 0, 0), symbolPen='w') def compareOptions(self): if not (self.traindata): return self.w3.clear() self.legend1.scene().removeItem(self.legend1) self.legend1 = self.w3.addLegend((20, 20), (20, 0)) msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setWindowTitle("Выбор метрики") msg.setText("Privet") twoOptions = msg.addButton('Евклидово расстояние', QMessageBox.AcceptRole) threeOptions = msg.addButton('Манхэттенское расстояние', QMessageBox.AcceptRole) fourOptions = msg.addButton('Расстояние Чебышева', QMessageBox.AcceptRole) msg.exec() if msg.clickedButton() == twoOptions: metrick = 0 elif msg.clickedButton() == threeOptions: metrick = 1 elif msg.clickedButton() == fourOptions: metrick = 2 myspots = [] i = self.spinBoxK.value() while i < self.spinBoxElements.value(): self.labeltestdata4 = classifyKNN( self.traindata4, self.testData4, i, self.numberofclasses, self.checkBoxSuspended.isChecked(), metrick) myspots.append([ i, sum([ int(self.labeltestdata4[i] == self.trueTestDataLabels4[i] [1]) for i in range(len(self.trueTestDataLabels4)) ]) / float(len(self.trueTestDataLabels4)) ]) i += self.spinBoxK.singleStep() self.w3.plot(x=[x[0] for x in myspots], y=[y[1] for y in myspots], pen=(0, 255, 0), symbolBrush=(0, 255, 0), symbolPen='g', name="Четыре признака") self.w3.setLabels(title='Сравнение точности в зависимости от признака', left="Точность", bottom="K") myspots = [] i = self.spinBoxK.value() while i < self.spinBoxElements.value(): self.labeltestdata3 = classifyKNN( self.traindata3, self.testData3, i, self.numberofclasses, self.checkBoxSuspended.isChecked(), metrick) myspots.append([ i, sum([ int(self.labeltestdata3[i] == self.trueTestDataLabels3[i] [1]) for i in range(len(self.trueTestDataLabels3)) ]) / float(len(self.trueTestDataLabels3)) ]) i += self.spinBoxK.singleStep() self.w3.plot(x=[x[0] for x in myspots], y=[y[1] for y in myspots], pen=(0, 255, 0), symbolBrush=(0, 0, 255), symbol='o', name="Три признака") self.w3.setLabels(title='Сравнение точности в зависимости от признака', left="Точность", bottom="K") myspots = [] i = self.spinBoxK.value() while i < self.spinBoxElements.value(): self.labeltestdata = classifyKNN( self.traindata, self.testData, i, self.numberofclasses, self.checkBoxSuspended.isChecked(), metrick) myspots.append([ i, sum([ int(self.labeltestdata[i] == self.trueTestDataLabels[i][1]) for i in range(len(self.trueTestDataLabels)) ]) / float(len(self.trueTestDataLabels)) ]) i += self.spinBoxK.singleStep() self.w3.plot(x=[x[0] for x in myspots], y=[y[1] for y in myspots], pen=(255, 0, 0), symbolBrush=(255, 0, 0), symbolPen='w', name="Два признака") self.w3.setLabels(title='Сравнение точности в зависимости от признака', left="Точность", bottom="K")