class PlotWidget(QtWidgets.QWidget): def __init__(self, parent=None): QtWidgets.QWidget.__init__(self, parent) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas, self) self.button = QtWidgets.QPushButton("Plot") self.button.clicked.connect(self.plot) layout = QtWidgets.QVBoxLayout() layout.addWidget(self.toolbar) layout.addWidget(self.canvas) layout.addWidget(self.button) self.setLayout(layout) def plot(self): data = [x for x in range(10)] ax = self.figure.add_subplot(111) ax.hold(False) ax.plot(data, "*-") self.canvas.draw()
class ColorbarWidget(QWidget): def __init__(self, parent=None): super(ColorbarWidget, self).__init__(parent) fig = Figure() rect = 0.25, 0.05, 0.1, 0.90 self.cb_axes = fig.add_axes(rect) self.canvas = FigureCanvas(fig) self.setLayout(QVBoxLayout()) self.layout().addWidget(self.canvas) self.button = QPushButton("Update") self.layout().addWidget(self.button) self.button.pressed.connect(self._update_cb_scale) self._create_colorbar(fig) def _create_colorbar(self, fig): self.mappable = ScalarMappable(norm=SymLogNorm(0.0001, 1,vmin=-10., vmax=10000.), cmap=DEFAULT_CMAP) self.mappable.set_array([]) fig.colorbar(self.mappable, ax=self.cb_axes, cax=self.cb_axes) def _update_cb_scale(self): self.mappable.colorbar.remove() rect = 0.25, 0.05, 0.1, 0.90 self.cb_axes = self.canvas.figure.add_axes(rect) self.mappable = ScalarMappable(Normalize(30, 4300), cmap=DEFAULT_CMAP) self.mappable.set_array([]) self.canvas.figure.colorbar(self.mappable, ax=self.cb_axes, cax=self.cb_axes) self.canvas.draw()
class Statistics(): def __init__(self, stat_label, parent, width=3, height=4, dpi=100): self.fig = Figure(figsize=(width, height), dpi=dpi) self.axes = self.fig.add_subplot(111) self.axes.hold(False) self.canvas = FigureCanvasQTAgg(self.fig) parent.addWidget(self.canvas, 1, 0, 1, 1) self.canvas.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding) self.canvas.updateGeometry() self.stat_label = stat_label; self.reset() def refresh(self, stats): # stats.print() _translate = QtCore.QCoreApplication.translate self.stat_label.setText(_translate("MainWindow", stats.print())) # counters foodCnt = stats.foodCnt() self.foods.append(foodCnt.existing) self.stepNumbers.append(stats.stepNumber()) # plot self.axes.plot(self.stepNumbers, self.foods) self.axes.set_xlabel("Step number") self.axes.set_ylabel("Food count") self.canvas.draw() def reset(self): self.foods = [] self.stepNumbers = []
class Window(QDialog): # https://stackoverflow.com/questions/12459811/how-to-embed-matplotlib-in-pyqt-for-dummies def __init__(self, parent=None): super(Window, self).__init__(parent) # a figure instance to plot on self.figure = plt.figure() # this is the Canvas Widget that displays the `figure` # it takes the `figure` instance as a parameter to __init__ self.canvas = FigureCanvas(self.figure) # this is the Navigation widget # it takes the Canvas widget and a parent self.toolbar = NavigationToolbar(self.canvas, self) # Just some button connected to `plot` method self.button = QPushButton('Plot') self.button.clicked.connect(self.plot) # set the layout layout = QVBoxLayout() layout.addWidget(self.toolbar) layout.addWidget(self.canvas) layout.addWidget(self.button) self.setLayout(layout) def plot(self): ''' plot some random stuff ''' # random data data = [random.random() for i in range(10)] # instead of ax.hold(False) self.figure.clear() # create an axis ax = self.figure.add_subplot(111) # discards the old graph # ax.hold(False) # deprecated, see above # plot data ax.plot(data, '*-') # refresh canvas self.canvas.draw() def keyPressEvent(self, event): # http://zetcode.com/gui/pyqt5/eventssignals/ if event.key() == QtCore.Qt.Key_Escape: self.close() if event.key() == QtCore.Qt.Key_Space: global gridLayout item = gridLayout.itemAtPosition(1,1) w = item.widget() w.setText("test")
class RadarUI(QtWidgets.QWidget): # class RadarUI(QtWidgets.QMainWindow): def __init__(self): super(RadarUI, self).__init__() self.__controller = None self.__init_ui() def __init_ui(self): remove_clutter = QtWidgets.QPushButton('Remove Clutter', self) restore_clutter = QtWidgets.QPushButton('Restore Clutter', self) remove_clutter.clicked.connect(self.remove_clutter) restore_clutter.clicked.connect(self.restore_clutter) buttons_layout = QtWidgets.QHBoxLayout() buttons_layout.addWidget(remove_clutter) buttons_layout.addWidget(restore_clutter) figure = Figure() self.__controller = controller.Controller(figure) self.__controller.update.connect(self.__update_label) ax = figure.add_subplot(212) self.__line, = ax.plot(range(10)) self.__canvas = FigureCanvasQTAgg(figure) self.__canvas.show() self.__name_label = QtWidgets.QLabel("asdf") # main layout main_layout = QtWidgets.QVBoxLayout() main_layout.addStretch(1) main_layout.addWidget(self.__canvas) main_layout.addWidget(self.__name_label) main_layout.addLayout(buttons_layout) self.setLayout(main_layout) self.show() def remove_clutter(self): # todo x, y = self.__line.get_data() self.__line.set_ydata(y - 0.2 * x) self.__canvas.draw() def restore_clutter(self): # todo x, y = self.__line.get_data() self.__line.set_ydata(y + 0.2 * x) self.__canvas.draw() def run(self): self.__controller.run2() @QtCore.pyqtSlot(np.ndarray) def __update_label(self, value): self.__name_label.setText(str(value))
class MainWindow(QMainWindow, Ui_MainWindow): def __init__(self): super(MainWindow, self).__init__() self.setupUi(self) self.setWindowTitle('Fit Window') self._create_mplplot() self._peak_picker = self._create_peak_picker(self._canvas) self._onpick = self._canvas.mpl_connect('pick_event', self._on_pick) def _create_mplplot(self): x = np.arange(1,101, 0.01) mu, sigma = 50, 5 y = np.exp( - (x - mu)**2 / (2 * sigma**2)) fig = Figure() axes = fig.add_subplot(111) axes.plot(x, y, color='black') axes.set_title('Text', y=1.02) self._canvas = FigureCanvas(fig) print(dir(FigureCanvas)) self._filter = MouseClickMonitor(self._canvas) self._canvas.installEventFilter(self._filter) self.mpllayout.addWidget(self._canvas) self._canvas.draw() return fig def _create_peak_picker(self, canvas): picker = PeakPickerTool(canvas) self.on_region_update(picker.lines[0].get_xdata()[0], picker.lines[1].get_xdata()[0]) picker.region_updated.connect(self.on_region_update) return picker def _on_pick(self, evt): if not evt.mouseevent.dblclick: return print(dir(evt.artist.get_text())) # print("Title double clicked at matplotlib coords",evt.mouseevent.x, evt.mouseevent.y) # print("Canvas width=",self._canvas.width(), "height=", self._canvas.height()) # editor = QLineEdit(self._canvas) # editor.setAttribute(Qt.WA_DeleteOnClose) # editor.setText(self._canvas.figure.get_axes()[0].get_title()) # self._canvas.figure.get_axes()[0].set_title('') # self._canvas.draw() # editor.move(evt.mouseevent.x - (0.5*editor.width()), self._canvas.height() - evt.mouseevent.y - 0.5*editor.height()) # editor.show() # self._editor = editor def on_region_update(self, leftx, rightx): self.table_widget.setItem(0, 1, QTableWidgetItem(str(leftx))) self.table_widget.setItem(1, 1, QTableWidgetItem(str(rightx)))
def test_resize_qt(): # This test just ensures that the code runs, but doesn't check for now # that the behavior is correct. pytest.importorskip('PyQt5') from PyQt5.QtWidgets import QMainWindow from matplotlib.figure import Figure from matplotlib.backends.backend_qt5 import FigureManagerQT from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg fig = Figure() canvas = FigureCanvasQTAgg(fig) canvas.manager = FigureManagerQT(canvas, 0) # noqa ax = fig.add_subplot(1, 1, 1) canvas.draw = Mock(side_effect=canvas.draw) from matplotlib.backends.backend_qt5 import qApp window = QMainWindow() window.setCentralWidget(canvas) window.show() x1 = np.random.normal(0, 1, 10000000) y1 = np.random.normal(0, 1, 10000000) a = ScatterDensityArtist(ax, x1, y1) ax.add_artist(a) canvas.draw() assert not a.stale assert canvas.draw.call_count == 1 window.resize(300, 300) # We can't actually check that stale is set to True since it only remains # so for a short amount of time, but we can check that draw is called twice # (once at the original resolution then once with the updated resolution). start = time.time() while time.time() - start < 1: qApp.processEvents() assert canvas.draw.call_count == 3 assert not a.stale start = time.time() while time.time() - start < 1: qApp.processEvents() a.remove() qApp.processEvents()
class PlotFigure(object): signals = [] canvas = None def __init__(self, parent=None): self.fig = Figure(figsize=(600, 600), dpi=72, facecolor=(1, 1, 1), edgecolor=(0, 0, 0)) self.canvas = FigureCanvas(self.fig) def addSeries(self, series): self.rmSeries(series) # Add a new series if self.signals: if((self.signals[0].xunits == series.xunits) and (self.signals[0].yunits == series.yunits)): self.signals.append(series) else: self.signals = [series] else: self.signals = [series] def rmSeries(self, series): if self.signals: try: self.signals.remove(series) except: pass def clearSeries(self): self.signals = [] def draw(self): self.ax = self.fig.add_subplot(1, 1, 1) self.ax.cla() for s in self.signals: self.ax.plot(s.xvalues, s.data, label=s.label) if len(self.signals): self.ax.set_xlabel(self.signals[0].xunits) self.ax.set_ylabel(self.signals[0].yunits) handles, labels = self.ax.get_legend_handles_labels() self.ax.legend(handles[::-1], labels[::-1]) self.ax.legend(handles, labels) try: self.plotExtras() except: pass self.canvas.draw() def getWidget(self): return self.canvas
class MainWindow(QWidget): updGUI=pyqtSignal() def __init__(self, pose3d, parent=None): super(MainWindow, self).__init__(parent) layout = QGridLayout() self.seconds = 0 self.MAXseconds = 900 self.contSeconds = 0 self.secondsArray = [0] self.devPercentajes = [0] self.percentaje = porcentajeWidget(self, pose3d) self.percentajePrev = 0 self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) layout.addWidget(self.canvas) vSpacer = QSpacerItem(30, 50, QSizePolicy.Ignored, QSizePolicy.Ignored) layout.addItem(vSpacer,1,0) self.setFixedSize(1200,500); self.setLayout(layout) timer = QTimer(self) timer.start(1000) timer.timeout.connect(self.contadorTime) def contadorTime(self): if self.seconds < self.MAXseconds: self.percentaje.updateG() self.seconds += 1 if self.seconds % 2 == 0: self.contSeconds += 1 dif = float(float(self.percentaje.porcentajeCasa) - float(self.percentajePrev)) self.devPercentajes.append(dif) self.secondsArray.append(self.contSeconds) self.percentajePrev = self.percentaje.porcentajeCasa ax = self.figure.add_subplot(111) ax.set_xlabel('Time') ax.set_ylabel('Percentage Derivative') ax.set_xlim([0, 450]); ax.set_ylim([0, 0.7]); ax.plot(self.secondsArray, self.devPercentajes,'r') self.canvas.draw()
class MyWindow(QWidget): def __init__(self): super().__init__() self.setupUI() def setupUI(self): self.setGeometry(600, 200, 1200, 600) self.setWindowTitle("PyChart Viewer v0.1") self.setWindowIcon(QIcon('icon.png')) self.lineEdit = QLineEdit() self.pushButton = QPushButton("차트그리기") self.pushButton.clicked.connect(self.pushButtonClicked) self.fig = plt.Figure() self.canvas = FigureCanvas(self.fig) leftLayout = QVBoxLayout() leftLayout.addWidget(self.canvas) # Right Layout rightLayout = QVBoxLayout() rightLayout.addWidget(self.lineEdit) rightLayout.addWidget(self.pushButton) rightLayout.addStretch(1) layout = QHBoxLayout() layout.addLayout(leftLayout) layout.addLayout(rightLayout) layout.setStretchFactor(leftLayout, 1) layout.setStretchFactor(rightLayout, 0) self.setLayout(layout) def pushButtonClicked(self): code = self.lineEdit.text() df = web.DataReader(code, "yahoo") df['MA20'] = df['Adj Close'].rolling(window=20).mean() df['MA60'] = df['Adj Close'].rolling(window=60).mean() ax = self.fig.add_subplot(111) ax.plot(df.index, df['Adj Close'], label='Adj Close') ax.plot(df.index, df['MA20'], label='MA20') ax.plot(df.index, df['MA60'], label='MA60') ax.legend(loc='upper right') ax.grid() self.canvas.draw()
class PlotWidget(QtWidgets.QFrame): SStats = pyqtSignal(np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray) def __init__(self, parent=None): super(PlotWidget, self).__init__(parent) self.initUI() def initUI(self): self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas, self) layout = QtWidgets.QVBoxLayout() layout.addWidget(self.toolbar) layout.addWidget(self.canvas) self.setLayout(layout) def plot_sounding_axes(self): self.figure.clear() ax = self.figure.add_axes([0.05, 0.05, 0.90, 0.945]) # ax = self.figure.add_axes([0.005,0.05,0.985,0.945]) ax.hold(True) skewt.set_fontscalefactor(4) skewt.plot_sounding_axes(ax) self.canvas.draw() def plot_hodograph_axes(self): ax = self.figure.add_axes([0.005, 0.005, 0.985, 0.985]) ax.hold(True) skewt.plot_hodo_axes(ax) self.canvas.draw() def plot_sounding(self, z, th, p, qv, u, v): self.figure.clear() # ax = self.figure.add_axes([0.005,0.05,0.985,0.945]) ax = self.figure.add_axes([0.05, 0.05, 0.90, 0.945]) ax.hold(True) skewt.plot_sounding_axes(ax) skewt.plot_sounding(ax, z, th, p, qv, u, v) self.canvas.draw() # Send data to stats widget self.SStats.emit(z, th, p, qv, u, v) def plot_hodograph(self, z, u, v): self.figure.clear() ax = self.figure.add_axes([0.005, 0.05, 0.985, 0.945]) ax.hold(True) skewt.plot_hodo_axes(ax) skewt.plot_hodograph(ax, z, u, v) self.canvas.draw()
class Window(QtWidgets.QDialog): def __init__(self, parent=None): super(Window, self).__init__(parent) # a figure instance to plot on self.figure = plt.figure() # this is the Canvas Widget that displays the `figure` # it takes the `figure` instance as a parameter to __init__ self.canvas = FigureCanvas(self.figure) # this is the Navigation widget # it takes the Canvas widget and a parent self.toolbar = NavigationToolbar(self.canvas, self) # Just some button connected to `plot` method self.button = QtWidgets.QPushButton('Plot') self.button.clicked.connect(self.plot) # set the layout layout = QtWidgets.QVBoxLayout() layout.addWidget(self.toolbar) layout.addWidget(self.canvas) layout.addWidget(self.button) self.setLayout(layout) def plot(self): ''' plot some random stuff ''' # random data data = [random.random() for i in range(10)] # create an axis ax = self.figure.add_subplot(111) # discards the old graph ax.hold(False) # plot data ax.plot(data, '*-') # refresh canvas self.canvas.draw()
def detach_plot(self): new_window = QtWidgets.QMainWindow(self) new_window.setWindowTitle('Graphique détaché') frame = QtWidgets.QFrame(new_window) canvas = FigureCanvas(self.figure) canvas.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) canvas.updateGeometry() canvas.draw() toolbar = NavigationToolbar(canvas, frame) layout = QtWidgets.QVBoxLayout(frame) layout.addWidget(canvas, 1) layout.addWidget(toolbar, 0) new_window.setCentralWidget(frame) new_window.show() return new_window
class SensorWidget(): # ToDo: Add signal to this object and emit value each time new value # is taken from queue def __init__(self, parent=None): self.figure, self.axes = plt.subplots() self.x_axis = [] self.y_values = [] self.sensor_plot_queue = Queue(maxsize=N_POINTS_ON_PLOT) self.compute_initial_figure() self.canvas = FigureCanvas(self.figure) self.canvas.setParent(parent) self.timer = QtCore.QTimer() self.timer.timeout.connect(self.update_figure) self.timer.start(50) def compute_initial_figure(self): self.axes.plot(self.y_values) def feed_value(self, value): self.sensor_plot_queue.put(value) def update_figure(self): self.axes.cla() # ToDo: Need to add lock here and iterate through all elements if not self.sensor_plot_queue.empty(): self.y_values.append(self.sensor_plot_queue.get()) if len(self.y_values) > N_POINTS_ON_PLOT: self.y_values.pop(0) self.x_axis = [x + 1 for x in self.x_axis] else: self.axes.set_xlim(0, N_POINTS_ON_PLOT) while len(self.x_axis) < len(self.y_values): self.x_axis.append(len(self.y_values)) self.axes.plot(self.x_axis, self.y_values, ".") self.axes.plot(self.x_axis, self.y_values, "-") logging.debug("Drawing new plot") self.canvas.draw()
class fcHistogram(QDialog, Ui_histwin): def __init__(self, parent=None): super(fcHistogram, self).__init__(parent) self.setupUi(self) fig1 = Figure() self.canvas = FigureCanvas(fig1) self.histogram.addWidget(self.canvas) self.plot = fig1.add_subplot(111) self.plot.set_ylim([0, 5000]) self.plot.set_xlim([0, 256]) self.canvas.draw() def setupThreadingUpdates(self, imgthread): #set up connections to UI update from imgthread imgthread.displayWashoutsSig.connect(self.displayWashouts) imgthread.plotHistogramSig.connect(self.plotHistogram) def displayWashouts(self, over, px, avg): #in hindsight, is this really useful? logging.debug("DisplayWashouts Called") logging.debug(over[1]) logging.debug(avg) logging.debug(px) self.pctOverB.setText(adj_for_size(over[0], px)) self.pctOverG.setText(adj_for_size(over[1], px)) self.pctOverR.setText(adj_for_size(over[2], px)) self.pctUnder.setText(adj_for_size(over[3], px)) self.pctAvg.setText(str(avg)) def plotHistogram(self, colorhists, grayhist, px): global colors logging.debug("plotHistogram Called") self.plot.cla() self.plot.fill(grayhist, color="gray") for i,col in enumerate(colors): self.plot.plot(colorhists[i],color = col) self.plot.set_ylim([0,px/128]) self.plot.set_xlim([0,256]) self.canvas.draw()
class WidgetGallery(QDialog): def __init__(self, parent=None): super(WidgetGallery, self).__init__(parent) self.originalPalette = QApplication.palette() styleComboBox = QComboBox() styleComboBox.addItems(QStyleFactory.keys()) styleLabel = QLabel("&Style:") styleLabel.setBuddy(styleComboBox) self.useStylePaletteCheckBox = QCheckBox( "&Use style's standard palette") self.useStylePaletteCheckBox.setChecked(True) disableWidgetsCheckBox = QCheckBox("&Disable widgets") self.createButtons() self.createButtons2() self.createPlotCanvas() self.createSpreadsheet() mainLayout = QGridLayout() mainLayout.addWidget(self.buttonGroup, 0, 0) mainLayout.addWidget(self.buttonGroup2, 0, 1) mainLayout.addWidget(self.leftGroup, 1, 1) mainLayout.addWidget(self.rightGroup, 1, 0) self.setLayout(mainLayout) self.setWindowTitle("jikuGUI") def createButtons(self): self.buttonGroup = QGroupBox("") #self.buttonGroup.setFlat(True); #self.buttonGroup.setStyleSheet("border:0;") self.buttonGroup.setGeometry(0, 0, 100, 40) layout = QHBoxLayout() self.pushButtonLoad = QtWidgets.QPushButton(self) self.pushButtonLoad.setText("Load Data") self.pushButtonLoad.clicked.connect(self.on_pushButtonLoad_clicked) layout.addWidget(self.pushButtonLoad) self.pushButtonWrite = QtWidgets.QPushButton(self) self.pushButtonWrite.setText("Save Data") self.pushButtonWrite.clicked.connect(self.on_pushButtonWrite_clicked) layout.addWidget(self.pushButtonWrite) self.pushButtonWriteAnalysis = QtWidgets.QPushButton(self) self.pushButtonWriteAnalysis.setText("Save Analysis") #self.pushButtonWrite.clicked.connect(self.on_pushButtonWrite_clicked) layout.addWidget(self.pushButtonWriteAnalysis) self.buttonGroup.setLayout(layout) def createButtons2(self): self.buttonGroup2 = QGroupBox("") #self.buttonGroup.setFlat(True); #self.buttonGroup.setStyleSheet("border:0;") self.buttonGroup2.setGeometry(0, 0, 100, 40) layout = QHBoxLayout() self.pushButtonPlot = QtWidgets.QPushButton(self) self.pushButtonPlot.setText("Plot") self.pushButtonPlot.clicked.connect(self.on_pushButtonPlot_clicked) self.pushButtonAnalysis = QtWidgets.QPushButton(self) self.pushButtonAnalysis.setText("Analyze") self.pushButtonAnalysis.clicked.connect( self.on_pushButtonAnalysis_clicked) layout.addWidget(self.pushButtonPlot) layout.addWidget(self.pushButtonAnalysis) self.buttonGroup2.setLayout(layout) def createSpreadsheet(self): self.rightGroup = QGroupBox("Data") self.tabs = QTabWidget() self.tableWidget = QTableWidget(10, 10) layout = QVBoxLayout() layout.addWidget(self.tableWidget) self.rightGroup.setLayout(layout) def createPlotCanvas(self): self.leftGroup = QGroupBox("Statistics") self.tabs = QTabWidget() #tab1- matplotlib self.tab1 = QWidget() self.tab1.layout = QVBoxLayout(self) #tab2- matplotlib self.tab2 = QWidget() self.tab2.layout = QVBoxLayout(self) #tab3- matplotlib self.tab3 = QWidget() self.tab3.layout = QVBoxLayout(self) #tab3- matplotlib self.tab4 = QWidget() self.tab4.layout = QVBoxLayout(self) self.tabs.addTab(self.tab1, "Plot") self.tabs.addTab(self.tab2, "Analysis") self.tabs.addTab(self.tab3, "Advanced") self.tabs.addTab(self.tab4, "Wizard") layout = QVBoxLayout() # a figure instance to plot on self.figure1 = plt.figure() self.ax1 = self.figure1.add_axes([0.1, 0.1, 0.8, 0.8]) self.canvas1 = FigureCanvas(self.figure1) self.figure2 = plt.figure() self.ax2 = self.figure2.add_axes([0.1, 0.1, 0.8, 0.8]) self.canvas2 = FigureCanvas(self.figure2) self.dialog = QLineEdit(self) self.pushButtonRun = QtWidgets.QPushButton(self) self.pushButtonRun.setText("run") self.pushButtonRun.clicked.connect(self.on_pushButtonRun_clicked) self.tab1.layout.addWidget(self.canvas1) self.tab2.layout.addWidget(self.canvas2) self.tab3.layout.addWidget(self.dialog) self.tab3.layout.addWidget(self.pushButtonRun) self.tab1.setLayout(self.tab1.layout) self.tab2.setLayout(self.tab2.layout) self.tab3.setLayout(self.tab3.layout) layout.addWidget(self.tabs) self.leftGroup.setLayout(layout) def showDialog(self): text, ok = QInputDialog.getText(self, 'Input Dialog', 'Enter text:') if ok: self.le.setText(str(text)) def plot(self): try: ids = list( set(index.row() for index in self.tableWidget.selectedIndexes())) print(ids) print(self.model[ids, :].transpose()) self.ax1.clear() self.ax1.plot(self.model[ids, :].transpose()) self.canvas1.draw() except: self.ax1.clear() def parser(self): print("OK") def analysis(self): try: ids = list( set(index.row() for index in self.tableWidget.selectedIndexes())) print(ids) print(self.model[ids, :].transpose()) t = spm1d.stats.ttest(self.model[ids, :]) ti = t.inference(alpha=0.05, two_tailed=False, interp=True) self.ax2.clear() self.ax2.plot() ti.plot() self.canvas2.draw() except: self.ax2.clear() def loadCsv(self): fileName = QFileDialog.getOpenFileName(self, 'Open file', './', "spreadsheets (*.xlsx *.csv)") print(fileName) df = pd.read_csv(fileName[0], sep=',', header=None) self.model = df.values print(self.model) print(self.model.shape) nrows = self.model.shape[0] ncols = self.model.shape[1] if (self.tableWidget.rowCount() != nrows): self.tableWidget.setRowCount(nrows) if (self.tableWidget.columnCount() != nrows): self.tableWidget.setColumnCount(ncols) for m in range(nrows): for n in range(ncols): newitem = QtWidgets.QTableWidgetItem(str(self.model[m, n])) self.tableWidget.setItem(m, n, newitem) def writeCsv(self): fileName = QFileDialog.getOpenFileName(self, 'save file', 'c:\\', "Image files (*.xlsx *.csv)") with open(fileName[0], "w") as fileOutput: writer = csv.writer(fileOutput) for rowNumber in range(self.model.rowCount()): fields = [ self.model.data(self.model.index(rowNumber, columnNumber), QtCore.Qt.DisplayRole) for columnNumber in range(self.model.columnCount()) ] writer.writerow(fields) @QtCore.pyqtSlot() def on_pushButtonWrite_clicked(self): self.writeCsv() @QtCore.pyqtSlot() def on_pushButtonLoad_clicked(self): self.loadCsv() @QtCore.pyqtSlot() def on_pushButtonPlot_clicked(self): self.plot() @QtCore.pyqtSlot() def on_pushButtonAnalysis_clicked(self): self.analysis() @QtCore.pyqtSlot() def on_pushButtonRun_clicked(self): self.Parser()
class MPLCanvas(QtWidgets.QGroupBox): """Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.).""" @enum.unique class WindowTypes(enum.Enum): Rectangular = 0 Hann = 1 Flattop = 2 Tukey_5Percent = 3 windowFunctionMap = { WindowTypes.Rectangular: lambda M: windows.boxcar(M, sym=False), WindowTypes.Hann: lambda M: windows.hann(M, sym=False), WindowTypes.Flattop: lambda M: windows.flattop(M, sym=False), WindowTypes.Tukey_5Percent: lambda M: windows.tukey(M, sym=False, alpha=0.05), } dataIsPower = False dataSet = None prevDataSet = None _prevAxesLabels = None _axesLabels = None _prevDataLabel = None _dataLabel = None _lastPlotTime = 0 _isLiveData = False def __init__(self, parent=None): style_mpl() super().__init__(parent) dpi = QtWidgets.qApp.primaryScreen().logicalDotsPerInch() self.fig = Figure(dpi=dpi) self.fig.patch.set_alpha(0) self.axes = self.fig.add_subplot(2, 1, 1) self.ft_axes = self.fig.add_subplot(2, 1, 2) self.canvas = FigureCanvasQTAgg(self.fig) self.mpl_toolbar = NavigationToolbar2QT(self.canvas, self) self.mpl_toolbar.addSeparator() self.autoscaleAction = self.mpl_toolbar.addAction("Auto-scale") self.autoscaleAction.setCheckable(True) self.autoscaleAction.setChecked(True) self.autoscaleAction.triggered.connect(self._autoscale) self.mpl_toolbar.addWidget( QtWidgets.QLabel("Fourier transform " "window: ")) self.windowComboBox = QtWidgets.QComboBox(self.mpl_toolbar) for e in MPLCanvas.WindowTypes: self.windowComboBox.addItem(e.name, e) self.mpl_toolbar.addWidget(self.windowComboBox) self.windowComboBox.currentIndexChanged.connect(self._replot) vbox = QtWidgets.QVBoxLayout(self) vbox.addWidget(self.mpl_toolbar) vbox.addWidget(self.canvas) vbox.setContentsMargins(0, 0, 0, 0) vbox.setStretch(0, 1) vbox.setStretch(1, 1) self.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) self.canvas.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) self.updateGeometry() self.fig.tight_layout() self._lines = self.axes.plot([], [], [], [], animated=True) self._lines[0].set_alpha(0.25) self._ftlines = self.ft_axes.plot([], [], [], [], animated=True) self._ftlines[0].set_alpha(0.25) self.axes.legend(['Previous', 'Current']) self.ft_axes.legend(['Previous', 'Current']) self.axes.set_title('Data') self.ft_axes.set_title('Fourier transformed data') self._redraw() # Use a timer with a timeout of 0 to initiate redrawing of the canvas. # This ensures that the eventloop has run once more and prevents # artifacts. self._redrawTimer = QtCore.QTimer(self) self._redrawTimer.setSingleShot(True) self._redrawTimer.setInterval(100) self._redrawTimer.timeout.connect(self._redraw) # will be disconnected in drawDataSet() when live data is detected. self._redraw_id = self.canvas.mpl_connect('draw_event', self._redraw_artists) def _redraw_artists(self, *args): if not self._isLiveData: self.axes.draw_artist(self._lines[0]) self.ft_axes.draw_artist(self._ftlines[0]) self.axes.draw_artist(self._lines[1]) self.ft_axes.draw_artist(self._ftlines[1]) def _redraw(self): self.fig.tight_layout() self.canvas.draw() self.backgrounds = [ self.fig.canvas.copy_from_bbox(ax.bbox) for ax in (self.axes, self.ft_axes) ] self._redraw_artists() def showEvent(self, e): super().showEvent(e) self._redrawTimer.start() def resizeEvent(self, e): super().resizeEvent(e) self._redrawTimer.start() def get_ft_data(self, data): delta = np.mean(np.diff(data.axes[0])) winFn = self.windowFunctionMap[self.windowComboBox.currentData()] refUnit = 1 * data.data.units Y = np.fft.rfft(np.array(data.data / refUnit) * winFn(len(data.data)), axis=0) freqs = np.fft.rfftfreq(len(data.axes[0]), delta) dBdata = 10 * np.log10(np.abs(Y)) if not self.dataIsPower: dBdata *= 2 data_slice = np.array(freqs) < 2.1 return (freqs[data_slice], dBdata[data_slice]) def _dataSetToLines(self, data, line, ftline): if data is None: line.set_data([], []) ftline.set_data([], []) return #data.data -= np.mean(data.data) line.set_data(data.axes[0], data.data) freqs, dBdata = self.get_ft_data(data) ftline.set_data(freqs, dBdata) def _autoscale(self, *, redraw=True): prev_xlim = self.axes.get_xlim() prev_ylim = self.axes.get_ylim() prev_ft_xlim = self.ft_axes.get_xlim() prev_ft_ylim = self.ft_axes.get_ylim() self.axes.relim() self.axes.autoscale() self.ft_axes.relim() self.ft_axes.autoscale() need_redraw = (prev_xlim != self.axes.get_xlim() or prev_ylim != self.axes.get_ylim() or prev_ft_xlim != self.ft_axes.get_xlim() or prev_ft_ylim != self.ft_axes.get_ylim()) if need_redraw and redraw: self._redraw() return need_redraw def _replot(self, redraw_axes=False, redraw_axes_labels=False, redraw_data_label=False): if not self._isLiveData: self._dataSetToLines(self.prevDataSet, self._lines[0], self._ftlines[0]) self._dataSetToLines(self.dataSet, self._lines[1], self._ftlines[1]) if self._axesLabels and redraw_axes_labels: self.axes.set_xlabel('{} [{:C~}]'.format( self._axesLabels[0], self.dataSet.axes[0].units)) self.ft_axes.set_xlabel('1 / {} [1 / {:C~}]'.format( self._axesLabels[0], self.dataSet.axes[0].units)) if self._dataLabel and redraw_data_label: self.axes.set_ylabel('{} [{:C~}]'.format(self._dataLabel, self.dataSet.data.units)) ftUnits = self.dataSet.data.units if not self.dataIsPower: ftUnits = ftUnits**2 self.ft_axes.set_ylabel('Power [dB-({:C~})]'.format(ftUnits)) axis_limits_changed = False if (self.autoscaleAction.isChecked()): axis_limits_changed = self._autoscale(redraw=False) # check whether a full redraw is necessary or if simply redrawing # the data lines is enough if (redraw_axes or redraw_axes_labels or redraw_data_label or axis_limits_changed): self._redraw() else: for bg in self.backgrounds: self.canvas.restore_region(bg) self._redraw_artists() self.canvas.blit(self.axes.bbox) self.canvas.blit(self.ft_axes.bbox) def drawDataSet(self, newDataSet, axes_labels, data_label): plotTime = time.perf_counter() looksLikeLiveData = plotTime - self._lastPlotTime < 1 if looksLikeLiveData != self._isLiveData: if looksLikeLiveData: self.canvas.mpl_disconnect(self._redraw_id) else: self._redraw_id = self.canvas.mpl_connect( 'draw_event', self._redraw_artists) self._isLiveData = looksLikeLiveData # artificially limit the replot rate to 5 Hz if (plotTime - self._lastPlotTime < 0.2): return self._lastPlotTime = plotTime self.prevDataSet = self.dataSet self.dataSet = newDataSet redraw_axes = (self.prevDataSet is None or len(self.prevDataSet.axes) != len(self.dataSet.axes)) if not redraw_axes: for x, y in zip(self.prevDataSet.axes, self.dataSet.axes): if x.units != y.units: redraw_axes = True break redraw_axes_labels = ( self._axesLabels != axes_labels or self.prevDataSet and self.dataSet and self.prevDataSet.axes[0].units != self.dataSet.axes[0].units) redraw_data_label = ( self._dataLabel != data_label or self.prevDataSet and self.dataSet and self.prevDataSet.data.units != self.dataSet.data.units) self._axesLabels = axes_labels self._dataLabel = data_label self._replot(redraw_axes, redraw_axes_labels, redraw_data_label)
class Window(QDialog): def __init__(self, parent=None): super(Window, self).__init__(parent) with open('./features_extracted.json', 'r') as file: self.loaded_json_data = json.load(file) self.figures = [] self.canvases = [] self.toolbars = [] self.brainStateLabels = [] self.accuracyLabels = [] self.axes = [] self.tabs = [] self.tabs = QTabWidget() # a figure instance to plot on self.figure = plt.figure() # this is the Canvas Widget that displays the plot or (figure) self.canvas = FigureCanvas(self.figure) self.openFileDialog() # this is the Navigation Toolbar for the top of the plot self.toolbar = NavigationToolbar(self.canvas, self) # create the layout and menu layout = QVBoxLayout() menu_bar = QMenuBar() fileMenu = menu_bar.addMenu('File') importDataAction = QAction('Import Data', self) importDataAction.setShortcut('Ctrl+I') importDataAction.triggered.connect(self.openFileDialog) fileMenu.addAction(importDataAction) layout.setMenuBar(menu_bar) layout.addWidget(self.toolbar) layout.addWidget(self.canvas) outputHBox = QHBoxLayout() # create the labels that we will need to access again self.brainStateLabel = QLabel("Brain State : ") self.brainStateLabel.setFixedSize(200, 20) self.accuracyLabel = QLabel("Accuracy of Prediction: ") self.accuracyLabel.setFixedSize(400, 20) predictionStatisticsVBoxLeft = QVBoxLayout() predictionStatisticsVBoxLeft.addWidget(self.brainStateLabel) predictionStatisticsVBoxRight = QVBoxLayout() predictionStatisticsVBoxRight.addWidget(self.accuracyLabel) outputHBox.addLayout(predictionStatisticsVBoxLeft) outputHBox.addLayout(predictionStatisticsVBoxRight) layout.addLayout(outputHBox) self.setLayout(layout) # mouse button press event press_event_id = self.canvas.mpl_connect('button_press_event', self.onclick) # motion_event_id = self.canvas.mpl_connect('motion_notify_event', self.on_move) self.plot() self.model = fNIRLib.load_model() def openFileDialog(self): options = QFileDialog.Options() # options |= QFileDialog.DontUseNativeDialog file_path, _ = QFileDialog.getOpenFileName( self, "QFileDialog.getOpenFileName()", "", "All Files (*);;Python Files (*.py)", options=options) if file_path: print(file_path) data = fNIRLib.importSingleton(file_path) data_frames = [] for df in data: data_frames.append(df) all_features = pd.concat(data_frames) self.features = all_features.drop(all_features.columns[[16]], axis=1) self.plot() def onclick(self, event, i): print('%s click: button=%d, x=%d, y=%d, xdata=%f, ydata=%f' % ('double' if event.dblclick else 'single', event.button, event.x, event.y, event.xdata, event.ydata)) if event.button == 1: self.figure.tight_layout() self.ax.patches.clear() if event.button == 3: self.draw_rectangle(event.xdata, i) x_point = int(round(event.xdata)) ml_data = self.features.iloc[0:x_point] ml_data['column_id'] = ml_data.shape[0] * [0] ml_data['time_id'] = range(ml_data.shape[0]) print(ml_data) features_extracted = feature_extraction.extract_features( ml_data, kind_to_fc_parameters=self.loaded_json_data, column_id="column_id", column_sort="time_id") print(features_extracted) predicted_class = self.model.predict_classes( features_extracted.values)[0][0] if predicted_class == 0: self.brainStateLabel.setText("Brain State: Low") else: self.brainStateLabel.setText("Brain State: High") self.accuracyLabel.setText("Prediction Accuracy: 75%") QApplication.processEvents() self.canvas.draw() # def on_move(self, event): # # get the x and y pixel coords # x, y = event.x, event.y # # if event.inaxes: # ax = event.inaxes # the axes instance # print('data coords %f %f' % (event.xdata, event.ydata)) # self.figure.tight_layout() def draw_rectangle(self, x, i): self.ax.patches.clear() rectangle = Rectangle((0, -10), width=x, height=100, color='#0F0F0F2F') self.ax.add_patch(rectangle) self.canvas.draw() def plot(self): self.figure.clear() # create an axis self.ax = self.figure.add_subplot(111) # self.ax.set_aspect('auto') self.ax.plot(self.features, '-') self.ax.legend(self.ax.get_lines(), self.features.columns, bbox_to_anchor=(0., 1.02, 1., .102), loc=3, ncol=8, mode="expand", borderaxespad=0.) self.ax.set_xlim(0, len(self.features)) self.figure.tight_layout() # refresh canvas self.canvas.draw()
class WaterfallPlotter(QWidget): generated_rectangles_signal = QtCore.pyqtSignal(list) #send list of rects for data display in tree def __init__(self,parent): super(WaterfallPlotter,self).__init__(parent) self.get_settings() self.settings_update = False self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas,self) self.btn_plot = QPushButton('Default Plot') self.btn_plot.clicked.connect(self.default_plot) self.layout = QVBoxLayout() self.layout.addWidget(self.toolbar) self.layout.addWidget(self.canvas) self.layout.addWidget(self.btn_plot) self.setLayout(self.layout) def on_waterfall_data_signal(self,signal): self.waterfall_data = signal['waterfall_data'] #pandas dataframe self.btn_plot.setEnabled(True) def get_settings(self): try: with shelve.open('WaterfallSettings') as shelfFile: self.keys_and_colors = shelfFile['keys_and_colors'] shelfFile.close() except: #set and use default settings self.keys_and_colors = { 'CR':'#03945D', 'PR':'#B1EE97', 'PD':'#FF6F69', 'SD':'#707070'} with shelve.open('WaterfallSettings') as shelfFile: shelfFile['keys_and_colors'] = self.keys_and_colors shelfFile.close() def on_general_settings_signal(self,signal): self.gen_settings = signal self.settings_update = True self.default_plot() def get_bar_colors(self,responses): return [self.keys_and_colors[x] for x in responses] def default_plot(self): ''' Plot waterfall data ''' self.figure.clear() self.rect_locations = np.arange(len(self.waterfall_data['Best response percent change'])) self.ax = self.figure.add_subplot(111) self.bar_colors = self.get_bar_colors(self.waterfall_data['Overall response']) if self.settings_update == False: self.ax.tick_params( axis='x', # changes apply to the x-axis which='both', # both major and minor ticks are affected bottom='on', # ticks along the bottom edge are off top='on', # ticks along the top edge are off labelbottom='on' ) # labels along the bottom edge are off self.ax.axhline(y=20, linestyle='--', c='k', alpha=0.5, lw=2.0, label='twenty_percent') self.ax.axhline(y=-30, linestyle='--', c='k', alpha=0.5, lw=2.0, label='thirty_percent') self.ax.axhline(y=0, c='k', alpha=1, lw=2.0, label='zero_percent') self.ax.grid(color = 'k', axis = 'y', alpha=0.25) self.rects = self.ax.bar(self.rect_locations, self.waterfall_data['Best response percent change'], color=self.bar_colors) else: #settings were updated, we received them and stored in variable self.gen_settings self.ax.set_title(self.gen_settings[0]) self.ax.set_xlabel(self.gen_settings[1]) self.ax.set_ylabel(self.gen_settings[2]) if self.gen_settings[3][0]: self.ax.axhline(y=20, linestyle='--', c='k', alpha=0.5, lw=2.0, label='twenty_percent') if self.gen_settings[3][1]: self.ax.axhline(y=-30, linestyle='--', c='k', alpha=0.5, lw=2.0, label='thirty_percent') if self.gen_settings[3][2]: self.ax.axhline(y=0, c='k', alpha=1, lw=2.0, label='zero_percent') if self.gen_settings[4][0] and ~self.gen_settings[6]: #show responses as labels, default color bars #legend depends on user specified keys self.rects = self.ax.bar(self.rect_locations, self.waterfall_data['Best response percent change']) self.add_labels(self.ax, self.rects, self.waterfall_data, 1) elif self.gen_settings[4][1]: #color bars with response type self.rects = self.ax.bar(self.rect_locations, self.waterfall_data['Best response percent change'], color=self.bar_colors) self.patches = [] for key in self.keys_and_colors.keys(): self.patches.append(mpatches.Patch(color = self.keys_and_colors[key],label=key)) self.ax.legend(handles=self.patches) else: self.rects = self.ax.bar(self.rect_locations, self.waterfall_data['Best response percent change']) if self.gen_settings[5]: self.plot_table() if self.gen_settings[6] and ~self.gen_settings[4][0]: self.add_labels(self.ax, self.rects, self.waterfall_data, 0) if ~self.gen_settings[6] self.ax.grid(color = 'k', axis = 'y', alpha=0.25) self.canvas.draw() self.generated_rectangles_signal.emit([self.rects]) def plot_table(self): rows = ['%s' % x for x in self.waterfall_data.keys()] rows = rows[4:] #skip first three, they are the 4 standard headers, rest are table rows columns = self.waterfall_data['Patient number'] #patient numbers cell_text = [] for row in rows: cell_text_temp = [] for col in range(len(columns)): cell_text_temp.append(self.waterfall_data[row][col]) cell_text.append(cell_text_temp) the_table = self.ax.table(cellText=cell_text, rowLabels=rows, colLabels=columns, loc='bottom', cellLoc='center', colLoc='center') plt.subplots_adjust(bottom=0.15,left=0.5) self.ax.set_xlim(-0.5,len(columns)-0.5) self.ax.tick_params( axis='x', # changes apply to the x-axis which='both', # both major and minor ticks are affected bottom='off', # ticks along the bottom edge are off top='off', # ticks along the top edge are off labelbottom='off' ) # labels along the bottom edge are off def update_plot(self): ''' TODO ''' pass def add_labels(self, ax, rects, waterfall_data, label_type): ''' Add labels above/below bars. label_type == 1 --> display responses; == 0 --> display cancer type ''' i = 0 if label_type: for rect in rects: height = rect.get_height() if height >= 0: valign = 'bottom' else: valign = 'top' ax.text(rect.get_x() + rect.get_width()/2., height, '%s' % waterfall_data['Overall response'][i], ha='center', va=valign) i+=1 else: for rect in rects: height = rect.get_height() if height >= 0: valign = 'top' hgt = -1 else: valign = 'bottom' hgt = 1 ax.text(rect.get_x() + rect.get_width()/2., hgt, '%s' % waterfall_data['Cancer'][i], ha='center', va=valign, rotation='vertical') i+=1
class OpappPlotLayout(QVBoxLayout): def __init__(self): super(OpappPlotLayout, self).__init__() self.start = 0 self.end = 1 self.filter = 1 self.pos_x = 0 self.pos_y = 0 self.vmin = -1 self.vmax = 1 self.obj = None self.edit_start = QLineEdit() self.edit_start.setText(str(self.start)) self.edit_start.textChanged.connect(self.draw) self.edit_end = QLineEdit() self.edit_end.setText(str(self.end)) self.edit_end.textChanged.connect(self.draw) self.edit_filter = QLineEdit() self.edit_filter.setText(str(self.filter)) self.edit_filter.textChanged.connect(self.draw) self.edit_pos_x = QLineEdit() self.edit_pos_x.setText(str(self.pos_x)) self.edit_pos_x.textChanged.connect(self.draw) self.edit_pos_y = QLineEdit() self.edit_pos_y.setText(str(self.pos_y)) self.edit_pos_y.textChanged.connect(self.draw) layout = QHBoxLayout() layout.addWidget(QLabel(u'start')) layout.addWidget(self.edit_start) layout.addWidget(QLabel(u'end')) layout.addWidget(self.edit_end) layout.addWidget(QLabel(u'filter')) layout.addWidget(self.edit_filter) layout.addWidget(QLabel(u'pos_x')) layout.addWidget(self.edit_pos_x) layout.addWidget(QLabel(u'pos_y')) layout.addWidget(self.edit_pos_y) self.addLayout(layout) self.figure = plt.figure() self.axes = plt.axes() self.canvas = FigureCanvas(self.figure) self.addWidget(self.canvas) try: self.loadPath() except: pass def setObject(self, obj): self.obj = obj self.vmax = obj.vmax self.vmin = obj.vmin if obj is None: return if len(self.obj.data) > 0: L, H, W = obj.data.shape self.edit_pos_y.setText(str(H // 2)) self.edit_pos_x.setText(str(H // 2)) self.edit_start.setText(str(0)) self.edit_end.setText(str(L)) #self.plot.set_data(t, ts) #self.plot, = self.axes.plot([], []) self.draw() def calc_APD70(self, ts): apd_start = 0 apd_end = 0 threshold = 0.7 * ts.min() + 0.3 * ts.max() flg = 0 for i, v in enumerate(ts): if i == 0: continue if v > threshold and flg == 0: flg = 1 apd_start = i if v <= threshold and flg == 1: flg = 2 apd_end = i return threshold, apd_start, apd_end def draw(self): self.axes.clear() self.start = int(self.edit_start.text()) self.end = int(self.edit_end.text()) self.filter = int(self.edit_filter.text()) self.pos_x = int(self.edit_pos_x.text()) self.pos_y = int(self.edit_pos_y.text()) #try: ts = xp.asnumpy(self.obj.data[self.start:self.end, self.pos_y, self.pos_x]) t = np.arange(self.start, self.end) if self.filter > 1: ts = gaussian_filter1d( ts, sigma=self.filter, ) self.axes.set_xlim(self.start, self.end) #self.axes.set_ylim(self.vmin, self.vmax) self.axes.set_ylim(ts.min(), ts.max()) #self.plot.set_data(t, ts) self.plot = self.axes.plot(t, ts) threshold, apd_start, apd_end = self.calc_APD70(ts) self.axes.hlines(threshold, self.start + apd_start, self.start + apd_end, "blue", linestyles="dashed") self.axes.text(self.start + (0.7 * apd_start + 0.3 * apd_end), threshold + (ts.max() - ts.min()) * 0.1, "APD70: %s (ms)" % (apd_end - apd_start), fontsize=20) self.canvas.draw() pass
class WaterfallPlotter(QWidget): generated_rectangles_signal = QtCore.pyqtSignal(list) #send list of rects for data display in tree def __init__(self,parent): super(WaterfallPlotter,self).__init__(parent) self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas,self) self.btn_plot = QPushButton('Default Plot') self.btn_plot.clicked.connect(self.default_plot) self.layout = QVBoxLayout() self.layout.addWidget(self.toolbar) self.layout.addWidget(self.canvas) self.layout.addWidget(self.btn_plot) self.setLayout(self.layout) def on_waterfall_data_signal(self,signal): self.waterfall_data = signal['waterfall_data'] #pandas dataframe self.btn_plot.setEnabled(True) def on_general_settings_signal(self,signal): try: hasattr(self,'ax') self.ax.set_title(signal[0]) self.ax.set_xlabel(signal[1]) self.ax.set_ylabel(signal[2]) self.canvas.draw() except Exception as e: print(e) def default_plot(self): ''' Plot waterfall data ''' self.figure.clear() self.rect_locations = np.arange(len(self.waterfall_data['Best response percent change'])) self.ax = self.figure.add_subplot(111) self.ax.axhline(y=20, linestyle='--', c='k', alpha=0.5, lw=2.0, label='twenty_percent') self.ax.axhline(y=-30, linestyle='--', c='k', alpha=0.5, lw=2.0, label='thirty_percent') self.ax.axhline(y=0, c='k', alpha=1, lw=2.0, label='zero_percent') self.ax.grid(color = 'k', axis = 'y', alpha=0.25) self.rects = self.ax.bar(self.rect_locations,self.waterfall_data['Best response percent change']) self.auto_label_responses(self.ax, self.rects, self.waterfall_data) #self.plot_table() self.canvas.draw() self.ax.hold(False) #rewrite the plot when plot() called self.generated_rectangles_signal.emit([self.rects]) def plot_table(self): rows = ['%s' % x for x in self.waterfall_data.keys()] rows = rows[4:] #skip first three, they are the 4 standard headers, rest are table rows columns = self.waterfall_data['Patient number'] #patient numbers cell_text = [] for row in rows: cell_text_temp = [] for col in range(len(columns)): cell_text_temp.append(self.waterfall_data[row][col]) cell_text.append(cell_text_temp) the_table = plt.table(cellText=cell_text, rowLabels=rows, colLabels=columns, loc='bottom', cellLoc='center') plt.subplots_adjust(bottom=0.15,left=0.5) self.ax.set_xlim(-0.5,len(columns)-0.5) plt.tick_params( axis='x', # changes apply to the x-axis which='both', # both major and minor ticks are affected bottom='off', # ticks along the bottom edge are off top='off', # ticks along the top edge are off labelbottom='off' ) # labels along the bottom edge are off def update_plot(self): ''' TODO ''' pass def auto_label_responses(self, ax, rects, waterfall_data): '''Add labels above/below bars''' i = 0 for rect in rects: height = rect.get_height() if height >= 0: valign = 'bottom' else: valign = 'top' ax.text(rect.get_x() + rect.get_width()/2., height, '%s' % waterfall_data['Overall response'][i], ha='center', va=valign) i+=1
class optMonitor(_optMonitor, _optMonitorUI): setStatusBar = QtCore.Signal(str) updateGraph = QtCore.Signal() def __init__(self, dat, parent=None): ''' Constructor for model set up dialog ''' super(optMonitor, self).__init__(parent=parent) self.settingsForm = parent self.setupUi(self) # Create the widgets self.dat = dat # all of the session data self.msgSubwindow = optMessageWindow(self) self.plotSubwindow = noCloseWidget(self) self.plotSubwindow.setLayout(QVBoxLayout()) self.coordPlotSubwindow = noCloseWidget(self) self.coordPlotSubwindow.setLayout(QVBoxLayout()) self.plotSubwindow.setMaximumSize(5000, 3000) self.coordPlotSubwindow.setMaximumSize(5000, 3000) self.mdiArea.addSubWindow(self.plotSubwindow) self.plotSubwindow.setWindowTitle("Objective Function Plot") self.mdiArea.addSubWindow(self.coordPlotSubwindow) self.coordPlotSubwindow.setWindowTitle( "Best Solution Parallel Coordinate Plot") self.mdiArea.addSubWindow(self.msgSubwindow) self.msgSubwindow.setWindowTitle("Optimization Solver Messages") self.startButton.clicked.connect(self.startOptimization) self.stopButton.clicked.connect(self.stopOptimization) self.msgSubwindow.clearMsgButton.clicked.connect(self.clearMessages) # setup plot the plots self.objFig = Figure(figsize=(600, 600), dpi=72, facecolor=(1, 1, 1), edgecolor=(0, 0, 0), tight_layout=True) self.coordFig = Figure(figsize=(600, 600), dpi=72, facecolor=(1, 1, 1), edgecolor=(0, 0, 0), tight_layout=True) self.objFigAx = self.objFig.add_subplot(111) self.coordFigAx = self.coordFig.add_subplot(111) self.objCanvas = FigureCanvas(self.objFig) self.coordCanvas = FigureCanvas(self.coordFig) self.plotSubwindow.layout().addWidget(self.objCanvas) self.objCanvas.setParent(self.plotSubwindow) self.coordPlotSubwindow.layout().addWidget(self.coordCanvas) self.coordCanvas.setParent(self.coordPlotSubwindow) self.timer = QtCore.QTimer(self) #self.connect( # self.timer, # QtCore.SIGNAL("timeout()"), # self.updateStatus) self.timer.timeout.connect(self.updateStatus) self.updateDelay = 500 self.delayEdit.setText(str(self.updateDelay)) self.delayEdit.textChanged.connect(self.updateDelayChange) self.opt = None self.bestObj = 0 self.bestCoord = None self.iteration = 0 self.mdiArea.tileSubWindows() self.startButton.setEnabled(True) self.stopButton.setEnabled(False) def createMessageWindow(self): pass def createParallelAxisPlot(self): pass def createObjectivePlot(self): pass def updateDelayChange(self): if self.delayEdit.text() == "": self.updateDelay = 0 else: try: self.updateDelay = int(float(self.delayEdit.text())) except: self.delayEdit.setText(str(self.updateDelay)) def clearMessages(self): self.msgSubwindow.clearMessages() self.msgSubwindow.statusLine.setText("") def clearPlots(self): self.objFigAx.clear() self.coordFigAx.clear() self.objFigAx.set_xlabel("Iteration") self.objFigAx.set_ylabel("Objective") #self.objCanvas.draw() #self.coordCanvas.draw() def coordAxSetup(self): self.coordFigAx.clear() self.xnames = [] gr = self.dat.flowsheet for name in self.opt.prob.v: self.xnames.append(name) self.coordFigAx.set_xlabel("Variable") self.coordFigAx.set_ylabel("Scaled Value") self.coordFigAx.set_ylim(-0.1, 10.1, auto=False) self.coordFigAx.set_xlim(0.75, len(self.xnames) + 0.25, auto=False) self.coordFigAx.set_yticks(list(range(11))) self.coordFigAx.set_xticks(list(range(1, len(self.xnames) + 1))) self.coordFigAx.set_xticklabels(self.xnames, rotation='vertical') self.bestX = [11] * len(self.xnames) self.sampLim = [[11] * len(self.xnames), [11] * len(self.xnames)] self.coordXCoord = list(range(1, (len(self.bestX) + 1))) self.coorFigLine1 = self.coordFigAx.plot(self.coordXCoord, self.bestX) self.coorFigLine2 = self.coordFigAx.plot(self.coordXCoord, self.sampLim[0], 'bo') self.coorFigLine3 = self.coordFigAx.plot(self.coordXCoord, self.sampLim[1], 'bo') def startOptimization(self): self.dat.flowsheet.generateGlobalVariables() pg = self.dat.optSolvers.plugins[self.dat.optProblem.solver].\ opt(self.dat) e = self.dat.optProblem.check(self.dat.flowsheet, pg.minVars, pg.maxVars) if not e[0] == 0: QMessageBox.information( self, "Error", "The optimization will not be started there is an error in the set up:\n" + e[1]) return self.dat.save("backupBeforeOpt.json", False) self.clearPlots() self.objCanvas.draw() self.settingsForm.running = True self.opt = self.dat.optProblem.run(self.dat) time.sleep( 0.5) #give the optimization function a little time to get started self.coordAxSetup() self.a = True self.timer.start(self.updateDelay) self.timeRunning = time.time() self.startButton.setEnabled(False) self.stopButton.setEnabled(True) self.setStatusBar.emit("Optimization Running") def stopOptimization(self): self.opt.terminate() def updateStatus(self): done = False if self.opt.updateGraph: self.opt.updateGraph = False self.updateGraph.emit() if not self.opt.isAlive(): done = True while not self.opt.msgQueue.empty(): msg = str(self.opt.msgQueue.get(False)) self.msgSubwindow.msgTextBrowser.append(msg) bestChange = False itChange = False updateStatusLine = False objPoints = [[], []] while not self.opt.resQueue.empty(): msg = self.opt.resQueue.get(False) if msg[0] == "BEST": self.bestObj = msg[1][0] self.bestX = msg[2] bestChange = True elif msg[0] == "SAMP": if self.a: self.samp = np.array(msg[1]) self.sampLim = [[0] * len(self.xnames), [10] * len(self.xnames)] for i in range(len(self.xnames)): self.sampLim[0][i] = np.min(self.samp[:, i]) self.sampLim[1][i] = np.max(self.samp[:, i]) bestChange = True elif msg[0] == "IT": self.iteration = msg[1] itChange = True objPoints[0].append(msg[1]) objPoints[1].append(msg[2]) elif msg[0] == "PROG": itJobsComplete = msg[1] itTotalJobs = msg[2] itErrors = msg[3] it = msg[4] totalRead = msg[5] totalErrors = msg[6] updateStatusLine = True if bestChange: self.coorFigLine1[0].set_data(self.coordXCoord, self.bestX) self.coorFigLine2[0].set_data(self.coordXCoord, self.sampLim[0]) self.coorFigLine3[0].set_data(self.coordXCoord, self.sampLim[1]) self.coordCanvas.draw() if itChange: self.objFigAx.plot(objPoints[0], objPoints[1], 'bo') self.objCanvas.draw() if updateStatusLine: self.msgSubwindow.statusLine.setText("".join([ "ITERATION ", str(it), ": ", str(itJobsComplete), "/", str(itTotalJobs), " Err: ", str(itErrors), " TOTAL Complete: ", str(totalRead), " Err:", str(totalErrors) ])) if done: self.timer.stop() self.startButton.setEnabled(True) self.stopButton.setEnabled(False) self.setStatusBar.emit( "Optimization Finished, Elapsed Time: " + hhmmss(math.floor(time.time() - self.timeRunning))) self.settingsForm.refreshContents() self.settingsForm.running = False else: self.setStatusBar.emit( "Optimization Running, Elapsed Time: " + hhmmss(math.floor(time.time() - self.timeRunning)))
class MinionCwodmrUI(QWidget): continueodmr = pyqtSignal() def __init__(self, parent): super(MinionCwodmrUI, self).__init__(parent) self.parent = parent self.counter = self.parent.counter # smiq.connect(smiq) self.measurementrunning = False self.frequency = 2.87*10**9 #Hz self.power = -20. self.modi = ['const', 'list'] self.mode = 'const' self.cwodmrdata = np.zeros(100) self.freqlist = [] self.powerlist = [] self.uisetup() def __del__(self): pass# smiq.disconnect(smiq) def uisetup(self): self.cwodmrfigure = Figure() self.cwodmrcanvas = FigureCanvas(self.cwodmrfigure) self.cwodmrcanvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.cwodmrcanvas.setMinimumSize(50, 50) self.cwodmrtoolbar = NavigationToolbar(self.cwodmrcanvas, self) self.cwodmraxes = self.cwodmrfigure.add_subplot(111) self.cwodmraxes.hold(False) self.freqlabel = QLabel('Frequency [GHz]') self.freqtext = QDoubleSpinBox() self.freqtext.setRange(0, 6) self.freqtext.setDecimals(6) self.freqtext.setSingleStep(0.001) self.freqtext.setValue(self.frequency/(1.*10**9)) self.freqtext.editingFinished.connect(self.freqchanged) self.powerlabel = QLabel('Power [dBm]') self.powertext = QDoubleSpinBox() self.powertext.setRange(-140, 16) self.powertext.setDecimals(1) self.powertext.setValue(self.power) self.powertext.editingFinished.connect(self.powerchanged) self.modeselectlabel = QLabel('mode:') self.modeselect = QComboBox() self.modeselect.addItems(self.modi) self.modeselect.currentIndexChanged.connect(self.modechange) self.toggleoutputbutton = QPushButton('output on/off') self.toggleoutputbutton.setCheckable(True) self.toggleoutputbutton.setStyleSheet("QPushButton {background-color: red;}") self.toggleoutputbutton.toggled.connect(self.toggleoutput) self.listtable = QTableWidget() self.listtable.setColumnCount(4) self.listtable.setRowCount(1) self.listtable.setHorizontalHeaderLabels(('start[GHz]', 'stop[GHz]', 'points[#]', 'power[dBm]')) self.listtableaddrowbutton = QPushButton('add row') self.listtableaddrowbutton.clicked.connect(self.listtableaddrow) self.listtableremoverowbutton = QPushButton('remove row') self.listtableremoverowbutton.clicked.connect(self.listtableremoverow) self.sendlisttosmiqbutton = QPushButton('send list') self.sendlisttosmiqbutton.clicked.connect(self.sendlisttosmiq) self.startcwodmrbutton = QPushButton('start sweep') self.startcwodmrbutton.setCheckable(True) self.startcwodmrbutton.setStyleSheet("QPushButton {background-color: red;}") self.startcwodmrbutton.toggled.connect(self.startcwodmr) self.abortodmrsweepbutton = QPushButton('abort sweep') self.abortodmrsweepbutton.clicked.connect(self.abortodmrsweep) self.saveodmrsweepbutton = QPushButton('save spectrum') self.saveodmrsweepbutton.clicked.connect(self.saveodmrsweep) # LAYOUT cwodmrlayout = QGridLayout() cwodmrlayout.addWidget(self.cwodmrcanvas) cwodmrlayout.addWidget(self.cwodmrtoolbar) cwodmrlayout.addWidget(self.freqlabel) cwodmrlayout.addWidget(self.freqtext) cwodmrlayout.addWidget(self.powerlabel) cwodmrlayout.addWidget(self.powertext) cwodmrlayout.addWidget(self.modeselectlabel) cwodmrlayout.addWidget(self.modeselect) cwodmrlayout.addWidget(self.toggleoutputbutton) cwodmrlayout.addWidget(self.listtable) cwodmrlayout.addWidget(self.listtableaddrowbutton) cwodmrlayout.addWidget(self.listtableremoverowbutton) cwodmrlayout.addWidget(self.sendlisttosmiqbutton) cwodmrlayout.addWidget(self.startcwodmrbutton) cwodmrlayout.addWidget(self.abortodmrsweepbutton) cwodmrlayout.addWidget(self.saveodmrsweepbutton) self.setLayout(cwodmrlayout) def abortodmrsweep(self): try: print('aborting sweep') self.cwODMRaquisition.stop() self.cwODMRaquisitionthread.quit() except: print('no sweep running') def saveodmrsweep(self): np.save('odmr_data.npy', self.cwodmrdata) print('spectrum saved') def freqchanged(self): freq = self.freqtext.value()*10**9 self.freq = smiq.freq(smiq, freq) def powerchanged(self): power = self.powertext.value() self.power = smiq.power(smiq, power) def modechange(self): pass def toggleoutput(self): if self.toggleoutputbutton.isChecked() is True: self.toggleoutputbutton.setStyleSheet("QPushButton {background-color: green;}") smiq.on(smiq) else: self.toggleoutputbutton.setStyleSheet("QPushButton {background-color: red;}") smiq.off(smiq) def listtableaddrow(self): self.listtable.insertRow(self.listtable.rowCount()+1) self.listtable.setRowCount(self.listtable.rowCount()+1) def listtableremoverow(self): if self.listtable.rowCount() >= 2: self.listtable.removeRow(self.listtable.rowCount()) self.listtable.setRowCount(self.listtable.rowCount()-1) else: pass def sendlisttosmiq(self): self.freqlist = [] self.powerlist = [] self.listdata = np.zeros((self.listtable.rowCount(), self.listtable.columnCount())) for i in range(self.listtable.rowCount()): for j in range(self.listtable.columnCount()): self.listdata[i, j] = float(self.listtable.item(i, j).text().replace(',', '.')) for i in range(len(self.listdata)): list = self.listdata[i, :] self.freqlist.extend(np.array(np.linspace(list[0]*10**9, list[1]*10**9, int(list[2])))) self.powerlist.extend(np.ones(int(list[2]))*list[3]) self.power = self.powerlist[0] print('list updated') # smiq.setlist(smiq, self.freqlist, self.powerlist) @pyqtSlot(np.ndarray) def updateODMRdata(self, odmrupdate): self.cwodmrdataplot += odmrupdate if np.size(self.cwodmrdata, 0) == 1: self.cwodmrdata = odmrupdate self.cwodmraxes.plot(self.freqlist[:-1], self.cwodmrdataplot[:-1]) else: self.cwodmrdata = np.vstack((self.cwodmrdata, odmrupdate)) self.cwodmraxes.plot(self.freqlist[:-1], self.cwodmrdataplot[:-1]) # self.cwodmraxes.relim() # self.cwodmraxes.autoscale_view() self.cwodmrcanvas.draw() @pyqtSlot() def continueodmraquisition(self): self.continueodmr.emit() def startcwodmr(self): if self.startcwodmrbutton.isChecked() is True: if self.parent.hardware_stage is True and self.parent.hardware_counter is True: self.measurementrunning = True self.cwodmrdata = np.zeros(len(self.freqlist)) self.cwodmrdataplot = np.zeros(len(self.freqlist)) self.cwODMRaquisition = MinionODMRAquisition(self.parent.fpga, self.parent.confocalwidget.xpos, self.parent.confocalwidget.ypos, self.parent.confocalwidget.zpos, self.power, self.freqlist) self.cwODMRaquisitionthread = QThread(self, objectName='workerThread') self.cwODMRaquisition.moveToThread(self.cwODMRaquisitionthread) self.cwODMRaquisition.finished.connect(self.cwODMRaquisitionthread.quit) self.cwODMRaquisition.track.connect(self.parent.trackerwidget.findmaxclicked) self.cwODMRaquisition.update.connect(self.updateODMRdata) self.continueodmr.connect(self.cwODMRaquisition.trackfinished) self.cwODMRaquisitionthread.started.connect(self.cwODMRaquisition.longrun) self.cwODMRaquisitionthread.finished.connect(self.cwODMRaquisitionthread.deleteLater) # self.findmax.update.connect(self.updatefindcentermaps) self.cwODMRaquisitionthread.start() self.startcwodmrbutton.setStyleSheet("QPushButton {background-color: green;}") # self.parent.fpga.settriggermasks(mask=8, invertedmask=8) # SetTriggerMask + SetTriggerinvertedMask # self.parent.fpga.setnumbercountingbins(len(self.freqlist)) # SetNumberOfTriggeredCountingBins # print('num bins:', self.parent.fpga.getnumbercountingbins()) # # self.parent.fpga.setcountingbinrepetitions(1) # SetTriggeredCountingBinRepetitions # self.parent.fpga.setsplittriggeredbins(0) # SetSplitTriggeredCountingBins # smiq.liston(smiq) # time.sleep(2) # self.parent.fpga.resettriggerbins() #ResetTriggeredCountingData # time.sleep(0.001) # self.parent.fpga.enabletriggeredcounting() #EnableTriggeredCounting # time.sleep(0.001) # self.cwodmrdata = np.zeros(len(self.freqlist)) # # for i in range(2): # smiq.listrun(smiq) # time.sleep(len(self.freqlist)*0.011*2) # print('binpos:', self.parent.fpga.getcurrentbinpos()) # print('counttime:', self.parent.fpga.checkcounttime()) # smiq.listrun(smiq) # apd1, apd2, apd_sum = self.parent.fpga.readcountingbins() # self.cwodmrdata += apd_sum # print(self.cwodmrdata) # # time.sleep(0.5) # # smiq.cw(smiq, 2.87*10**9, -20) # # disable triggered counting # # # self.counter.write(b'r') #DisableTriggeredCounting # # self.counter.write(b'0') #ResetTriggeredCountingData # # check_counttime = self.parent.fpga.checkcounttime() # check counttime # print('counttime:', check_counttime) # # self.counter.write(b'r') #DisableTriggeredCounting # TODO - remove below and fix above # dont use list mode and sweep over cw modes else: self.startcwodmrbutton.toggle() self.startcwodmrbutton.setStyleSheet("QPushButton {background-color: red;}")
class R2DWindow(QtWidgets.QMainWindow): XY_VIEW = "X/Y" THREE_PANEL_VIEW = "Three panel" def __init__(self): super(R2DWindow, self).__init__() self.fixed_img = None self.moving_img = None self.setGeometry(0, 0, 1024, 768) # # Menus # self.file_menu = QtWidgets.QMenu("&File", self) self.file_menu.addAction("Open Fixed", self.open_fixed) self.file_menu.addAction("Open Moving", self.open_moving) self.file_menu.addAction("Save", self.save) self.menuBar().addMenu(self.file_menu) # # Splitter # main_widget = QtWidgets.QWidget() self.setCentralWidget(main_widget) top_layout = QtWidgets.QVBoxLayout() main_widget.setLayout(top_layout) splitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal) top_layout.addWidget(splitter) # # Controls # left_widget = QtWidgets.QWidget() splitter.addWidget(left_widget) left_layout = QtWidgets.QVBoxLayout() left_widget.setLayout(left_layout) # offset group = QtWidgets.QGroupBox("Offset") left_layout.addWidget(group) group_layout = QtWidgets.QVBoxLayout() group.setLayout(group_layout) hlayout = QtWidgets.QHBoxLayout() group_layout.addLayout(hlayout) hlayout.addWidget(QtWidgets.QLabel("X:")) self.w_off_x = QtWidgets.QSpinBox() hlayout.addWidget(self.w_off_x) hlayout = QtWidgets.QHBoxLayout() group_layout.addLayout(hlayout) hlayout.addWidget(QtWidgets.QLabel("Y:")) self.w_off_y = QtWidgets.QSpinBox() hlayout.addWidget(self.w_off_y) # center group = QtWidgets.QGroupBox("Center") left_layout.addWidget(group) group_layout = QtWidgets.QVBoxLayout() group.setLayout(group_layout) hlayout = QtWidgets.QHBoxLayout() group_layout.addLayout(hlayout) hlayout.addWidget(QtWidgets.QLabel("X:")) self.w_center_x = QtWidgets.QSpinBox() hlayout.addWidget(self.w_center_x) hlayout = QtWidgets.QHBoxLayout() group_layout.addLayout(hlayout) hlayout.addWidget(QtWidgets.QLabel("Y:")) self.w_center_y = QtWidgets.QSpinBox() hlayout.addWidget(self.w_center_y) self.w_center_button = QtWidgets.QPushButton("Center") group_layout.addWidget(self.w_center_button) self.w_center_button.clicked.connect(self.on_center) # angle group = QtWidgets.QGroupBox("Rotation") left_layout.addWidget(group) group_layout = QtWidgets.QVBoxLayout() group.setLayout(group_layout) hlayout = QtWidgets.QHBoxLayout() group_layout.addLayout(hlayout) hlayout.addWidget(QtWidgets.QLabel("Angle in degrees:")) self.w_angle = QtWidgets.QDoubleSpinBox() hlayout.addWidget(self.w_angle) hlayout = QtWidgets.QHBoxLayout() group_layout.addLayout(hlayout) self.w_flip_lr = QtWidgets.QCheckBox("Flip left/right") hlayout.addWidget(self.w_flip_lr) hlayout = QtWidgets.QHBoxLayout() group_layout.addLayout(hlayout) self.w_flip_ud = QtWidgets.QCheckBox("Flip up/down") hlayout.addWidget(self.w_flip_ud) # z heights group = QtWidgets.QGroupBox("Z height and downsample") left_layout.addWidget(group) group_layout = QtWidgets.QVBoxLayout() group.setLayout(group_layout) hlayout = QtWidgets.QHBoxLayout() group_layout.addLayout(hlayout) hlayout.addWidget(QtWidgets.QLabel("Fixed:")) self.fixed_img_z = QtWidgets.QSpinBox() hlayout.addWidget(self.fixed_img_z) hlayout = QtWidgets.QHBoxLayout() group_layout.addLayout(hlayout) hlayout.addWidget(QtWidgets.QLabel("Moving:")) self.moving_img_z = QtWidgets.QSpinBox() hlayout.addWidget(self.moving_img_z) hlayout = QtWidgets.QHBoxLayout() group_layout.addLayout(hlayout) hlayout.addWidget(QtWidgets.QLabel("Downsample: ")) self.w_downsample = QtWidgets.QSpinBox() hlayout.addWidget(self.w_downsample) self.w_downsample.setMinimum(1) self.w_downsample.setMaximum(32) self.w_downsample.setValue(1) hlayout = QtWidgets.QHBoxLayout() group_layout.addLayout(hlayout) hlayout.addWidget(QtWidgets.QLabel("View")) self.w_view_choice = QtWidgets.QComboBox() self.w_view_choice.addItems([self.XY_VIEW, self.THREE_PANEL_VIEW]) self.w_view_choice.setCurrentIndex(1) self.w_view_choice.setEditable(False) hlayout.addWidget(self.w_view_choice) self.show_button = QtWidgets.QPushButton("Show") left_layout.addWidget(self.show_button) self.show_button.setDisabled(True) self.show_button.clicked.connect(self.on_show) left_layout.addStretch(1) # # Matplotlib canvas # self.figure = Figure() self.canvas = FigureCanvasQTAgg(self.figure) splitter.addWidget(self.canvas) self.addToolBar(NavigationToolbar(self.canvas, self)) self.figure.add_subplot(1, 1, 1) self.canvas.draw() def open_fixed(self): try: self.fixed_img = self.open_any("Fixed") except UserWarning: return except FileNotFoundError as e: QtWidgets.QMessageBox.warning(self, "File not found", e.strerror) return self.fixed_img_z.setMinimum(0) self.fixed_img_z.setMaximum(self.fixed_img.shape[2]) self.w_center_x.setMaximum(self.fixed_img.shape[0]) self.w_center_y.setMaximum(self.fixed_img.shape[1]) self.update_ui() def open_any(self, name): # Grrr... native directory dialogs are BROKEN in Gnome, it seems. # So use the generic built-in # filename = QtWidgets.QFileDialog.getExistingDirectory( self, "%s ZARR file name" % name, ".", QtWidgets.QFileDialog.ShowDirsOnly | QtWidgets.QFileDialog.DontUseNativeDialog ) if len(filename) == 0: raise UserWarning("No filename entered") try: return zarr.open(filename, mode="r") except: raise FileNotFoundError(errno.ENOENT, "Unable to open %s as ZARR file" % filename, filename) def open_moving(self): try: self.moving_img = self.open_any("Moving") except UserWarning: return except FileNotFoundError as e: QtWidgets.QMessageBox.warning(self, "File not found", e.strerror()) return self.w_off_x.setMinimum(-self.moving_img.shape[0]) self.w_off_x.setMaximum(self.moving_img.shape[0]) self.w_off_y.setMinimum(-self.moving_img.shape[1]) self.w_off_y.setMaximum(self.moving_img.shape[1]) self.moving_img_z.setMinimum(0) self.moving_img_z.setMaximum(self.moving_img.shape[2]) self.update_ui() def save(self): filename, filter_type = QtWidgets.QFileDialog.getSaveFileName( self, "Save parameters", filter="JSON file (*.json)", options=QtWidgets.QFileDialog.DontUseNativeDialogs ) d = dict( x_offset=self.w_off_x.value(), y_offset=self.w_off_y.value(), x_center=self.w_center_x.value(), y_center=self.w_center_y.value(), angle=self.w_angle.value(), flip_lr=self.w_flip_lr.isChecked(), flip_ud=self.w_flip_ud.isChecked() ) with open(filename, "w") as fd: json.dump(d, fd, indent=2) def update_ui(self): if self.fixed_img is not None and self.moving_img is not None: self.show_button.setEnabled(True) else: self.show_button.setDisabled(True) def on_center(self, *args): if self.fixed_img is not None: center_x = self.fixed_img.shape[0] // 2 center_y = self.fixed_img.shape[1] // 2 self.w_center_x.setValue(center_x) self.w_center_y.setValue(center_y) def on_show(self, *args): QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) self.figure.clf() if self.w_view_choice.currentText() == self.XY_VIEW: self.show_xy(self.figure.add_subplot(1, 1, 1)) else: ax_xy = self.figure.add_subplot(2, 2, 1) ax_xz = self.figure.add_subplot(2, 2, 2) ax_yz = self.figure.add_subplot(2, 2, 4) self.show_xy(ax_xy) self.show_xz(ax_xz) self.show_yz(ax_yz) self.canvas.draw() QtWidgets.QApplication.restoreOverrideCursor() def show_xy(self, axes): downsample = self.w_downsample.value() fixed_slice = self.fixed_img[::downsample, ::downsample, self.fixed_img_z.value()].transpose() moving_slice = self.moving_img[::downsample, ::downsample, self.moving_img_z.value()].transpose() if self.w_flip_lr.isChecked(): moving_slice = np.fliplr(moving_slice) if self.w_flip_ud.isChecked(): moving_slice = np.flipud(moving_slice) angle = self.w_angle.value() * np.pi / 180 rot_matrix = np.array([[np.cos(angle), -np.sin(angle)], [np.sin(angle), np.cos(angle)]]) y, x = np.mgrid[0:fixed_slice.shape[0], 0:fixed_slice.shape[1]] center = np.array([self.w_center_y.value(), self.w_center_x.value()]).reshape(1, 2) // downsample offset = np.array([self.w_off_y.value(), self.w_off_x.value()]).reshape(1, 2) // downsample yx = np.column_stack([y.flatten(), x.flatten()]) yxt = ((yx - center - offset) @ rot_matrix) + center yt, xt = yxt.transpose() yt, xt = [_.reshape(fixed_slice.shape) for _ in (yt, xt)] cimg = np.zeros((fixed_slice.shape[0], fixed_slice.shape[1], 3), np.float32) cimg[:, : , 0] = fixed_slice map_coordinates(moving_slice, [yt, xt], cimg[:, :, 1]) axes.cla() clip = np.quantile(cimg.flatten(), .90) axes.imshow(np.clip(cimg, 0, clip) / clip) self.redo_axes_ticks(axes, self.fixed_img.shape[0], self.fixed_img.shape[1]) def redo_axes_ticks(self, axes:matplotlib.axes.Axes, x_len:int, y_len:int): downsample = self.w_downsample.value() x_stops = np.linspace(0, x_len, 6) x_stops_downsampled = x_stops / downsample axes.set_xticks(x_stops_downsampled) axes.set_xticklabels(["%d" % x for x in x_stops]) y_stops = np.linspace(0, y_len, 6)[::-1] y_stops_downsampled = y_stops / downsample axes.set_yticks(y_stops_downsampled) axes.set_yticklabels(["%d" % y for y in y_stops]) def show_xz(self, axes): downsample = self.w_downsample.value() y = self.fixed_img.shape[1] // 2 min_x = min(self.fixed_img.shape[0], self.moving_img.shape[0]) min_z = min(self.fixed_img.shape[2], self.moving_img.shape[2]) fixed_slice = self.fixed_img[:min_x:downsample, y, :min_z:downsample].transpose() moving_slice = self.moving_img[:min_x:downsample, y, :min_z:downsample].transpose() combined = np.stack([fixed_slice, moving_slice, np.zeros_like(fixed_slice)], 2).astype(np.float32) clip = np.quantile(combined.flatten(), .90) combined = np.clip(combined, 0, clip) axes.imshow(combined) z_fixed = self.fixed_img_z.value() // downsample z_moving = self.moving_img_z.value() // downsample axes.plot([0, min_x // downsample], [z_fixed, z_fixed]) axes.plot([0, min_x // downsample], [z_moving, z_moving]) self.redo_axes_ticks(axes, min_x, min_z) def show_yz(self, axes): downsample = self.w_downsample.value() x = self.fixed_img.shape[0] // 2 min_y = min(self.fixed_img.shape[1], self.moving_img.shape[1]) min_z = min(self.fixed_img.shape[2], self.moving_img.shape[2]) fixed_slice = self.fixed_img[x, :min_y:downsample, :min_z:downsample] moving_slice = self.moving_img[x, :min_y:downsample, :min_z:downsample] combined = np.stack([fixed_slice, moving_slice, np.zeros_like(fixed_slice)], 2).astype(np.float32) clip = np.quantile(combined.flatten(), .90) combined = np.clip(combined, 0, clip) axes.imshow(combined) z_fixed = self.fixed_img_z.value() // downsample z_moving = self.moving_img_z.value() // downsample axes.plot([z_fixed, z_fixed], [0, min_y // downsample]) axes.plot([z_moving, z_moving], [0, min_y // downsample]) self.redo_axes_ticks(axes, min_z, min_y)
class HistogramDialog(QDialog): """ This dialog controls settings for plotting a histogram and displays it """ def __init__(self, *args, **kwargs): super(HistogramDialog, self).__init__(*args, **kwargs) self.appctx = self.parent().appctx self.dataset = self.appctx.datasets[self.appctx.current_dataset_idx] self.column = list(self.dataset.df)[0] self.bins = None self.figsize = (12, 5) self.dpi = 100 # Setup UI self.setup_ui() def setup_ui(self): self.setWindowTitle(f"Plot Histogram") self.setMinimumWidth(500) self.setModal(True) layout = QHBoxLayout() # Settings settings = QGroupBox("Plot Settings") left_layout = QFormLayout() settings.setLayout(left_layout) layout.addWidget(settings) # Plot right_layout = QVBoxLayout() layout.addLayout(right_layout) # Canvas fig = Figure(figsize=self.figsize, dpi=self.dpi) self.canvas = FigureCanvas(fig) right_layout.addWidget(self.canvas) # Toolbar self.canvas_toolbar = NavigationToolbar(self.canvas, self) right_layout.addWidget(self.canvas_toolbar) # Which column in the dataset self.column_btn = QPushButton("None", parent=self) self.column_btn.clicked.connect(self.launch_get_column) left_layout.addRow("Variable", self.column_btn) # Number of bins self.bins_sb = QSpinBox(parent=self) self.bins_sb.valueChanged.connect(self.update_bin_num) self.update_bin_setting() left_layout.addRow("Number of Bins", self.bins_sb) # Ok/Cancel QBtn = QDialogButtonBox.Close self.buttonBox = QDialogButtonBox(QBtn) right_layout.addWidget(self.buttonBox) self.buttonBox.rejected.connect(self.reject) # Set Layout self.setLayout(layout) # Plot inital selection self.column_btn.setText(f"{self.column}") self.update_canvas() def launch_get_column(self): """Launch a dialog to set the plotted column from the dataset""" column = SelectColumnDialog.get_column( columns=list(self.dataset.df), selected=self.column, parent=self ) if column is not None: self.column = column self.column_btn.setText(f"{self.column}") self.update_bin_setting() self.update_canvas() def update_bin_setting(self): var_type = self.dataset.get_types()[self.column] var_unique_vals = self.dataset.df[self.column].nunique() if var_type == "categorical": self.bins_sb.setEnabled(False) self.bins_sb.setRange(1, var_unique_vals) self.bins_sb.setValue(var_unique_vals) else: self.bins_sb.setEnabled(True) self.bins_sb.setRange(1, var_unique_vals) self.bins_sb.setValue(min(100, var_unique_vals)) def update_canvas(self): self.canvas.figure.clear() clarite.plot.histogram( data=self.dataset.df, column=self.column, title=f"Histogram of {self.column}", figure=self.canvas.figure, bins=self.bins, ) self.canvas.draw() @pyqtSlot(int) def update_bin_num(self, value): self.bins = value self.update_canvas()
class StatsWidget(QWidget, FORM_CLASS): signalAskCloseWindow = pyqtSignal(name='signalAskCloseWindow') def __init__(self, parent=None): self.parent = parent super(StatsWidget, self).__init__() self.setupUi(self) self.label_progressStats.setText('') # Connect # noinspection PyUnresolvedReferences self.pushButton_saveTable.clicked.connect(self.save_table) # noinspection PyUnresolvedReferences self.pushButton_saveYValues.clicked.connect(self.save_y_values) self.buttonBox_stats.button(QDialogButtonBox.Ok).clicked.connect( self.run_stats) self.buttonBox_stats.button(QDialogButtonBox.Cancel).clicked.connect( self.signalAskCloseWindow.emit) # a figure instance to plot on self.figure = Figure() self.canvas = FigureCanvas(self.figure) self.canvas.setMinimumSize(QSize(300, 0)) self.toolbar = CustomNavigationToolbar(self.canvas, self) self.layout_plot.addWidget(self.toolbar) self.layout_plot.addWidget(self.canvas) self.tab = [] self.comboBox_blurredLayer.setFilters( QgsMapLayerProxyModel.PolygonLayer) self.comboBox_statsLayer.setFilters( QgsMapLayerProxyModel.PolygonLayer) def run_stats(self): self.progressBar_stats.setValue(0) self.label_progressStats.setText('') # noinspection PyArgumentList QApplication.processEvents() blurred_layer = self.comboBox_blurredLayer.currentLayer() stats_layer = self.comboBox_statsLayer.currentLayer() try: if not blurred_layer or not stats_layer: raise NoLayerProvidedException crs_blurred_layer = blurred_layer.crs() crs_stats_layer = stats_layer.crs() if crs_blurred_layer != crs_stats_layer: raise DifferentCrsException( epsg1=crs_blurred_layer.authid(), epsg2=crs_stats_layer.authid()) if blurred_layer == stats_layer: raise NoLayerProvidedException if not blurred_layer or not stats_layer: raise NoLayerProvidedException nb_feature_stats = stats_layer.featureCount() nb_feature_blurred = blurred_layer.featureCount() features_stats = {} label_preparing = tr('Preparing index on the stats layer') label_creating = tr('Creating index on the stats layer') label_calculating = tr('Calculating') if Qgis.QGIS_VERSION_INT < 20700: self.label_progressStats.setText('%s 1/3' % label_preparing) for i, feature in enumerate(stats_layer.getFeatures()): features_stats[feature.id()] = feature percent = int((i + 1) * 100 / nb_feature_stats) self.progressBar_stats.setValue(percent) # noinspection PyArgumentList QApplication.processEvents() self.label_progressStats.setText('%s 2/3' % label_creating) # noinspection PyArgumentList QApplication.processEvents() index = QgsSpatialIndex() for i, f in enumerate(stats_layer.getFeatures()): index.insertFeature(f) percent = int((i + 1) * 100 / nb_feature_stats) self.progressBar_stats.setValue(percent) # noinspection PyArgumentList QApplication.processEvents() self.label_progressStats.setText('%s 3/3' % label_calculating) else: # If QGIS >= 2.7, we can speed up the spatial index. # From 1 min 15 to 7 seconds on my PC. self.label_progressStats.setText('%s 1/2' % label_creating) # noinspection PyArgumentList QApplication.processEvents() index = QgsSpatialIndex(stats_layer.getFeatures()) self.label_progressStats.setText('%s 2/2' % label_calculating) # noinspection PyArgumentList QApplication.processEvents() self.tab = [] for i, feature in enumerate(blurred_layer.getFeatures()): count = 0 ids = index.intersects(feature.geometry().boundingBox()) for unique_id in ids: request = QgsFeatureRequest().setFilterFid(unique_id) f = next(stats_layer.getFeatures(request)) if f.geometry().intersects(feature.geometry()): count += 1 self.tab.append(count) percent = int((i + 1) * 100 / nb_feature_blurred) self.progressBar_stats.setValue(percent) # noinspection PyArgumentList QApplication.processEvents() stats = Stats(self.tab) items_stats = [ 'Count(blurred),%d' % nb_feature_blurred, 'Count(stats),%d' % nb_feature_stats, 'Min,%d' % stats.min(), 'Average,%f' % stats.average(), 'Max,%d' % stats.max(), 'Median,%f' % stats.median(), 'Range,%d' % stats.range(), 'Variance,%f' % stats.variance(), 'Standard deviation,%f' % stats.standard_deviation() ] self.tableWidget.clear() self.tableWidget.setColumnCount(2) labels = ['Parameters', 'Values'] self.tableWidget.setHorizontalHeaderLabels(labels) self.tableWidget.setRowCount(len(items_stats)) for i, item in enumerate(items_stats): s = item.split(',') self.tableWidget.setItem(i, 0, QTableWidgetItem(s[0])) self.tableWidget.setItem(i, 1, QTableWidgetItem(s[1])) self.tableWidget.resizeRowsToContents() self.draw_plot(self.tab) except GeoPublicHealthException as e: self.label_progressStats.setText('') display_message_bar(msg=e.msg, level=e.level, duration=e.duration) def save_table(self): if not self.tableWidget.rowCount(): return False csv_string = 'parameter,values\n' for i in range(self.tableWidget.rowCount()): item_param = self.tableWidget.item(i, 0) item_value = self.tableWidget.item(i, 1) csv_string += \ str(item_param.text()) + ',' + item_value.text() + '\n' last_directory = get_last_input_path() # noinspection PyArgumentList output_file, __ = QFileDialog.getSaveFileName( parent=self, caption=tr('Select file'), directory=last_directory, filter='CSV (*.csv)') if output_file: path = dirname(output_file) set_last_input_path(path) fh = open(output_file, 'w') fh.write(csv_string) fh.close() return True def save_y_values(self): if not self.tableWidget.rowCount(): return False csv_string = 'parameter,values\n' for value in self.tab: csv_string += str(value) + '\n' last_directory = get_last_input_path() # noinspection PyArgumentList output_file, __ = QFileDialog.getSaveFileName( parent=self, caption=tr('Select file'), directory=last_directory, filter='CSV (*.csv)') if output_file: path = dirname(output_file) set_last_input_path(path) fh = open(output_file, 'w') fh.write(csv_string) fh.close() return True def draw_plot(self, data): # Creating the plot # create an axis ax = self.figure.add_subplot(111) # discards the old graph # plot data ax.plot(data, '*-') # ax.set_title('Number of intersections per entity') ax.set_xlabel('Blurred entity') ax.set_ylabel('Number of intersections') ax.grid() # refresh canvas self.canvas.draw()
class Window(QWidget): xgrid=[] data=[] fit=[] rng1=random.SystemRandom() rng2=random.SystemRandom() def __init__(self): super().__init__() #---Control buttons--- self.btnread = QPushButton('Read Data', self) self.btnreset = QPushButton('Reset Fitting', self) self.btnfit1 = QPushButton('Fit 1x', self) self.btnfit100 = QPushButton('Fit 100x', self) self.energy=QLabel("Energy: -, steps: 0",self) layout=QHBoxLayout(self) layout.addWidget(self.btnread) layout.addWidget(self.btnreset) layout.addWidget(self.btnfit1) layout.addWidget(self.btnfit100) layout.addWidget(self.energy) #layout.addStretch() self.control_buttons=QGroupBox() self.control_buttons.setLayout(layout) #------ #---Parameter boxes self.titleBeta = QLabel("Beta",self) self.Beta = QLineEdit("100",self) self.titleA = QLabel("A",self) self.initA = QLineEdit("1",self) self.stepA = QLineEdit("0.1",self) self.titleTau = QLabel("Tau",self) self.initTau = QLineEdit("130",self) self.stepTau = QLineEdit("10",self) self.titleT = QLabel("T",self) self.initT = QLineEdit("200",self) self.stepT = QLineEdit("10",self) layout=QGridLayout(self) layout.addWidget(self.titleBeta,0,0) layout.addWidget(self.Beta,0,1) layout.addWidget(self.titleA,1,0) layout.addWidget(self.initA,1,1) layout.addWidget(self.stepA,1,2) layout.addWidget(self.titleTau,2,0) layout.addWidget(self.initTau,2,1) layout.addWidget(self.stepTau,2,2) layout.addWidget(self.titleT,3,0) layout.addWidget(self.initT,3,1) layout.addWidget(self.stepT,3,2) layout.setColumnStretch(2,0) self.param_boxes=QGroupBox() self.param_boxes.setLayout(layout) #------ #---Main plot--- self.main_plot = plt.figure() self.main_canvas = FigureCanvas(self.main_plot) #------ #---Final layout--- layout=QVBoxLayout(self) layout.addWidget(self.main_canvas) layout.addWidget(self.control_buttons) layout.addWidget(self.param_boxes) layout.addStretch() self.setLayout(layout) self.setWindowTitle('Monte-Carlo fitting') self.show() #------ #---Control button actions--- self.btnread.clicked.connect(self._read_data) self.btnreset.clicked.connect(self._reset) self.btnfit1.clicked.connect(self._fit1) self.btnfit100.clicked.connect(self._fit100) #------ #reads data series from a textfile #required format: xvalue whitespace yvalue newline (for each point) def _read_data(self): #resetting the data and x values arrays and the iteration counter self.cnt=0 self.data=[] self.xgrid=[] self.energy.setText("Energy: -, steps: 0") from PyQt5.QtWidgets import QFileDialog fname=QFileDialog.getOpenFileName()[0] try: fin=open(fname,"r") except FileNotFoundError as e: print("File not found.") return try: for line in fin: self.data.append(float(line.split()[1])) self.xgrid.append(float(line.split()[0])) self._plot_data() except Exception as e: print(e.__class__.__name__+": "+str(e)) print("Invalid file.") self.data=[] self.xgrid=[] fin.close() #draws the data points def _plot_data(self): self.main_plot.clear() ax = self.main_plot.add_subplot(111) ax.plot(self.data, '+') self.main_canvas.draw() #Gets the values from the LineEdits def _getparams(self): #reading the values self.beta=float(self.Beta.text()) self.A=float(self.initA.text()) self.dA=float(self.stepA.text()) self.tau=float(self.initTau.text()) self.dtau=float(self.stepTau.text()) self.T=float(self.initT.text()) self.dT=float(self.stepT.text()) #initializing the array of fitted values and the energy self.E=0 for i in range(len(self.xgrid)): x=self.xgrid[i] self.fit.append(self.A*math.exp(-x/self.tau)*math.sin(2*math.pi*x/self.T)) self.E+=abs(self.data[i]-self.fit[-1]) #Writes the modified parameters back to the LineEdits def _setparams(self): self.initA.setText(str(self.A)) self.initTau.setText(str(self.tau)) self.initT.setText(str(self.T)) #Executes one fitting step def _fit1(self): self.fit=[] try: self._getparams() except Exception as e: print(e.__class__.__name__+": "+str(e)) print("Invalid parameter.") return self._fit() self._plot_fit() self._setparams() #Executes 100 fitting steps def _fit100(self): self.fit=[] try: self._getparams() except Exception as e: print(e.__class__.__name__+": "+str(e)) print("Invalid parameter.") return [self._fit() for i in range(100)] self._plot_fit() self._setparams() def _func(self, A, tau, T): fit=[0] E=0 for i in range(len(self.xgrid)): x=self.xgrid[i] fit.append(A*math.exp(-x/tau)*math.sin(2*math.pi*x/T)) E+=abs(self.data[i]-fit[i]) return fit, E #performs a fitting step def _fit(self): self.cnt+=1 A=self.A+self.dA*(1-2*self.rng1.random()) fit, E = self._func(A, self.tau, self.T) if((E<self.E) or (self.rng2.random()<math.exp(-self.beta*abs(E-self.E)))): self.E=E self.fit=fit self.A=A tau=self.tau+self.dtau*(1-2*self.rng1.random()) fit, E = self._func(self.A, tau, self.T) if((E<self.E) or (self.rng2.random()<math.exp(-self.beta*abs(E-self.E)))): self.E=E self.fit=fit self.tau=tau T=self.T+self.dT*(1-2*self.rng1.random()) fit, E = self._func(self.A, self.tau, T) if((E<self.E) or (self.rng2.random()<math.exp(-self.beta*abs(E-self.E)))): self.E=E self.fit=fit self.T=T #draws the data points and the fitted curve and writes the energy def _plot_fit(self): self.main_plot.clear() ax = self.main_plot.add_subplot(111) ax.plot(self.data, '+') ax.plot(self.fit, '-') self.main_canvas.draw() self.energy.setText("Energy: {:.5E}, steps: {}".format(self.E, self.cnt)) #resets the iteration counter and deletes the fitted curve def _reset(self): self.cnt=0 self._plot_data() self.energy=QLabel("Energy: -, steps: 0",self)
class FS_window(QMainWindow, Ui_MainWindow): def __init__(self, parent=None): #初始化,没有父类 super(FS_window, self).__init__(parent) self.setupUi(self) self.setWindowTitle('基于机器视觉的智慧农药化肥喷洒平台') #给一个窗口标题 self.setStyleSheet("#Main_Window{background-color: white}") self.setStyleSheet("#stackedWidget{background-color: white}") self.train_data.triggered.connect(self.load_traindata) #链接训练数据 self.test_data.triggered.connect(self.load_testdata) #链接测试数据,在界面左上角 self.picture_data.triggered.connect(self.load_picturedata) #链接图片数据 #按钮空间对应界面的不同页面 self.button_reading.clicked.connect( self.topage_1) #一个按钮可以与一个页面(page)连接 self.button_preprocessing.clicked.connect(self.topage_2) self.button_segemation.clicked.connect(self.topage_3) self.button_feature_extraction.clicked.connect(self.topage_4) self.button_classification.clicked.connect(self.topage_8) self.button_color_feature.clicked.connect(self.topage_5) self.button_shape_feature.clicked.connect(self.topage_6) self.button_texture_feature.clicked.connect(self.topage_7) #先让button灰调,也就是按钮按不了。等它前面的步骤都做完了,再亮回来。 #self.button_preprocessing.setEnabled(False) #self.button_segemation.clicked.setEnabled(False) #self.button_feature_extraction.setEnabled(False) #self.button_classification.clicked.setEnabled(False) #self.button_color_feature.clicked.setEnabled(False) #self.button_shape_feature.clicked.setEnabled(False) #self.button_texture_feature.clicked.setEnabled(False) #按钮控件对应函数 self.button_get_picture.clicked.connect( self.get_picture) #和后面的函数连接,也就是我们写的函数 self.button_histogram_equalization.clicked.connect( self.histogram_equalization) self.button_color_segemation.clicked.connect(self.color_segemation) self.button_color_moment.clicked.connect(self.color_moment) #这写函数还未命名 self.button_Hu_invariant_moment.clicked.connect( self.Hu_invariant_moment) self.button_gray_level_co_occurance_matrix.clicked.connect( self.gray_level_co_occurance_matrix) self.button_classifier.clicked.connect(self.adaboost_classifier) ## 画布——对应image(原图) self.fig_image = Figure((7, 5)) # 15, 8这里应该只确定了figsize self.canvas_image = FigureCanvas(self.fig_image) #self.canvas_pca.setParent(self.pca_gongxiantu) self.graphicscene_image = QGraphicsScene() self.graphicscene_image.addWidget(self.canvas_image) self.toolbar_image = NavigationToolbar(self.canvas_image, self.picture_dujuan_1) ## 画布——对应imageH(均衡化后的图) self.fig_imageH = Figure((7, 5)) # 15, 8这里应该只确定了figsize self.canvas_imageH = FigureCanvas(self.fig_imageH) #self.canvas_pca.setParent(self.pca_gongxiantu) self.graphicscene_imageH = QGraphicsScene() self.graphicscene_imageH.addWidget(self.canvas_imageH) self.toolbar_imageH = NavigationToolbar(self.canvas_imageH, self.picture_imageH) ## 画布——对应img_RGB self.fig_img_RGB = Figure((7, 5)) # 15, 8这里应该只确定了figsize self.canvas_img_RGB = FigureCanvas(self.fig_img_RGB) #self.canvas_pca.setParent(self.pca_gongxiantu) self.graphicscene_img_RGB = QGraphicsScene() self.graphicscene_img_RGB.addWidget(self.canvas_img_RGB) self.toolbar_img_RGB = NavigationToolbar(self.canvas_img_RGB, self.picture_img_RGB) #界面切换 def topage_1(self): self.stackedWidget.setCurrentWidget(self.page_1) def topage_2(self): self.stackedWidget.setCurrentWidget(self.page_2) def topage_3(self): self.stackedWidget.setCurrentWidget(self.page_3) def topage_4(self): self.stackedWidget.setCurrentWidget(self.page_4) def topage_5(self): self.stackedWidget_2.setCurrentWidget(self.page_5) def topage_6(self): self.stackedWidget_2.setCurrentWidget(self.page_6) def topage_7(self): self.stackedWidget_2.setCurrentWidget(self.page_7) def topage_8(self): self.stackedWidget.setCurrentWidget(self.page_8) #导入训练数据 def load_traindata(self): try: datafile, _ = QFileDialog.getOpenFileName(self, "选择训练数据") print((datafile)) table = pd.read_csv(datafile) print(table) # table = xlrd.open_workbook(datafile).sheet_by_index(0) nrows = table.shape[0] ncols = table.shape[1] self.trainWidget.setRowCount(nrows) #确定行数 self.trainWidget.setColumnCount(ncols) #确定列数 self.train_data = np.zeros((nrows, ncols)) #设初始值,零矩阵 self.dataArr = np.zeros((nrows, ncols - 1)) self.LabelArr = np.zeros((nrows, 1)) for i in range(nrows): for j in range(ncols): #table.at[i, j] self.trainWidget.setItem( i, j, QTableWidgetItem(str( table.at[i, str(j)]))) #这里的trainWidget是界面的东西 self.train_data[i, j] = table.at[i, str(j)] #把数据一个一个导入进去 for i in range(nrows): for j in range(ncols - 1): self.dataArr[i, j] = self.train_data[i, j] for i in range(nrows): self.LabelArr[i] = self.train_data[i, -1] #print(self.dataArr) #print(self.LabelArr) #print(self.LabelArr.T) self.statusbar.showMessage('训练数据已导入') except: QMessageBox.information(self, 'Warning', '数据为CSV表格', QMessageBox.Ok) #导入测试数据 def load_testdata(self): try: datafile, _ = QFileDialog.getOpenFileName(self, "选择测试数据") table = pd.read_csv(datafile) print(table) nrows = table.shape[0] ncols = table.shape[1] self.testWidget.setRowCount(nrows) self.testWidget.setColumnCount(ncols) self.test_data = np.zeros((nrows, ncols)) self.tsetArr = np.zeros((nrows, ncols - 1)) self.testLabelArr = np.zeros((nrows, 1)) for i in range(nrows): for j in range(ncols): self.testWidget.setItem( i, j, QTableWidgetItem(str(table.at[i, str(j)]))) self.test_data[i, j] = table.at[i, str(j)] self.statusbar.showMessage('测试数据已导入') for i in range(nrows): for j in range(ncols - 1): self.tsetArr[i, j] = self.test_data[i, j] for i in range(nrows): self.testLabelArr[i] = self.test_data[i, -1] except: QMessageBox.information(self, 'Warning', '数据为CSV表格', QMessageBox.Ok) #选择图片 def load_picturedata(self): try: #选择图片 imgName, imgType = QFileDialog.getOpenFileName( self, "打开图片", "img", "*.jpg;*.tif;*.png;;All Files(*)") if imgName == "": return 0 self.img = cv2.imread(imgName) #qt5读取图片 #self.jpg = QPixmap(imgName).scaled(self.picture_dujuan_1.width(), self.picture_dujuan_1.height()) except: QMessageBox.information(self, 'Warning', '导入失败', QMessageBox.Ok) def get_picture(self): try: # img=cv2.imread("dujuan_1.jpg") #img=cv2.cvtColor(self.jpg,cv2.COLOR_RGB2BGR) # gray=cv2.cvtColor(self.img,cv2.COLOR_BGR2GRAY) # 修改原图的尺寸 fx = 0.3 fy = 0.3 self.image = cv2.resize(self.img, dsize=None, fx=fx, fy=fy, interpolation=cv2.INTER_AREA) self.fig_image.clear() plt = self.fig_image.add_subplot(111) plt.imshow(cv2.cvtColor(self.image, cv2.COLOR_BGR2RGB)) self.canvas_image.draw() self.picture_dujuan_1.setScene(self.graphicscene_image) self.picture_dujuan_1.show() #self.button_preprocessing.setEnabled(True) except: QMessageBox.information(self, 'Warning', '绘制图片的时候出错', QMessageBox.Ok) def histogram_equalization(self): (b, g, r) = cv2.split(self.image) bH = cv2.equalizeHist(b) gH = cv2.equalizeHist(g) rH = cv2.equalizeHist(r) self.imageH = cv2.merge((bH, gH, rH)) self.fig_imageH.clear() plt = self.fig_imageH.add_subplot(111) plt.imshow(cv2.cvtColor(self.imageH, cv2.COLOR_BGR2RGB)) self.canvas_imageH.draw() self.picture_imageH.setScene(self.graphicscene_imageH) self.picture_imageH.show() #self.button_segemation.clicked.setEnabled(True) def color_segemation(self): #基于H分量的双阈值分割 HSV_img = cv2.cvtColor(self.imageH, cv2.COLOR_BGR2HSV) hue = HSV_img[:, :, 0] lower_gray = np.array([1, 0, 0]) upper_gray = np.array([99, 255, 255]) mask = cv2.inRange(HSV_img, lower_gray, upper_gray) # Bitwise-AND mask and original image res2 = cv2.bitwise_and(self.imageH, self.imageH, mask=mask) # 先将这张图进行二值化 ret1, thresh1 = cv2.threshold(res2, 0, 255, cv2.THRESH_BINARY) # 然后是进行形态学操作 # 我们采用矩形核(10,10)进行闭运算 kernel_1 = cv2.getStructuringElement(cv2.MORPH_RECT, (10, 10)) closing = cv2.morphologyEx(thresh1, cv2.MORPH_CLOSE, kernel_1) # 对原图进行RGB三通道分离 (B, G, R) = cv2.split(self.image) #之前得到的图 # 三个通道分别和closing这个模板进行与运算 mask = cv2.cvtColor(closing, cv2.COLOR_BGR2GRAY) and_img_B = cv2.bitwise_and(B, mask) and_img_G = cv2.bitwise_and(G, mask) and_img_R = cv2.bitwise_and(R, mask) # 多通道图像进行混合 zeros = np.zeros(res2.shape[:2], np.uint8) img_RGB = cv2.merge([and_img_R, and_img_G, and_img_B]) # 下面我先用closing的结果,进一步进行处理 # 这个颜色空间转来转去的,要小心 img_BGR = cv2.cvtColor(img_RGB, cv2.COLOR_RGB2BGR) #这个颜色空间转来转去的,要小心 HSV_img = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2HSV) hue = HSV_img[:, :, 0] lower_gray = np.array([1, 0, 0]) upper_gray = np.array([99, 255, 255]) mask = cv2.inRange(HSV_img, lower_gray, upper_gray) # Bitwise-AND mask and original image self.result = cv2.bitwise_and(img_BGR, img_BGR, mask=mask) self.fig_img_RGB.clear() plt = self.fig_img_RGB.add_subplot(111) plt.imshow(cv2.cvtColor(self.result, cv2.COLOR_BGR2RGB)) self.canvas_img_RGB.draw() self.picture_img_RGB.setScene(self.graphicscene_img_RGB) self.picture_img_RGB.show() #self.button_feature_extraction.setEnabled(True) #self.button_color_feature.clicked.setEnabled(True) #self.button_shape_feature.clicked.setEnabled(True) #self.button_texture_feature.clicked.setEnabled(True) def color_moment(self): try: # Convert BGR to HSV colorspace hsv = cv2.cvtColor(self.image, cv2.COLOR_BGR2HSV) # Split the channels - h,s,v h, s, v = cv2.split(hsv) # Initialize the color feature color_feature = [] # N = h.shape[0] * h.shape[1] # The first central moment - average h_mean = np.mean(h) # np.sum(h)/float(N) s_mean = np.mean(s) # np.sum(s)/float(N) v_mean = np.mean(v) # np.sum(v)/float(N) color_feature.extend([h_mean, s_mean, v_mean]) # The second central moment - standard deviation h_std = np.std(h) # np.sqrt(np.mean(abs(h - h.mean())**2)) s_std = np.std(s) # np.sqrt(np.mean(abs(s - s.mean())**2)) v_std = np.std(v) # np.sqrt(np.mean(abs(v - v.mean())**2)) color_feature.extend([h_std, s_std, v_std]) # The third central moment - the third root of the skewness h_skewness = np.mean(abs(h - h.mean())**3) s_skewness = np.mean(abs(s - s.mean())**3) v_skewness = np.mean(abs(v - v.mean())**3) h_thirdMoment = h_skewness**(1. / 3) s_thirdMoment = s_skewness**(1. / 3) v_thirdMoment = v_skewness**(1. / 3) color_feature.extend([h_thirdMoment, s_thirdMoment, v_thirdMoment]) self.lineEdit_H_first.setText(str(color_feature[0])) self.lineEdit_H_second.setText(str(color_feature[1])) self.lineEdit_H_third.setText(str(color_feature[2])) self.lineEdit_S_first.setText(str(color_feature[3])) self.lineEdit_S_second.setText(str(color_feature[4])) self.lineEdit_S_third.setText(str(color_feature[5])) self.lineEdit_V_first.setText(str(color_feature[6])) self.lineEdit_V_second.setText(str(color_feature[7])) self.lineEdit_V_third.setText(str(color_feature[8])) except: QMessageBox.information(self, 'Warning', '提取颜色矩出错', QMessageBox.Ok) def Hu_invariant_moment(self): try: seg = self.result seg_gray = cv2.cvtColor(seg, cv2.COLOR_BGR2GRAY) moments = cv2.moments(seg_gray) humoments = cv2.HuMoments(moments) humoments = np.log(np.abs(humoments)) # 同样建议取对数 self.fai_1.setText(str(humoments[0])) self.fai_2.setText(str(humoments[1])) self.fai_3.setText(str(humoments[2])) self.fai_4.setText(str(humoments[3])) self.fai_5.setText(str(humoments[4])) self.fai_6.setText(str(humoments[5])) self.fai_7.setText(str(humoments[6])) except: QMessageBox.information(self, 'Warning', '提取颜色矩出错', QMessageBox.Ok) def gray_level_co_occurance_matrix(self): try: img_shape = self.result.shape resized_img = cv2.resize( self.result, (int(img_shape[1] / 2), int(img_shape[0] / 2)), interpolation=cv2.INTER_CUBIC) img_gray = cv2.cvtColor(resized_img, cv2.COLOR_BGR2GRAY) gray_level = 16 #之前的getGlcm(self,img_gray,d_x,d_y) d_x = 0 d_y = 1 srcdata = img_gray.copy() p = [[0.0 for i in range(gray_level)] for j in range(gray_level)] (height, width) = img_gray.shape #以前的maxGrayLevel(img) max_gray_level = 0 (height, width) = img_gray.shape #print(height,width) for y in range(height): for x in range(width): if img_gray[y][x] > max_gray_level: max_gray_level = img_gray[y][x] max_gray_level = max_gray_level + 1 #若灰度级数大于gray_level,则将图像的灰度级缩小至gray_level,减小灰度共生矩阵的大小 if max_gray_level > gray_level: for j in range(height): for i in range(width): srcdata[j][ i] = srcdata[j][i] * gray_level / max_gray_level for j in range(height - d_y): for i in range(width - d_x): rows = srcdata[j][i] cols = srcdata[j + d_y][i + d_x] p[rows][cols] += 1.0 for i in range(gray_level): for j in range(gray_level): p[i][j] /= float(height * width) #之前的feature_computer() con = 0.0 eng = 0.0 asm = 0.0 idm = 0.0 for i in range(gray_level): for j in range(gray_level): con += (i - j) * (i - j) * p[i][j] asm += p[i][j] * p[i][j] idm += p[i][j] / (1 + (i - j) * (i - j)) if p[i][j] > 0.0: eng -= p[i][j] * math.log(p[i][j]) self.energy_1.setText(str(asm)) self.entrophy_1.setText(str(eng)) self.contrast_ratio.setText(str(con)) self.inverse_variance.setText(str(idm)) except: QMessageBox.information(self, 'Warning', '提取灰度共生矩阵出错', QMessageBox.Ok) @staticmethod def stumpClassify(dataMatrix, dimen, threshVal, threshIneq): """ 单层决策树分类函数 Parameters: dataMatrix - 数据矩阵 dimen - 第dimen列,也就是第几个特征 threshVal - 阈值 threshIneq - 标志 Returns: retArray - 分类结果 """ retArray = np.ones((np.shape(dataMatrix)[0], 1)) # 初始化retArray为1 if threshIneq == 'lt': retArray[ dataMatrix[:, dimen] <= threshVal] = -1.0 # 如果小于阈值,则赋值为-1 else: retArray[dataMatrix[:, dimen] > threshVal] = -1.0 # 如果大于阈值,则赋值为-1 return retArray @staticmethod def buildStump(dataArr, classLabels, D): """ 找到数据集上最佳的单层决策树 Parameters: dataArr - 数据矩阵 classLabels - 数据标签 D - 样本权重 Returns: bestStump - 最佳单层决策树信息 minError - 最小误差 bestClasEst - 最佳的分类结果 """ dataMatrix = np.mat(dataArr) labelMat = np.mat(classLabels).T m, n = np.shape(dataMatrix) numSteps = 10.0 bestStump = {} bestClasEst = np.mat(np.zeros((m, 1))) minError = float('inf') # 最小误差初始化为正无穷大 for i in range(n): # 遍历所有特征 rangeMin = dataMatrix[:, i].min() rangeMax = dataMatrix[:, i].max() # 找到特征中最小的值和最大值 stepSize = (rangeMax - rangeMin) / numSteps # 计算步长 for j in range(-1, int(numSteps) + 1): for inequal in [ 'lt', 'gt' ]: # 大于和小于的情况,均遍历。lt:less than,gt:greater than threshVal = (rangeMin + float(j) * stepSize) # 计算阈值 predictedVals = FS_window.stumpClassify( dataMatrix, i, threshVal, inequal) # 计算分类结果 errArr = np.mat(np.ones((m, 1))) # 初始化误差矩阵 errArr[predictedVals == labelMat] = 0 # 分类正确的,赋值为0 weightedError = D.T * errArr # 计算误差 # print("split: dim %d, thresh %.2f, thresh ineqal: %s, the weighted error is %.3f" % (i, threshVal, inequal, weightedError)) if weightedError < minError: # 找到误差最小的分类方式 minError = weightedError bestClasEst = predictedVals.copy() bestStump['dim'] = i bestStump['thresh'] = threshVal bestStump['ineq'] = inequal return bestStump, minError, bestClasEst # def adaboost_classifier(self): # try: # weakClassArr = [] # m = np.shape(self.dataArr)[0] # D = np.mat(np.ones((m, 1)) / m) # 初始化权重 # aggClassEst = np.mat(np.zeros((m, 1))) # numIt = 40 # for i in range(numIt): # # bestStump, error, classEst = buildStump(self.dataArr, self.LabelArr, D) #构建单层决策树 # # dataMatrix = np.mat(self.dataArr); # labelMat = np.mat(self.LabelArr).T # m, n = np.shape(dataMatrix) # numSteps = 10.0; # bestStump = {}; # bestClasEst = np.mat(np.zeros((m, 1))) # minError = float('inf') # 最小误差初始化为正无穷大 # for i in range(n): # 遍历所有特征 # rangeMin = dataMatrix[:, i].min(); # rangeMax = dataMatrix[:, i].max() # 找到特征中最小的值和最大值 # stepSize = (rangeMax - rangeMin) / numSteps # 计算步长 # for j in range(-1, int(numSteps) + 1): # for inequal in ['lt', 'gt']: # 大于和小于的情况,均遍历。lt:less than,gt:greater than # threshVal = (rangeMin + float(j) * stepSize) # 计算阈值 # # predictedVals = stumpClassify(dataMatrix, i, threshVal, inequal)#计算分类结果 # dimen = i # threshIneq = inequal # retArray = np.ones((np.shape(dataMatrix)[0], 1)) # 初始化retArray为1 # if threshIneq == 'lt': # retArray[dataMatrix[:, dimen] <= threshVal] = -1.0 # 如果小于阈值,则赋值为-1 # else: # retArray[dataMatrix[:, dimen] > threshVal] = -1.0 # # predictedVals = retArray # errArr = np.mat(np.ones((m, 1))) # 初始化误差矩阵 # errArr[predictedVals == labelMat] = 0 # 分类正确的,赋值为0 # weightedError = D.T * errArr # 计算误差 # # print("split: dim %d, thresh %.2f, thresh ineqal: %s, the weighted error is %.3f" % (i, threshVal, inequal, weightedError)) # if weightedError < minError: # 找到误差最小的分类方式 # minError = weightedError # bestClasEst = predictedVals.copy() # bestStump['dim'] = i # bestStump['thresh'] = threshVal # bestStump['ineq'] = inequal # error = minError # classEst = bestClasEst # alpha = float(0.5 * np.log((1.0 - error) / max(error, 1e-16))) # 计算弱学习算法权重alpha,使error不等于0,因为分母不能为0 # bestStump['alpha'] = alpha # 存储弱学习算法权重 # weakClassArr.append(bestStump) # 存储单层决策树 # # print("classEst: ", classEst.T) # expon = np.multiply(-1 * alpha * np.mat(self.LabelArr).T, classEst) # 计算e的指数项 # D = np.multiply(D, np.exp(expon)) # D = D / D.sum() # 根据样本权重公式,更新样本权重 # # 计算AdaBoost误差,当误差为0的时候,退出循环 # aggClassEst += alpha * classEst # 计算类别估计累计值 # # print("aggClassEst: ", aggClassEst.T) # aggErrors = np.multiply(np.sign(aggClassEst) != np.mat(self.LabelArr).T, np.ones((m, 1))) # 计算误差 # errorRate = aggErrors.sum() / m # # print("total error: ", errorRate) # if errorRate == 0.0: break # # # predictions = adaClassify(dataArr, weakClassArr) # datToClass = self.dataArr # classifierArr = self.weakClassArr # dataMatrix = np.mat(datToClass) # m = np.shape(dataMatrix)[0] # aggClassEst = np.mat(np.zeros((m, 1))) # for i in range(len(classifierArr)): # 遍历所有分类器,进行分类 # classEst = stumpClassify(dataMatrix, classifierArr[i]['dim'], classifierArr[i]['thresh'], # classifierArr[i]['ineq']) # aggClassEst += classifierArr[i]['alpha'] * classEst # # print(aggClassEst) # predictions = np.sign(aggClassEst) # # errArr = np.mat(np.ones((len(self.dataArr), 1))) # print('训练集的错误率:%.3f%%' % float( # errArr[predictions != np.mat(self.LabelArr).T].sum() / len(self.dataArr) * 100)) # # predictions = adaClassify(testArr, weakClassArr) # datToClass = self.testArr # classifierArr = self.weakClassArr # dataMatrix = np.mat(datToClass) # m = np.shape(dataMatrix)[0] # aggClassEst = np.mat(np.zeros((m, 1))) # for i in range(len(classifierArr)): # 遍历所有分类器,进行分类 # classEst = stumpClassify(dataMatrix, classifierArr[i]['dim'], classifierArr[i]['thresh'], # classifierArr[i]['ineq']) # aggClassEst += classifierArr[i]['alpha'] * classEst # # print(aggClassEst) # predictions = np.sign(aggClassEst) # # errArr = np.mat(np.ones((len(self.testArr), 1))) # print('测试集的错误率:%.3f%%' % float( # errArr[predictions != np.mat(self.testLabelArr).T].sum() / len(self.testArr) * 100)) # # # except: # QMessageBox.information(self, 'Warning', '构建分类器出错', QMessageBox.Ok) #def adaBoostTrainDS(self): def adaboost_classifier(self): """ 使用AdaBoost算法提升弱分类器性能 Parameters: dataArr - 数据矩阵 classLabels - 数据标签 numIt - 最大迭代次数 Returns: weakClassArr - 训练好的分类器 aggClassEst - 类别估计累计值 """ try: weakClassArr = [] m = np.shape(self.dataArr)[0] D = np.mat(np.ones((m, 1)) / m) # 初始化权重 aggClassEst = np.mat(np.zeros((m, 1))) numIt = 40 for i in range(numIt): bestStump, error, classEst = FS_Window.buildStump( self.dataArr, self.classLabels, D) # 构建单层决策树 # print("D:",D.T) alpha = float(0.5 * np.log( (1.0 - error) / max(error, 1e-16)) ) # 计算弱学习算法权重alpha,使error不等于0,因为分母不能为0 bestStump['alpha'] = alpha # 存储弱学习算法权重 weakClassArr.append(bestStump) # 存储单层决策树 # print("classEst: ", classEst.T) expon = np.multiply(-1 * alpha * np.mat(self.classLabels).T, classEst) # 计算e的指数项 D = np.multiply(D, np.exp(expon)) D = D / D.sum() # 根据样本权重公式,更新样本权重 # 计算AdaBoost误差,当误差为0的时候,退出循环 aggClassEst += alpha * classEst # 计算类别估计累计值 # print("aggClassEst: ", aggClassEst.T) aggErrors = np.multiply( np.sign(aggClassEst) != np.mat(self.classLabels).T, np.ones((m, 1))) # 计算误差 errorRate = aggErrors.sum() / m # print("total error: ", errorRate) if errorRate == 0.0: break # 误差为0,退出循环 return weakClassArr, aggClassEst except: QMessageBox.information(self, 'Warning', '构建分类器出错', QMessageBox.Ok)
class VNA(QMainWindow, Ui_VNA): max_size = 16384 def __init__(self): super(VNA, self).__init__() self.setupUi(self) # IP address validator rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$') self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue)) # state variables self.idle = True self.reading = False # sweep parameters self.sweep_start = 100 self.sweep_stop = 60000 self.sweep_size = 600 self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True) self.xaxis *= 1000 # buffer and offset for the incoming samples self.buffer = bytearray(24 * VNA.max_size) self.offset = 0 self.data = np.frombuffer(self.buffer, np.complex64) self.adc1 = np.zeros(VNA.max_size, np.complex64) self.adc2 = np.zeros(VNA.max_size, np.complex64) self.dac1 = np.zeros(VNA.max_size, np.complex64) self.open = np.zeros(VNA.max_size, np.complex64) self.short = np.zeros(VNA.max_size, np.complex64) self.load = np.zeros(VNA.max_size, np.complex64) self.dut = np.zeros(VNA.max_size, np.complex64) self.mode = 'dut' # create figure self.figure = Figure() self.figure.set_facecolor('none') self.canvas = FigureCanvas(self.figure) self.plotLayout.addWidget(self.canvas) # create navigation toolbar self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False) # initialize cursor self.cursor = None # remove subplots action actions = self.toolbar.actions() self.toolbar.removeAction(actions[7]) self.plotLayout.addWidget(self.toolbar) # create TCP socket self.socket = QTcpSocket(self) self.socket.connected.connect(self.connected) self.socket.readyRead.connect(self.read_data) self.socket.error.connect(self.display_error) # connect signals from buttons and boxes self.sweepFrame.setEnabled(False) self.dutSweep.setEnabled(False) self.connectButton.clicked.connect(self.start) self.writeButton.clicked.connect(self.write_cfg) self.readButton.clicked.connect(self.read_cfg) self.openSweep.clicked.connect(self.sweep_open) self.shortSweep.clicked.connect(self.sweep_short) self.loadSweep.clicked.connect(self.sweep_load) self.dutSweep.clicked.connect(self.sweep_dut) self.csvButton.clicked.connect(self.write_csv) self.s1pButton.clicked.connect(self.write_s1p) self.s2pButton.clicked.connect(self.write_s2p) self.startValue.valueChanged.connect(self.set_start) self.stopValue.valueChanged.connect(self.set_stop) self.sizeValue.valueChanged.connect(self.set_size) self.rateValue.addItems(['500', '100', '50', '10', '5', '1']) self.rateValue.lineEdit().setReadOnly(True) self.rateValue.lineEdit().setAlignment(Qt.AlignRight) for i in range(0, self.rateValue.count()): self.rateValue.setItemData(i, Qt.AlignRight, Qt.TextAlignmentRole) self.rateValue.currentIndexChanged.connect(self.set_rate) self.corrValue.valueChanged.connect(self.set_corr) self.levelValue.valueChanged.connect(self.set_level) self.openPlot.clicked.connect(self.plot_open) self.shortPlot.clicked.connect(self.plot_short) self.loadPlot.clicked.connect(self.plot_load) self.dutPlot.clicked.connect(self.plot_dut) self.smithPlot.clicked.connect(self.plot_smith) self.impPlot.clicked.connect(self.plot_imp) self.rcPlot.clicked.connect(self.plot_rc) self.swrPlot.clicked.connect(self.plot_swr) self.rlPlot.clicked.connect(self.plot_rl) self.gainPlot.clicked.connect(self.plot_gain) # create timer self.startTimer = QTimer(self) self.startTimer.timeout.connect(self.timeout) def start(self): if self.idle: self.connectButton.setEnabled(False) self.socket.connectToHost(self.addrValue.text(), 1001) self.startTimer.start(5000) else: self.stop() def stop(self): self.idle = True self.socket.abort() self.connectButton.setText('Connect') self.connectButton.setEnabled(True) self.sweepFrame.setEnabled(False) self.selectFrame.setEnabled(True) self.dutSweep.setEnabled(False) def timeout(self): self.display_error('timeout') def connected(self): self.startTimer.stop() self.idle = False self.set_start(self.startValue.value()) self.set_stop(self.stopValue.value()) self.set_size(self.sizeValue.value()) self.set_rate(self.rateValue.currentIndex()) self.set_corr(self.corrValue.value()) self.set_level(self.levelValue.value()) self.connectButton.setText('Disconnect') self.connectButton.setEnabled(True) self.sweepFrame.setEnabled(True) self.dutSweep.setEnabled(True) def read_data(self): if not self.reading: self.socket.readAll() return size = self.socket.bytesAvailable() self.progress.setValue((self.offset + size) / 24) limit = 24 * (self.sweep_size + 1) if self.offset + size < limit: self.buffer[self.offset:self.offset + size] = self.socket.read(size) self.offset += size else: self.buffer[self.offset:limit] = self.socket.read(limit - self.offset) self.adc1 = self.data[0::3] self.adc2 = self.data[1::3] self.dac1 = self.data[2::3] getattr(self, self.mode)[0:self.sweep_size] = self.adc1[1:self.sweep_size + 1] / self.dac1[1:self.sweep_size + 1] getattr(self, 'plot_%s' % self.mode)() self.reading = False self.sweepFrame.setEnabled(True) self.selectFrame.setEnabled(True) def display_error(self, socketError): self.startTimer.stop() if socketError == 'timeout': QMessageBox.information(self, 'VNA', 'Error: connection timeout.') else: QMessageBox.information(self, 'VNA', 'Error: %s.' % self.socket.errorString()) self.stop() def set_start(self, value): self.sweep_start = value self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True) self.xaxis *= 1000 if self.idle: return self.socket.write(struct.pack('<I', 0<<28 | int(value * 1000))) def set_stop(self, value): self.sweep_stop = value self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True) self.xaxis *= 1000 if self.idle: return self.socket.write(struct.pack('<I', 1<<28 | int(value * 1000))) def set_size(self, value): self.sweep_size = value self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True) self.xaxis *= 1000 if self.idle: return self.socket.write(struct.pack('<I', 2<<28 | int(value))) def set_rate(self, value): if self.idle: return rate = [1, 5, 10, 50, 100, 500][value] self.socket.write(struct.pack('<I', 3<<28 | int(rate))) def set_corr(self, value): if self.idle: return self.socket.write(struct.pack('<I', 4<<28 | int(value))) def set_level(self, value): if self.idle: return self.socket.write(struct.pack('<I', 5<<28 | int(32767 * np.power(10.0, value / 20.0)))) def sweep(self): if self.idle: return self.sweepFrame.setEnabled(False) self.selectFrame.setEnabled(False) self.socket.write(struct.pack('<I', 6<<28)) self.offset = 0 self.reading = True self.progress = QProgressDialog('Sweep status', 'Cancel', 0, self.sweep_size + 1) self.progress.setModal(True) self.progress.setMinimumDuration(1000) self.progress.canceled.connect(self.cancel) def cancel(self): self.offset = 0 self.reading = False self.socket.write(struct.pack('<I', 7<<28)) self.sweepFrame.setEnabled(True) self.selectFrame.setEnabled(True) def sweep_open(self): self.mode = 'open' self.sweep() def sweep_short(self): self.mode = 'short' self.sweep() def sweep_load(self): self.mode = 'load' self.sweep() def sweep_dut(self): self.mode = 'dut' self.sweep() def gain(self): size = self.sweep_size return self.dut[0:size]/self.short[0:size] def impedance(self): size = self.sweep_size return 50.0 * (self.open[0:size] - self.load[0:size]) * (self.dut[0:size] - self.short[0:size]) / ((self.load[0:size] - self.short[0:size]) * (self.open[0:size] - self.dut[0:size])) def gamma(self): z = self.impedance() return (z - 50.0)/(z + 50.0) def plot_gain(self): if self.cursor is not None: self.cursor.hide().disable() matplotlib.rcdefaults() self.figure.clf() self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98) axes1 = self.figure.add_subplot(111) axes1.cla() axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix)) axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix)) axes1.tick_params('y', color = 'blue', labelcolor = 'blue') axes1.yaxis.label.set_color('blue') gain = self.gain() axes1.plot(self.xaxis, 20.0 * np.log10(np.absolute(gain)), color = 'blue', label = 'Gain') axes2 = axes1.twinx() axes2.spines['left'].set_color('blue') axes2.spines['right'].set_color('red') axes1.set_xlabel('Hz') axes1.set_ylabel('Gain, dB') axes2.set_ylabel('Phase angle') axes2.tick_params('y', color = 'red', labelcolor = 'red') axes2.yaxis.label.set_color('red') axes2.plot(self.xaxis, np.angle(gain, deg = True), color = 'red', label = 'Phase angle') self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple') self.canvas.draw() def plot_magphase(self, data): if self.cursor is not None: self.cursor.hide().disable() matplotlib.rcdefaults() self.figure.clf() self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98) axes1 = self.figure.add_subplot(111) axes1.cla() axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix)) axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix)) axes1.tick_params('y', color = 'blue', labelcolor = 'blue') axes1.yaxis.label.set_color('blue') axes1.plot(self.xaxis, np.absolute(data), color = 'blue', label = 'Magnitude') axes2 = axes1.twinx() axes2.spines['left'].set_color('blue') axes2.spines['right'].set_color('red') axes1.set_xlabel('Hz') axes1.set_ylabel('Magnitude') axes2.set_ylabel('Phase angle') axes2.tick_params('y', color = 'red', labelcolor = 'red') axes2.yaxis.label.set_color('red') axes2.plot(self.xaxis, np.angle(data, deg = True), color = 'red', label = 'Phase angle') self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple') self.canvas.draw() def plot_open(self): self.plot_magphase(self.open[0:self.sweep_size]) def plot_short(self): self.plot_magphase(self.short[0:self.sweep_size]) def plot_load(self): self.plot_magphase(self.load[0:self.sweep_size]) def plot_dut(self): self.plot_magphase(self.dut[0:self.sweep_size]) def plot_smith_grid(self, axes, color): load = 50.0 ticks = np.array([0.0, 0.2, 0.5, 1.0, 2.0, 5.0]) for tick in ticks * load: axis = np.logspace(-4, np.log10(1.0e3), 200) * load z = tick + 1.0j * axis gamma = (z - load)/(z + load) axes.plot(gamma.real, gamma.imag, color = color, linewidth = 0.4, alpha = 0.3) axes.plot(gamma.real, -gamma.imag, color = color, linewidth = 0.4, alpha = 0.3) z = axis + 1.0j * tick gamma = (z - load)/(z + load) axes.plot(gamma.real, gamma.imag, color = color, linewidth = 0.4, alpha = 0.3) axes.plot(gamma.real, -gamma.imag, color = color, linewidth = 0.4, alpha = 0.3) if tick == 0.0: axes.text(1.0, 0.0, u'\u221E', color = color, ha = 'left', va = 'center', clip_on = True, fontsize = 18.0) axes.text(-1.0, 0.0, u'0\u03A9', color = color, ha = 'left', va = 'bottom', clip_on = True, fontsize = 12.0) continue lab = u'%d\u03A9' % tick x = (tick - load) / (tick + load) axes.text(x, 0.0, lab, color = color, ha = 'left', va = 'bottom', clip_on = True, fontsize = 12.0) lab = u'j%d\u03A9' % tick z = 1.0j * tick gamma = (z - load)/(z + load) * 1.05 x = gamma.real y = gamma.imag angle = np.angle(gamma) * 180.0 / np.pi - 90.0 axes.text(x, y, lab, color = color, ha = 'center', va = 'center', clip_on = True, rotation = angle, fontsize = 12.0) lab = u'-j%d\u03A9' % tick axes.text(x, -y, lab, color = color, ha = 'center', va = 'center', clip_on = True, rotation = -angle, fontsize = 12.0) def plot_smith(self): if self.cursor is not None: self.cursor.hide().disable() matplotlib.rcdefaults() self.figure.clf() self.figure.subplots_adjust(left = 0.0, bottom = 0.0, right = 1.0, top = 1.0) axes1 = self.figure.add_subplot(111) self.plot_smith_grid(axes1, 'blue') gamma = self.gamma() plot, = axes1.plot(gamma.real, gamma.imag, color = 'red') axes1.axis('equal') axes1.set_xlim(-1.12, 1.12) axes1.set_ylim(-1.12, 1.12) axes1.xaxis.set_visible(False) axes1.yaxis.set_visible(False) for loc, spine in axes1.spines.items(): spine.set_visible(False) self.cursor = datacursor(plot, formatter = SmithFormatter(self.xaxis), display = 'multiple') self.canvas.draw() def plot_imp(self): self.plot_magphase(self.impedance()) def plot_rc(self): self.plot_magphase(self.gamma()) def plot_swr(self): if self.cursor is not None: self.cursor.hide().disable() matplotlib.rcdefaults() self.figure.clf() self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98) axes1 = self.figure.add_subplot(111) axes1.cla() axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix)) axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix)) axes1.set_xlabel('Hz') axes1.set_ylabel('SWR') magnitude = np.absolute(self.gamma()) swr = np.maximum(1.0, np.minimum(100.0, (1.0 + magnitude) / np.maximum(1.0e-20, 1.0 - magnitude))) axes1.plot(self.xaxis, swr, color = 'blue', label = 'SWR') self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple') self.canvas.draw() def plot_rl(self): if self.cursor is not None: self.cursor.hide().disable() matplotlib.rcdefaults() self.figure.clf() self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98) axes1 = self.figure.add_subplot(111) axes1.cla() axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix)) axes1.set_xlabel('Hz') axes1.set_ylabel('Return loss, dB') magnitude = np.absolute(self.gamma()) axes1.plot(self.xaxis, 20.0 * np.log10(magnitude), color = 'blue', label = 'Return loss') self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple') self.canvas.draw() def write_cfg(self): dialog = QFileDialog(self, 'Write configuration settings', '.', '*.ini') dialog.setDefaultSuffix('ini') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() settings = QSettings(name[0], QSettings.IniFormat) self.write_cfg_settings(settings) def read_cfg(self): dialog = QFileDialog(self, 'Read configuration settings', '.', '*.ini') dialog.setDefaultSuffix('ini') dialog.setAcceptMode(QFileDialog.AcceptOpen) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() settings = QSettings(name[0], QSettings.IniFormat) self.read_cfg_settings(settings) def write_cfg_settings(self, settings): settings.setValue('addr', self.addrValue.text()) settings.setValue('start', self.startValue.value()) settings.setValue('stop', self.stopValue.value()) settings.setValue('rate', self.rateValue.currentIndex()) settings.setValue('corr', self.corrValue.value()) size = self.sizeValue.value() settings.setValue('size', size) for i in range(0, size): settings.setValue('open_real_%d' % i, float(self.open.real[i])) settings.setValue('open_imag_%d' % i, float(self.open.imag[i])) for i in range(0, size): settings.setValue('short_real_%d' % i, float(self.short.real[i])) settings.setValue('short_imag_%d' % i, float(self.short.imag[i])) for i in range(0, size): settings.setValue('load_real_%d' % i, float(self.load.real[i])) settings.setValue('load_imag_%d' % i, float(self.load.imag[i])) for i in range(0, size): settings.setValue('dut_real_%d' % i, float(self.dut.real[i])) settings.setValue('dut_imag_%d' % i, float(self.dut.imag[i])) def read_cfg_settings(self, settings): self.addrValue.setText(settings.value('addr', '192.168.1.100')) self.startValue.setValue(settings.value('start', 100, type = int)) self.stopValue.setValue(settings.value('stop', 60000, type = int)) self.rateValue.setCurrentIndex(settings.value('rate', 0, type = int)) self.corrValue.setValue(settings.value('corr', 0, type = int)) size = settings.value('size', 600, type = int) self.sizeValue.setValue(size) for i in range(0, size): real = settings.value('open_real_%d' % i, 0.0, type = float) imag = settings.value('open_imag_%d' % i, 0.0, type = float) self.open[i] = real + 1.0j * imag for i in range(0, size): real = settings.value('short_real_%d' % i, 0.0, type = float) imag = settings.value('short_imag_%d' % i, 0.0, type = float) self.short[i] = real + 1.0j * imag for i in range(0, size): real = settings.value('load_real_%d' % i, 0.0, type = float) imag = settings.value('load_imag_%d' % i, 0.0, type = float) self.load[i] = real + 1.0j * imag for i in range(0, size): real = settings.value('dut_real_%d' % i, 0.0, type = float) imag = settings.value('dut_imag_%d' % i, 0.0, type = float) self.dut[i] = real + 1.0j * imag def write_csv(self): dialog = QFileDialog(self, 'Write csv file', '.', '*.csv') dialog.setDefaultSuffix('csv') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() fh = open(name[0], 'w') gamma = self.gamma() size = self.sizeValue.value() fh.write('frequency;open.real;open.imag;short.real;short.imag;load.real;load.imag;dut.real;dut.imag\n') for i in range(0, size): fh.write('0.0%.8d;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f\n' % (self.xaxis[i], self.open.real[i], self.open.imag[i], self.short.real[i], self.short.imag[i], self.load.real[i], self.load.imag[i], self.dut.real[i], self.dut.imag[i])) fh.close() def write_s1p(self): dialog = QFileDialog(self, 'Write s1p file', '.', '*.s1p') dialog.setDefaultSuffix('s1p') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() fh = open(name[0], 'w') gamma = self.gamma() size = self.sizeValue.value() fh.write('# GHz S MA R 50\n') for i in range(0, size): fh.write('0.0%.8d %8.6f %7.2f\n' % (self.xaxis[i], np.absolute(gamma[i]), np.angle(gamma[i], deg = True))) fh.close() def write_s2p(self): dialog = QFileDialog(self, 'Write s2p file', '.', '*.s2p') dialog.setDefaultSuffix('s2p') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() fh = open(name[0], 'w') gain = self.gain() gamma = self.gamma() size = self.sizeValue.value() fh.write('# GHz S MA R 50\n') for i in range(0, size): fh.write('0.0%.8d %8.6f %7.2f %8.6f %7.2f 0.000000 0.00 0.000000 0.00\n' % (self.xaxis[i], np.absolute(gamma[i]), np.angle(gamma[i], deg = True), np.absolute(gain[i]), np.angle(gain[i], deg = True))) fh.close()
class App(QMainWindow): def __init__(self): super(App, self).__init__() self.title = 'Histogram Equalization' top = 100 left = 100 width = 680 height = 500 self.setGeometry(top, left, width, height) self.inputLoaded = None self.targetLoaded = None # a figure instance to plot on self.figure = Figure() # Canvas widget that displays figure self.canvas = FigureCanvas(self.figure) # You can define other things in here self.initUI() def openInputImage(self): # This function is called when the user clicks File->Input Image. self.inputLoaded = QFileDialog.getOpenFileName(self, 'Input Image', os.getenv('HOME')) self.input_img.setPixmap(QPixmap(self.inputLoaded[0])) self.plot() def openTargetImage(self): # This function is called when the user clicks File->Target Image. self.targetLoaded = QFileDialog.getOpenFileName( self, 'Target Image', os.getenv('HOME')) self.target_img.setPixmap(QPixmap(self.targetLoaded[0])) def initUI(self): # Write GUI initialization code menu = self.menuBar() file = menu.addMenu('File') input_Action = QAction('Open Input', self) target_Action = QAction('Open Target', self) exit_Action = QAction('Exit', self) equalize_hist_action = QAction('Equalize Histogram', self) toolbar = self.addToolBar('Toolbar') toolbar.addAction(equalize_hist_action) equalize_hist_action.triggered.connect(self.histogramButtonClicked) file.addAction(input_Action) file.addAction(target_Action) file.addAction(exit_Action) input_Action.triggered.connect(self.openInputImage) target_Action.triggered.connect(self.openTargetImage) exit_Action.triggered.connect(self.closeApp) inner_window = QWidget() input_box = QGroupBox('Input', inner_window) target_box = QGroupBox('Target', inner_window) result_box = QGroupBox('Result', inner_window) vbox_input = QVBoxLayout(self) input_box.setLayout(vbox_input) self.input_img = QLabel() vbox_input.addWidget(self.input_img) vbox_input.addWidget(self.canvas) self.plot() vbox_target = QVBoxLayout(self) target_box.setLayout(vbox_target) self.target_img = QLabel() vbox_target.addWidget(self.target_img) hbox = QHBoxLayout() hbox.addWidget(input_box) hbox.addWidget(target_box) hbox.addWidget(result_box) inner_window.setLayout(hbox) self.setCentralWidget(inner_window) self.show() def closeApp(self): self.close() def histogramButtonClicked(self): if not self.inputLoaded and not self.targetLoaded: # Error: "First load input and target images" in MessageBox QMessageBox.information(self, "Error", "First load input and target images") return None elif not self.inputLoaded: # Error: "Load input image" in MessageBox QMessageBox.information(self, "Error", "Load input image") return None elif not self.targetLoaded: # Error: "Load target image" in MessageBox QMessageBox.information(self, "Error", "Load target image") return None self.calcHistogram() def plot(self): # random data data = [np.random.random() for i in range(5)] # create an axis ax = self.figure.add_subplot(111) # clear old axis ax.clear() # plot data ax.plot(data) # refresh canvas self.canvas.draw() def calcHistogram(self, I): # Calculate histogram return NotImplementedError
class multivariateplotDlg(QtWidgets.QDialog, Ui_multivariateplot): def __init__(self, parent=None): super(multivariateplotDlg, self).__init__(parent) self.setupUi(self) self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowCloseButtonHint | QtCore.Qt.WindowMaximizeButtonHint) self.variablelistWidget.addItems(DS.Lc[DS.Ic]) self.variablelistWidget.doubleClicked.connect(self.additem_1) self.selectedlistWidget.doubleClicked.connect(self.additem_2) self.vradioButton.clicked.connect(self.allv) self.ApplyButton.clicked.connect(self.redraw) self.ResetButton.clicked.connect(self.reset) fig = Figure() ax = fig.add_subplot(111) ax.plot(np.array(0)) ax.set_xlim([0, 1]) ax.set_ylim([0, 1]) self.addmpl(fig) def allv(self): for i in range(self.variablelistWidget.count()): self.selectedlistWidget.addItem( self.variablelistWidget.item(i).text()) self.variablelistWidget.clear() def additem_1(self): nrow = self.variablelistWidget.currentRow() item_str = self.variablelistWidget.item(nrow).text() if (self.scattermatrixradioButton.isChecked()): maxlim = 6 if (self.selectedlistWidget.count() > maxlim): QtWidgets.QMessageBox.critical(self, 'Error', "Too many variables!", QtWidgets.QMessageBox.Ok) return () self.variablelistWidget.takeItem(nrow) self.selectedlistWidget.addItem(item_str) def additem_2(self): nrow = self.selectedlistWidget.currentRow() item_str = self.selectedlistWidget.item(nrow).text() self.variablelistWidget.addItem(item_str) self.selectedlistWidget.takeItem(nrow) def redraw(self): nv = self.selectedlistWidget.count() variables = [] for i in range(nv): variables.append(self.selectedlistWidget.item(i).text()) data = DS.Raw.iloc[DS.Ir, DS.Ic] data = data.assign(Lr=DS.Lr[DS.Ir]) data = data.assign(Cr=DS.Cr[DS.Ir]) data = data[variables + ['Lr', 'Cr']] Nnan = data.isnull().isnull().all().all() data = data.dropna() Lr = data['Lr'].values Cr = data['Cr'].values data = data.drop('Lr', axis=1) data = data.drop('Cr', axis=1) if data.dtypes.all() == 'float' and data.dtypes.all() == 'int': QtWidgets.QMessageBox.critical(self,'Error',"Some values are not numbers!",\ QtWidgets.QMessageBox.Ok) return () fig = Figure() nr, nc = data.shape Cc = DS.Cc[DS.Ic] Cc = Cc[np.in1d(DS.Lc[DS.Ic], variables)] if self.starradioButton.isChecked(): if (self.selectedlistWidget.count() < 3): QtWidgets.QMessageBox.critical(self,'Error',"Too few variables!",\ QtWidgets.QMessageBox.Ok) return () mn = data.min() mn[mn == 0] = 0.001 mx = data.max() mx[mx == 0] = 0.001 ranges = list() for i in range(len(mn)): ranges.append([mn[i], mx[i]]) radar = ComplexRadar(fig, variables, ranges) for i in range(nr): y = data.iloc[i, :] y[y == 0] = 0.001 y = y.tolist() radar.plot(y) elif self.scattermatrixradioButton.isChecked(): fig = scatterplot_matrix(data.T.values, variables, linestyle='none', marker='o', color='black', mfc='none') fig.suptitle('Simple Scatterplot Matrix') elif self.magnituderadioButton.isChecked(): ax = fig.add_subplot(111) ax.plot(data.values.min(axis=0), 'o', color='red', label='min') ax.plot(data.values.max(axis=0), 'o', color='green', label='max') ax.legend(loc=4) for i in range(nv): ax.vlines(i, data.values.min(axis=0)[i], data.values.max(axis=0)[i], linestyles='solid', color=Cc[i]) #ax.tick_params(axis='x',which='both',bottom='off',top='off',labelbottom='off') ax.set_xticklabels([''] + variables + ['']) ax.set_xlabel('Feature Index') ax.set_ylabel('Feature Magnitude') ax.set_yscale("log") ax.set_xlim([-1, nv]) ax.xaxis.grid(True) ax.yaxis.grid(True) elif self.corrradioButton.isChecked(): fig = plt.figure() ax = fig.add_subplot(111) cax = ax.matshow(np.corrcoef(data)) fig.colorbar(cax) ax.set_title('Correlation Matrix') elif self.covradioButton.isChecked(): fig = plt.figure() ax = fig.add_subplot(111) cax = ax.matshow(np.cov(data)) fig.colorbar(cax) ax.set_title('Covariance Matrix') elif self.trendradioButton.isChecked(): ax = fig.add_subplot(111) ncol = nc nrow = nr Lrow = Lr color_point = Cr color_line = Cc if self.rowcheckBox.isChecked(): ncol = nr nrow = nc Lrow = np.array(variables) color_point = Cc color_line = Cr data = data.T ind = np.array(range(1, nrow + 1)) for i in range(ncol): if self.PcheckBox.isChecked(): ax.scatter(ind, data.iloc[:, i], marker='o', color=color_point) if self.LcheckBox.isChecked(): ax.plot(ind, data.iloc[:, i], color=color_line[i]) if (nrow > 30): itick = np.linspace(0, nrow - 1, 20).astype(int) ltick = Lrow[itick] else: itick = ind ltick = Lrow ax.set_xticks(itick) ax.set_xticklabels(ltick, rotation='vertical') ax.set_xlabel('Object') if Nnan: ax.annotate('{:04.2f} NaN'.format(Nnan), xy=(0.80, 0.95), xycoords='figure fraction') self.rmmpl() self.addmpl(fig) def reset(self): self.variablelistWidget.addItems(DS.getLc().tolist()) self.selectedlistWidget.clear() self.update() def addmpl(self, fig): self.canvas = FigureCanvas(fig) self.mplvl.addWidget(self.canvas) self.canvas.draw() self.toolbar = NavigationToolbar(self.canvas, self.mplwindow, coordinates=True) self.mplvl.addWidget(self.toolbar) def rmmpl(self, ): self.mplvl.removeWidget(self.canvas) self.canvas.close() self.mplvl.removeWidget(self.toolbar) self.toolbar.close()
class Main(QMainWindow, Ui_MainWindow): def __init__(self,specfilename,parfilename=None,wave1=None,wave2=None,numchunks=8,parent=None): QtWidgets.QMainWindow.__init__(self, parent) #super(Main,self).__init__() self.setupUi(self) ### Initialize stuff self.line_dict = {} self.fitpars = None self.parinfo = None self.linecmts = None self.wave1 = wave1 self.wave2 = wave2 self.numchunks = numchunks self.spls = [] self.labeltog = 1 self.pixtog = 0 self.restog = 1 self.fitconvtog = 0 self.lastclick=1334. ### Read in spectrum and list of lines to fit self.specfilename=specfilename self.spectrum = readspec(specfilename) self.wave=self.spectrum.wavelength.value self.normflux=self.spectrum.flux/self.spectrum.co self.normsig=self.spectrum.sig/self.spectrum.co cfg.spectrum = self.spectrum cfg.wave=self.wave cfg.normflux=self.normflux cfg.filename=self.specfilename if not parfilename==None: self.initialpars(parfilename) ### Connect signals to slots self.fitButton.clicked.connect(self.fitlines) self.fitConvBox.clicked.connect(self.togfitconv) self.boxLineLabel.clicked.connect(self.toglabels) self.boxFitpix.clicked.connect(self.togfitpix) self.boxResiduals.clicked.connect(self.togresiduals) self.loadParsButton.clicked.connect(self.openParFileDialog) self.addLineButton.clicked.connect(self.addLineDialog) self.writeParsButton.clicked.connect(self.writeParFileDialog) self.writeModelButton.clicked.connect(self.writeModelFileDialog) self.writeModelCompButton.clicked.connect(self.writeModelCompFileDialog) self.quitButton.clicked.connect(self.quitGui) ### Initialize spectral plots fig=Figure() self.fig=fig self.initplot(fig) ### Initialize side plot sidefig=Figure(figsize=(5.25,2)) self.sidefig = sidefig self.addsidempl(self.sidefig) self.sideplot(self.lastclick) #Dummy initial cenwave setting def initplot(self,fig,numchunks=8): wlen=len(self.spectrum.wavelength)/numchunks self.spls=[] if self.wave1==None: waveidx1=0 # Default to plotting entire spectrum for now else: waveidx1=jbg.closest(self.wave,self.wave1) if self.fitpars!=None: model=joebvpfit.voigtfunc(self.wave,self.datamodel.fitpars) sg=jbg.subplotgrid(numchunks) for i in range(numchunks): self.spls.append(fig.add_subplot(sg[i][0],sg[i][1],sg[i][2])) pixs=range(waveidx1+i*wlen,waveidx1+(i+1)*wlen) self.spls[i].plot(self.wave[pixs],self.normflux[pixs],linestyle='steps-mid') if self.fitpars!=None: self.spls[i].plot(self.wave,model,'r') self.spls[i].set_xlim(self.wave[pixs[0]],self.wave[pixs[-1]]) self.spls[i].set_ylim(cfg.ylim) self.spls[i].set_xlabel('wavelength',labelpad=0) self.spls[i].set_ylabel('relative flux',labelpad=-5) self.spls[i].get_xaxis().get_major_formatter().set_scientific(False) fig.subplots_adjust(top=0.98,bottom=0.05,left=0.08,right=0.97,wspace=0.15,hspace=0.25) self.addmpl(fig) def initialpars(self,parfilename): ### Deal with initial parameters from line input file self.fitpars,self.fiterrors,self.parinfo,self.linecmts = joebvpfit.readpars(parfilename) cfg.fitidx=joebvpfit.fitpix(self.wave, self.fitpars) #Set pixels for fit cfg.wavegroups=[] self.datamodel = LineParTableModel(self.fitpars,self.fiterrors,self.parinfo,linecmts=self.linecmts) self.tableView.setModel(self.datamodel) self.datamodel.updatedata(self.fitpars,self.fitpars,self.parinfo,self.linecmts) def sideplot(self,cenwave,wavebuf=3): if len(self.sidefig.axes)==0: self.sideax=self.sidefig.add_subplot(111) self.sideax.clear() self.sideax.plot(self.wave, self.normflux, linestyle='steps-mid') if self.pixtog == 1: self.sideax.plot(self.wave[cfg.fitidx], self.normflux[cfg.fitidx], 'gs', markersize=4, mec='green') model = joebvpfit.voigtfunc(self.wave, self.fitpars) res = self.normflux - model self.sideax.plot(self.wave, model, 'r') if self.restog == 1: self.sideax.plot(self.wave, -res, '.', color='black', ms=2) self.sideax.plot(self.wave, [0] * len(self.wave), color='gray') ### label lines we are trying to fit if self.labeltog == 1: for j in range(len(self.fitpars[0])): labelloc = self.fitpars[0][j] * (1. + self.fitpars[3][j]) + self.fitpars[4][j] / c * \ self.fitpars[0][j] * ( 1. + self.fitpars[3][j]) label = ' {:.1f}_\nz{:.4f}'.format(self.fitpars[0][j], self.fitpars[3][j]) self.sideax.text(labelloc, cfg.label_ypos, label, rotation=90, withdash=True, ha='center', va='bottom', clip_on=True, fontsize=cfg.label_fontsize) self.sideax.plot(self.wave, self.normsig, linestyle='steps-mid', color='red', lw=0.5) self.sideax.plot(self.wave, -self.normsig, linestyle='steps-mid', color='red', lw=0.5) self.sideax.get_xaxis().get_major_formatter().set_scientific(False) self.sideax.get_xaxis().get_major_formatter().set_useOffset(False) try: self.sideax.set_xlim(cenwave-wavebuf,cenwave+wavebuf) self.sideax.set_ylim(cfg.ylim) self.changesidefig(self.sidefig) except TypeError: pass def fitlines(self): print('VPmeasure: Fitting line profile(s)...') print(len(self.fitpars[0]),'lines loaded for fitting.') if self.fitconvtog: self.fitpars, self.fiterrors = joebvpfit.fit_to_convergence(self.wave, self.normflux, self.normsig, self.datamodel.fitpars, self.datamodel.parinfo) else: self.fitpars, self.fiterrors = joebvpfit.joebvpfit(self.wave, self.normflux,self.normsig, self.datamodel.fitpars,self.datamodel.parinfo) self.datamodel.updatedata(self.fitpars,self.fiterrors,self.parinfo,self.linecmts) self.tableView.resizeColumnsToContents() self.updateplot() self.sideplot(self.lastclick) def togfitconv(self): if self.fitconvtog==1: self.fitconvtog=0 else: self.fitconvtog=1 def quitGui(self): self.deleteLater() self.close() def toglabels(self): if self.labeltog==1: self.labeltog=0 else: self.labeltog=1 self.updateplot() def togfitpix(self): if self.pixtog == 1: self.pixtog = 0 else: self.pixtog = 1 self.updateplot() def togresiduals(self): if self.restog == 1: self.restog = 0 else: self.restog = 1 self.updateplot() def openParFileDialog(self): fname = QtWidgets.QFileDialog.getOpenFileName(self, 'Open line parameter file','.') fname = str(fname[0]) if fname != '': self.initialpars(fname) self.updateplot() def writeParFileDialog(self): fname = QtWidgets.QFileDialog.getSaveFileName(self, 'Save line parameter file', cfg.VPparoutfile) fname = str(fname[0]) if fname != '': joebvpfit.writelinepars(self.datamodel.fitpars, self.datamodel.fiterrors, self.datamodel.parinfo, self.specfilename, fname, self.datamodel.linecmts) def writeModelFileDialog(self): fname = QtWidgets.QFileDialog.getSaveFileName(self, 'Save model to file', cfg.VPmodeloutfile) fname = str(fname[0]) if fname != '': joebvpfit.writeVPmodel(fname, self.wave, self.fitpars, self.normflux, self.normsig) def writeModelCompFileDialog(self): dirDialog = QtWidgets.QFileDialog(self) dirDialog.setFileMode(dirDialog.Directory) dirDialog.setOption(dirDialog.ShowDirsOnly, True) defDirName = cfg.VPmodeloutfile[:-5] dname = dirDialog.getSaveFileName(self, 'Save model to files split by components',defDirName) dname = str(dname[0]) if dname != '': joebvpfit.writeVPmodelByComp(dname, self.spectrum,self.fitpars) def addLineDialog(self): dlgOutput=newLineDialog.get_newline() if (dlgOutput != 0): if '' not in dlgOutput: newlam,newz,newcol,newb,newvel,newvel1,newvel2 = dlgOutput self.datamodel.addLine(self.wave,float(newlam), float(newz), float(newcol), float(newb), float(newvel), float(newvel1), float(newvel2)) #dialog=newLineDialog(parent=None) self.fitpars = self.datamodel.fitpars self.fiterrors = self.datamodel.fiterrors self.parinfo = self.datamodel.parinfo self.tableView.setModel(self.datamodel) def updateplot(self): if self.wave1==None: waveidx1=0 # Default to plotting entire spectrum for now else: waveidx1=jbg.closest(self.wave,self.wave1) wlen=len(self.spectrum.wavelength)/self.numchunks for i,sp in enumerate(self.spls): sp.clear() prange=range(waveidx1+i*wlen,waveidx1+(i+1)*wlen) if ((len(self.fitpars[0])>0)): sp.plot(self.wave,self.normflux,linestyle='steps-mid') if self.pixtog==1: sp.plot(self.wave[cfg.fitidx], self.normflux[cfg.fitidx], 'gs', markersize=4, mec='green') model=joebvpfit.voigtfunc(self.wave,self.fitpars) res=self.normflux-model sp.plot(self.wave,model,'r') if self.restog==1: sp.plot(self.wave,-res,'.',color='black', ms=2) sp.plot(self.wave,[0]*len(self.wave),color='gray') ### label lines we are trying to fit if self.labeltog==1: for j in range(len(self.fitpars[0])): labelloc=self.fitpars[0][j]*(1.+self.fitpars[3][j])+self.fitpars[4][j]/c*self.fitpars[0][j]*(1.+self.fitpars[3][j]) label = ' {:.1f}_\nz{:.4f}'.format(self.fitpars[0][j], self.fitpars[3][j]) sp.text(labelloc, cfg.label_ypos, label, rotation=90, withdash=True, ha='center', va='bottom', clip_on=True, fontsize=cfg.label_fontsize) sp.plot(self.wave,self.normsig,linestyle='steps-mid',color='red', lw=0.5) sp.plot(self.wave,-self.normsig,linestyle='steps-mid',color='red', lw=0.5) sp.set_ylim(cfg.ylim) sp.set_xlim(self.wave[prange[0]],self.wave[prange[-1]]) sp.set_xlabel('wavelength (A)', fontsize=cfg.xy_fontsize, labelpad=cfg.x_labelpad) sp.set_ylabel('normalized flux', fontsize=cfg.xy_fontsize, labelpad=cfg.y_labelpad) sp.get_xaxis().get_major_formatter().set_scientific(False) sp.get_xaxis().get_major_formatter().set_useOffset(False) self.changefig(self.fig) def changefig(self, item): #text = str(item.text()) self.rmmpl() self.addmpl(self.fig) def changesidefig(self, item): #text = str(item.text()) self.rmsidempl() self.addsidempl(self.sidefig) def on_click(self, event): self.lastclick=event.xdata self.sideplot(self.lastclick) def addmpl(self, fig): self.canvas = FigureCanvas(fig) self.canvas.mpl_connect('button_press_event',self.on_click) self.mplvl.addWidget(self.canvas) self.canvas.draw() self.toolbar = NavigationToolbar(self.canvas,self.mplwindow,coordinates=True) self.mplvl.addWidget(self.toolbar) def addsidempl(self, sidefig): self.sidecanvas = FigureCanvas(sidefig) self.sidecanvas.setParent(self.sideMplWindow) if len(self.sidefig.axes) == 0: self.sidemplvl = QVBoxLayout() if len(self.sidefig.axes) != 0: self.sidemplvl.addWidget(self.sidecanvas) if len(self.sidefig.axes) == 0: self.sideMplWindow.setLayout(self.sidemplvl) self.sidecanvas.draw() def rmmpl(self,): self.mplvl.removeWidget(self.canvas) self.canvas.close() self.mplvl.removeWidget(self.toolbar) self.toolbar.close() def rmsidempl(self, ): self.sidemplvl.removeWidget(self.sidecanvas) self.sidecanvas.close()
class MainWin(QtWidgets.QMainWindow): here = os.path.abspath(os.path.join(os.path.dirname(__file__))) # to be overloaded media = os.path.join(here, "media") font_size = 6 rc_context = { 'font.family': 'sans-serif', 'font.sans-serif': ['Tahoma', 'Bitstream Vera Sans', 'Lucida Grande', 'Verdana'], 'font.size': font_size, 'figure.titlesize': font_size + 1, 'axes.labelsize': font_size, 'legend.fontsize': font_size, 'xtick.labelsize': font_size - 1, 'ytick.labelsize': font_size - 1, 'axes.linewidth': 0.5, 'axes.xmargin': 0.01, 'axes.ymargin': 0.01, 'lines.linewidth': 1.0, 'grid.alpha': 0.2, } def __init__(self, main_win=None): super().__init__(main_win) self.main_win = main_win # set the application name and the version self.name = rori_name self.version = rori_version if self.main_win is None: self.setWindowTitle('%s v.%s' % (self.name, self.version)) else: self.setWindowTitle('%s' % (self.name,)) self.setMinimumSize(200, 200) self.resize(600, 900) # only called when stand-alone (without Sound Speed Manager) # noinspection PyArgumentList _app = QtCore.QCoreApplication.instance() if _app.applicationName() == 'python': _app.setApplicationName('%s v.%s' % (self.name, self.version)) _app.setOrganizationName("HydrOffice") _app.setOrganizationDomain("hydroffice.org") logger.debug("set application name: %s" % _app.applicationName()) # set icons icon_info = QtCore.QFileInfo(os.path.join(self.media, 'rori.png')) self.setWindowIcon(QtGui.QIcon(icon_info.absoluteFilePath())) if (sys.platform == 'win32') or (os.name is "nt"): # is_windows() try: # This is needed to display the app icon on the taskbar on Windows 7 import ctypes app_id = '%s v.%s' % (self.name, self.version) ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(app_id) except AttributeError as e: logger.debug("Unable to change app icon: %s" % e) # set palette style_info = QtCore.QFileInfo(os.path.join(self.here, 'styles', 'main.stylesheet')) style_content = open(style_info.filePath()).read() self.setStyleSheet(style_content) # mpl figure settings self.is_drawn = False self.f_dpi = 120 # dots-per-inch self.f_sz = (3.0, 6.0) # inches self.tvu_plot = None self.thu_plot = None self.iho_color = '#E69F24' self.noaa_color = '#1C75C3' # outline ui self.top_widget = QtWidgets.QWidget() self.setCentralWidget(self.top_widget) self.vbox = QtWidgets.QVBoxLayout() self.vbox.setContentsMargins(4, 4, 4, 4) self.top_widget.setLayout(self.vbox) # ### Settings ### self.settings = QtWidgets.QGroupBox("Settings") self.vbox.addWidget(self.settings) settings_vbox = QtWidgets.QVBoxLayout() self.settings.setLayout(settings_vbox) label_hbox = QtWidgets.QHBoxLayout() settings_vbox.addLayout(label_hbox) # stretch label_hbox.addStretch() # hssd text_1ab = QtWidgets.QLabel("") text_1ab.setAlignment(QtCore.Qt.AlignCenter) text_1ab.setFixedWidth(100) label_hbox.addWidget(text_1ab) # spacing label_hbox.addSpacing(10) # specs text_1ab = QtWidgets.QLabel("Great Lakes") text_1ab.setAlignment(QtCore.Qt.AlignCenter) text_1ab.setFixedWidth(100) label_hbox.addWidget(text_1ab) # spacing label_hbox.addSpacing(10) # specs text_1ab = QtWidgets.QLabel("") text_1ab.setAlignment(QtCore.Qt.AlignCenter) text_1ab.setFixedWidth(100) label_hbox.addWidget(text_1ab) # stretch label_hbox.addStretch() toggle_hbox = QtWidgets.QHBoxLayout() settings_vbox.addLayout(toggle_hbox) # stretch toggle_hbox.addStretch() # HSSD self.toggle_hssd = QtWidgets.QDial() self.toggle_hssd.setNotchesVisible(True) self.toggle_hssd.setFocusPolicy(QtCore.Qt.StrongFocus) self.toggle_hssd.setRange(0, 1) self.toggle_hssd.setValue(0) self.toggle_hssd.setFixedSize(QtCore.QSize(50, 50)) self.toggle_hssd.setInvertedAppearance(False) # noinspection PyUnresolvedReferences self.toggle_hssd.valueChanged.connect(self.on_settings_changed) toggle_hbox.addWidget(self.toggle_hssd) # spacing toggle_hbox.addSpacing(105) # area self.toggle_area = QtWidgets.QDial() self.toggle_area.setNotchesVisible(True) self.toggle_area.setFocusPolicy(QtCore.Qt.StrongFocus) self.toggle_area.setRange(0, 2) self.toggle_area.setValue(0) self.toggle_area.setFixedSize(QtCore.QSize(50, 50)) self.toggle_area.setInvertedAppearance(False) # noinspection PyUnresolvedReferences self.toggle_area.valueChanged.connect(self.on_settings_changed) toggle_hbox.addWidget(self.toggle_area) # spacing0 toggle_hbox.addSpacing(105) # specs self.toggle_z = QtWidgets.QDial() self.toggle_z.setNotchesVisible(True) self.toggle_z.setFocusPolicy(QtCore.Qt.StrongFocus) self.toggle_z.setRange(0, 1) self.toggle_z.setValue(0) self.toggle_z.setFixedSize(QtCore.QSize(50, 50)) self.toggle_z.setInvertedAppearance(False) # noinspection PyUnresolvedReferences self.toggle_z.valueChanged.connect(self.on_settings_changed) toggle_hbox.addWidget(self.toggle_z) # stretch toggle_hbox.addStretch() label2_hbox = QtWidgets.QHBoxLayout() settings_vbox.addLayout(label2_hbox) # stretch label2_hbox.addStretch() # specs text_special = QtWidgets.QLabel("HSSD 2018 ") text_special.setAlignment(QtCore.Qt.AlignRight) text_special.setFixedWidth(70) label2_hbox.addWidget(text_special) text_2 = QtWidgets.QLabel(" HSSD 2019+") text_2.setAlignment(QtCore.Qt.AlignLeft) text_2.setFixedWidth(70) label2_hbox.addWidget(text_2) # stretch label2_hbox.addSpacing(10) # area text_special = QtWidgets.QLabel("Pacific Coast ") text_special.setAlignment(QtCore.Qt.AlignRight) text_special.setFixedWidth(70) label2_hbox.addWidget(text_special) text_2 = QtWidgets.QLabel(" Atlantic Coast") text_2.setAlignment(QtCore.Qt.AlignLeft) text_2.setFixedWidth(70) label2_hbox.addWidget(text_2) # stretch label2_hbox.addSpacing(10) # specs text_special = QtWidgets.QLabel("Depth ") text_special.setAlignment(QtCore.Qt.AlignRight) text_special.setFixedWidth(70) label2_hbox.addWidget(text_special) text_2 = QtWidgets.QLabel(" Elevation") text_2.setAlignment(QtCore.Qt.AlignLeft) text_2.setFixedWidth(70) label2_hbox.addWidget(text_2) # stretch label2_hbox.addStretch() settings_vbox.addSpacing(8) hbox = QtWidgets.QHBoxLayout() hbox.addStretch() watlev_text = QtWidgets.QLabel("Always Dry: ") watlev_text.setFixedWidth(100) hbox.addWidget(watlev_text) self.always_dry_min_value = QtWidgets.QLineEdit() self.always_dry_min_value.setFixedWidth(120) self.always_dry_min_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.always_dry_min_value.setDisabled(True) self.always_dry_min_value.setText("") hbox.addWidget(self.always_dry_min_value) self.always_dry_max_value = QtWidgets.QLineEdit() self.always_dry_max_value.setFixedWidth(120) self.always_dry_max_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.always_dry_max_value.setDisabled(True) self.always_dry_max_value.setText("") hbox.addWidget(self.always_dry_max_value) hbox.addStretch() settings_vbox.addLayout(hbox) hbox = QtWidgets.QHBoxLayout() hbox.addStretch() watlev_text = QtWidgets.QLabel("Covers & Uncovers: ") watlev_text.setFixedWidth(100) hbox.addWidget(watlev_text) self.covers_and_uncovers_min_value = QtWidgets.QLineEdit() self.covers_and_uncovers_min_value.setFixedWidth(120) self.covers_and_uncovers_min_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.covers_and_uncovers_min_value.setDisabled(True) self.covers_and_uncovers_min_value.setText("") hbox.addWidget(self.covers_and_uncovers_min_value) self.covers_and_uncovers_max_value = QtWidgets.QLineEdit() self.covers_and_uncovers_max_value.setFixedWidth(120) self.covers_and_uncovers_max_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.covers_and_uncovers_max_value.setDisabled(True) self.covers_and_uncovers_max_value.setText("") hbox.addWidget(self.covers_and_uncovers_max_value) hbox.addStretch() settings_vbox.addLayout(hbox) hbox = QtWidgets.QHBoxLayout() hbox.addStretch() watlev_text = QtWidgets.QLabel("Awash: ") watlev_text.setFixedWidth(100) hbox.addWidget(watlev_text) self.awash_min_value = QtWidgets.QLineEdit() self.awash_min_value.setFixedWidth(120) self.awash_min_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.awash_min_value.setDisabled(True) self.awash_min_value.setText("") hbox.addWidget(self.awash_min_value) self.awash_max_value = QtWidgets.QLineEdit() self.awash_max_value.setFixedWidth(120) self.awash_max_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.awash_max_value.setDisabled(True) self.awash_max_value.setText("") hbox.addWidget(self.awash_max_value) hbox.addStretch() settings_vbox.addLayout(hbox) hbox = QtWidgets.QHBoxLayout() hbox.addStretch() watlev_text = QtWidgets.QLabel("Always underwater: ") watlev_text.setFixedWidth(100) hbox.addWidget(watlev_text) self.always_underwater_min_value = QtWidgets.QLineEdit() self.always_underwater_min_value.setFixedWidth(120) self.always_underwater_min_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.always_underwater_min_value.setDisabled(True) self.always_underwater_min_value.setText("") hbox.addWidget(self.always_underwater_min_value) self.always_underwater_max_value = QtWidgets.QLineEdit() self.always_underwater_max_value.setFixedWidth(120) self.always_underwater_max_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.always_underwater_max_value.setDisabled(True) self.always_underwater_max_value.setText("") hbox.addWidget(self.always_underwater_max_value) hbox.addStretch() settings_vbox.addLayout(hbox) # ### Inputs ### self.inputs = QtWidgets.QGroupBox("Input") self.vbox.addWidget(self.inputs) inputs_vbox = QtWidgets.QVBoxLayout() self.inputs.setLayout(inputs_vbox) # MHW hbox = QtWidgets.QHBoxLayout() hbox.addStretch() self.mhw_text = QtWidgets.QLabel("MHW [m]: ") hbox.addWidget(self.mhw_text) self.mhw_value = QtWidgets.QLineEdit() self.mhw_value.setFixedWidth(60) self.mhw_value.setValidator(QtGui.QDoubleValidator(-9999, 9999, 5, self.mhw_value)) self.mhw_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.mhw_value.setText("5.0") hbox.addWidget(self.mhw_value) depth_text = QtWidgets.QLabel("Depth [m]: ") hbox.addWidget(depth_text) self.depth_value = QtWidgets.QLineEdit() self.depth_value.setFixedWidth(60) self.depth_value.setValidator(QtGui.QDoubleValidator(-9999, 9999, 5, self.depth_value)) self.depth_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.depth_value.setText("1.0") hbox.addWidget(self.depth_value) hbox.addSpacing(16) self.calculate = QtWidgets.QPushButton("Run") self.calculate.setFixedHeight(28) self.calculate.setFixedWidth(42) # noinspection PyUnresolvedReferences self.calculate.clicked.connect(self.on_calculate) hbox.addWidget(self.calculate) button = QtWidgets.QPushButton() hbox.addWidget(button) button.setFixedHeight(GuiSettings.single_line_height()) button.setFixedWidth(GuiSettings.single_line_height()) icon_info = QtCore.QFileInfo(os.path.join(self.media, 'small_info.png')) button.setIcon(QtGui.QIcon(icon_info.absoluteFilePath())) button.setToolTip('Open the manual page') button.setStyleSheet(GuiSettings.stylesheet_info_button()) # noinspection PyUnresolvedReferences button.clicked.connect(self.click_open_manual) hbox.addStretch() inputs_vbox.addLayout(hbox) # ### Outputs ### self.outputs = QtWidgets.QGroupBox("Outputs") self.vbox.addWidget(self.outputs) outputs_vbox = QtWidgets.QVBoxLayout() self.outputs.setLayout(outputs_vbox) outputs_hbox = QtWidgets.QHBoxLayout() outputs_vbox.addLayout(outputs_hbox) outputs_hbox.addStretch() # pic self.out_pic_label = QtWidgets.QLabel() outputs_hbox.addWidget(self.out_pic_label) # info hbox = QtWidgets.QHBoxLayout() hbox.addStretch() out_text_vbox = QtWidgets.QVBoxLayout() hbox.addLayout(out_text_vbox) self.out_main_label = QtWidgets.QLabel() self.out_main_label.setFixedWidth(320) self.out_main_label.setStyleSheet("font-weight: bold") out_text_vbox.addWidget(self.out_main_label) self.out_more_label = QtWidgets.QLabel() self.out_more_label.setFixedWidth(320) out_text_vbox.addWidget(self.out_more_label) hbox.addStretch() outputs_hbox.addLayout(hbox) outputs_hbox.addStretch() # ### PLOTS ### # figure and canvas with rc_context(self.rc_context): self.f = Figure(figsize=self.f_sz, dpi=self.f_dpi) self.f.patch.set_alpha(0.0) self.c = FigureCanvas(self.f) self.c.setParent(self) self.c.setFocusPolicy(QtCore.Qt.ClickFocus) # key for press events!!! self.c.setFocus() outputs_vbox.addWidget(self.c) # axes self.levels_ax = self.f.add_subplot(111) self.levels_ax.invert_yaxis() # toolbar self.hbox = QtWidgets.QHBoxLayout() outputs_vbox.addLayout(self.hbox) # navigation self.nav = NavToolbar(canvas=self.c, parent=self.top_widget) self.hbox.addWidget(self.nav) self.on_settings_changed() self.on_first_draw() @classmethod def is_url(cls, value): if len(value) > 7: https = "https" if value[:len(https)] == https: return True return False @classmethod def is_darwin(cls): """ Check if the current OS is Mac OS """ return sys.platform == 'darwin' @classmethod def is_linux(cls): """ Check if the current OS is Linux """ return sys.platform in ['linux', 'linux2'] @classmethod def is_windows(cls): """ Check if the current OS is Windows """ return (sys.platform == 'win32') or (os.name is "nt") @classmethod def explore_folder(cls, path): """Open the passed path using OS-native commands""" if cls.is_url(path): import webbrowser webbrowser.open(path) return True if not os.path.exists(path): logger.warning('invalid path to folder: %s' % path) return False path = os.path.normpath(path) if cls.is_darwin(): subprocess.call(['open', '--', path]) return True elif cls.is_linux(): subprocess.call(['xdg-open', path]) return True elif cls.is_windows(): subprocess.call(['explorer', path]) return True logger.warning("Unknown/unsupported OS") return False @classmethod def click_open_manual(cls): logger.debug("open manual") cls.explore_folder( "https://www.hydroffice.org/manuals/qctools/user_manual_info.html#rori-your-rock-or-islet-oracle") def _draw_grid(self): for a in self.f.get_axes(): a.grid(True) def on_first_draw(self): """Redraws the figure, it is only called at the first import!!!""" with rc_context(self.rc_context): # self._set_title() self._draw_levels() self._draw_grid() self.is_drawn = True def _draw_levels(self): logger.debug("draw levels") mhw = float(self.mhw_value.text()) depth = float(self.depth_value.text()) if self.toggle_area.value() != 1: max_z = 1.5 * max(abs(mhw), abs(depth)) else: max_z = 1.5 * abs(depth) alpha = 0.3 text_color = '#666666' text_shift = 0.6 with rc_context(self.rc_context): self.levels_ax.clear() # self.levels_ax.set_xlabel('Depth [m]') if self.toggle_hssd.value() == 0: # 2018 HSSD if self.toggle_z.value() == 0: self.levels_ax.set_ylabel('Depth [m]') if self.toggle_area.value() == 1: self.levels_ax.axhline(y=0, color='b', linestyle=':') self.levels_ax.text(0.01, -0.01, 'LWD', rotation=0) self.levels_ax.axhline(y=depth, color='r', linestyle='-') self.levels_ax.text(0.01, depth + 0.01, 'depth', rotation=0) self.levels_ax.axhspan(- 1.2192, -max_z, facecolor='orange', alpha=alpha) self.levels_ax.text(text_shift, (- 1.2192 - max_z) / 2.0, 'ALWAYS DRY', color=text_color, rotation=0) self.levels_ax.axhspan(-0.6096, - 1.2192, facecolor='yellow', alpha=alpha) self.levels_ax.text(text_shift, (-0.6096 - 1.2192) / 2.0, 'COVERS & UNCOVERS', color=text_color, rotation=0) self.levels_ax.axhspan(0.6096, -0.6096, facecolor='cyan', alpha=alpha) self.levels_ax.text(text_shift, (0.6096 - 0.6096) / 2.0, 'AWASH', color=text_color, rotation=0) self.levels_ax.axhspan(max_z, 0.6096, facecolor='#0099ff', alpha=alpha) self.levels_ax.text(text_shift, (max_z + 0.6096) / 2.0, 'ALWAYS UNDERWATER', color=text_color, rotation=0) else: self.levels_ax.axhline(y=0.0, color='b', linestyle=':') self.levels_ax.text(0.01, 0.01, 'MLLW', rotation=0) self.levels_ax.axhline(y=-mhw, color='orange', linestyle=':') self.levels_ax.text(0.01, -mhw - 0.01, 'MHW', rotation=0) self.levels_ax.axhline(y=depth, color='r', linestyle='-') self.levels_ax.text(0.01, depth + 0.01, 'depth', rotation=0) if self.toggle_area.value() == 0: self.levels_ax.axhspan(-mhw - 0.6096, -max_z, facecolor='orange', alpha=alpha) self.levels_ax.text(text_shift, (-mhw - 0.6096 - max_z) / 2.0, 'ALWAYS DRY', color=text_color, rotation=0) self.levels_ax.axhspan(-0.6096, -mhw - 0.6096, facecolor='yellow', alpha=alpha) self.levels_ax.text(text_shift, (-0.6096 - mhw - 0.6096) / 2.0, 'COVERS & UNCOVERS', color=text_color, rotation=0) self.levels_ax.axhspan(0.6096, -0.6096, facecolor='cyan', alpha=alpha) self.levels_ax.text(text_shift, (0.6096 - 0.6096) / 2.0, 'AWASH', color=text_color, rotation=0) self.levels_ax.axhspan(max_z, 0.6096, facecolor='#0099ff', alpha=alpha) self.levels_ax.text(text_shift, (max_z + 0.6096) / 2.0, 'ALWAYS UNDERWATER', color=text_color, rotation=0) else: self.levels_ax.axhspan(-mhw - 0.3048, -max_z, facecolor='orange', alpha=alpha) self.levels_ax.text(text_shift, (-mhw - 0.3048 - max_z) / 2.0, 'ALWAYS DRY', color=text_color, rotation=0) self.levels_ax.axhspan(-0.3048, -mhw - 0.3048, facecolor='yellow', alpha=alpha) self.levels_ax.text(text_shift, (-0.3048 - mhw - 0.3048) / 2.0, 'COVERS & UNCOVERS', color=text_color, rotation=0) self.levels_ax.axhspan(0.3048, -0.3048, facecolor='cyan', alpha=alpha) self.levels_ax.text(text_shift, (0.3048 - 0.3048) / 2.0, 'AWASH', color=text_color, rotation=0) self.levels_ax.axhspan(max_z, 0.3048, facecolor='#0099ff', alpha=alpha) self.levels_ax.text(text_shift, (max_z + 0.3048) / 2.0, 'ALWAYS UNDERWATER', color=text_color, rotation=0) self.levels_ax.set_ylim([max_z, -max_z]) else: self.levels_ax.set_ylabel('Elevation [m]') if self.toggle_area.value() == 1: self.levels_ax.axhline(y=0, color='b', linestyle=':') self.levels_ax.text(0.01, 0.01, 'LWD', rotation=0) self.levels_ax.axhline(y=-depth, color='r', linestyle='-') self.levels_ax.text(0.01, -depth - 0.01, 'depth', rotation=0) self.levels_ax.axhspan(1.2192, max_z, facecolor='orange', alpha=alpha) self.levels_ax.text(text_shift, (1.2192 + max_z) / 2.0, 'ALWAYS DRY', color=text_color, rotation=0) self.levels_ax.axhspan(+0.6096, + 1.2192, facecolor='yellow', alpha=alpha) self.levels_ax.text(text_shift, (+0.6096 + 1.2192) / 2.0, 'COVERS & UNCOVERS', color=text_color, rotation=0) self.levels_ax.axhspan(-0.6096, 0.6096, facecolor='cyan', alpha=alpha) self.levels_ax.text(text_shift, (-0.6096 + 0.6096) / 2.0, 'AWASH', color=text_color, rotation=0) self.levels_ax.axhspan(-max_z, -0.6096, facecolor='#0099ff', alpha=alpha) self.levels_ax.text(text_shift, (-max_z - 0.6096) / 2.0, 'ALWAYS UNDERWATER', color=text_color, rotation=0) else: self.levels_ax.axhline(y=0.0, color='orange', linestyle=':') self.levels_ax.text(0.01, 0.01, 'MHW', rotation=0) self.levels_ax.axhline(y=-mhw, color='b', linestyle=':') self.levels_ax.text(0.01, -mhw - 0.01, 'MLLW', rotation=0) self.levels_ax.axhline(y=-mhw - depth, color='r', linestyle='-') self.levels_ax.text(0.01, -mhw - depth - 0.01, 'depth', rotation=0) if self.toggle_area.value() == 0: self.levels_ax.axhspan(0.6096, max_z, facecolor='orange', alpha=alpha) self.levels_ax.text(text_shift, (0.6096 + max_z) / 2.0, 'ALWAYS DRY', color=text_color, rotation=0) self.levels_ax.axhspan(-mhw + 0.6096, 0.6096, facecolor='yellow', alpha=alpha) self.levels_ax.text(text_shift, (-mhw + 0.6096 + 0.6096) / 2.0, 'COVERS & UNCOVERS', color=text_color, rotation=0) self.levels_ax.axhspan(-mhw - 0.6096, -mhw + 0.6096, facecolor='cyan', alpha=alpha) self.levels_ax.text(text_shift, (-mhw - 0.6096 - mhw + 0.6096) / 2.0, 'AWASH', color=text_color, rotation=0) self.levels_ax.axhspan(-max_z, -mhw - 0.6096, facecolor='#0099ff', alpha=alpha) self.levels_ax.text(text_shift, (-max_z - mhw - 0.6096) / 2.0, 'ALWAYS UNDERWATER', color=text_color, rotation=0) else: self.levels_ax.axhspan(0.3048, max_z, facecolor='orange', alpha=alpha) self.levels_ax.text(text_shift, (0.3048 + max_z) / 2.0, 'ALWAYS DRY', color=text_color, rotation=0) self.levels_ax.axhspan(-mhw + 0.3048, 0.3048, facecolor='yellow', alpha=alpha) self.levels_ax.text(text_shift, (-mhw + 0.3048 + 0.3048) / 2.0, 'COVERS & UNCOVERS', color=text_color, rotation=0) self.levels_ax.axhspan(-mhw - 0.3048, -mhw + 0.3048, facecolor='cyan', alpha=alpha) self.levels_ax.text(text_shift, (-mhw - 0.3048 - mhw + 0.3048) / 2.0, 'AWASH', color=text_color, rotation=0) self.levels_ax.axhspan(-max_z, -mhw - 0.3048, facecolor='#0099ff', alpha=alpha) self.levels_ax.text(text_shift, (-max_z - mhw - 0.3048) / 2.0, 'ALWAYS UNDERWATER', color=text_color, rotation=0) self.levels_ax.set_ylim([-max_z, max_z]) else: # 2019 HSSD if self.toggle_z.value() == 0: self.levels_ax.set_ylabel('Depth [m]') if self.toggle_area.value() == 1: self.levels_ax.axhline(y=0, color='b', linestyle=':') self.levels_ax.text(0.01, -0.01, 'LWD', rotation=0) self.levels_ax.axhline(y=depth, color='r', linestyle='-') self.levels_ax.text(0.01, depth + 0.01, 'depth', rotation=0) self.levels_ax.axhspan(- 0.1, -max_z, facecolor='orange', alpha=alpha) self.levels_ax.text(text_shift, (- 0.1 - max_z) / 2.0, 'ALWAYS DRY', color=text_color, rotation=0) self.levels_ax.axhspan(-0.1, - 0.1, facecolor='yellow', alpha=alpha) self.levels_ax.text(text_shift, (-0.1 - 0.1) / 2.0, 'COVERS & UNCOVERS', color=text_color, rotation=0) self.levels_ax.axhspan(0.1, -0.1, facecolor='cyan', alpha=alpha) self.levels_ax.text(text_shift, (0.1 - 0.1) / 2.0, 'AWASH', color=text_color, rotation=0) self.levels_ax.axhspan(max_z, 0.1, facecolor='#0099ff', alpha=alpha) self.levels_ax.text(text_shift, (max_z + 0.1) / 2.0, 'ALWAYS UNDERWATER', color=text_color, rotation=0) else: self.levels_ax.axhline(y=0.0, color='b', linestyle=':') self.levels_ax.text(0.01, 0.01, 'MLLW', rotation=0) self.levels_ax.axhline(y=-mhw, color='orange', linestyle=':') self.levels_ax.text(0.01, -mhw - 0.01, 'MHW', rotation=0) self.levels_ax.axhline(y=depth, color='r', linestyle='-') self.levels_ax.text(0.01, depth + 0.01, 'depth', rotation=0) if self.toggle_area.value() in [0, 2]: self.levels_ax.axhspan(-mhw - 0.1, -max_z, facecolor='orange', alpha=alpha) self.levels_ax.text(text_shift, (-mhw - 0.1 - max_z) / 2.0, 'ALWAYS DRY', color=text_color, rotation=0) self.levels_ax.axhspan(-0.1, -mhw - 0.1, facecolor='yellow', alpha=alpha) self.levels_ax.text(text_shift, (-0.1 - mhw - 0.1) / 2.0, 'COVERS & UNCOVERS', color=text_color, rotation=0) self.levels_ax.axhspan(0.1, -0.1, facecolor='cyan', alpha=alpha) self.levels_ax.text(text_shift, (0.1 - 0.1) / 2.0, 'AWASH', color=text_color, rotation=0) self.levels_ax.axhspan(max_z, 0.1, facecolor='#0099ff', alpha=alpha) self.levels_ax.text(text_shift, (max_z + 0.1) / 2.0, 'ALWAYS UNDERWATER', color=text_color, rotation=0) self.levels_ax.set_ylim([max_z, -max_z]) else: self.levels_ax.set_ylabel('Elevation [m]') if self.toggle_area.value() == 1: self.levels_ax.axhline(y=0, color='b', linestyle=':') self.levels_ax.text(0.01, 0.01, 'LWD', rotation=0) self.levels_ax.axhline(y=-depth, color='r', linestyle='-') self.levels_ax.text(0.01, -depth - 0.01, 'depth', rotation=0) self.levels_ax.axhspan(0.1, max_z, facecolor='orange', alpha=alpha) self.levels_ax.text(text_shift, (0.1 + max_z) / 2.0, 'ALWAYS DRY', color=text_color, rotation=0) self.levels_ax.axhspan(+0., + 0.1, facecolor='yellow', alpha=alpha) self.levels_ax.text(text_shift, (+0.1 + 0.1) / 2.0, 'COVERS & UNCOVERS', color=text_color, rotation=0) self.levels_ax.axhspan(-0.1, 0.1, facecolor='cyan', alpha=alpha) self.levels_ax.text(text_shift, (-0.1 + 0.1) / 2.0, 'AWASH', color=text_color, rotation=0) self.levels_ax.axhspan(-max_z, -0.1, facecolor='#0099ff', alpha=alpha) self.levels_ax.text(text_shift, (-max_z - 0.1) / 2.0, 'ALWAYS UNDERWATER', color=text_color, rotation=0) else: self.levels_ax.axhline(y=0.0, color='orange', linestyle=':') self.levels_ax.text(0.01, 0.01, 'MHW', rotation=0) self.levels_ax.axhline(y=-mhw, color='b', linestyle=':') self.levels_ax.text(0.01, -mhw - 0.01, 'MLLW', rotation=0) self.levels_ax.axhline(y=-mhw - depth, color='r', linestyle='-') self.levels_ax.text(0.01, -mhw - depth - 0.01, 'depth', rotation=0) if self.toggle_area.value() in [0, 2]: self.levels_ax.axhspan(0.1, max_z, facecolor='orange', alpha=alpha) self.levels_ax.text(text_shift, (0.1 + max_z) / 2.0, 'ALWAYS DRY', color=text_color, rotation=0) self.levels_ax.axhspan(-mhw + 0.1, 0.1, facecolor='yellow', alpha=alpha) self.levels_ax.text(text_shift, (-mhw + 0.1 + 0.1) / 2.0, 'COVERS & UNCOVERS', color=text_color, rotation=0) self.levels_ax.axhspan(-mhw - 0.1, -mhw + 0.1, facecolor='cyan', alpha=alpha) self.levels_ax.text(text_shift, (-mhw - 0.1 - mhw + 0.1) / 2.0, 'AWASH', color=text_color, rotation=0) self.levels_ax.axhspan(-max_z, -mhw - 0.1, facecolor='#0099ff', alpha=alpha) self.levels_ax.text(text_shift, (-max_z - mhw - 0.1) / 2.0, 'ALWAYS UNDERWATER', color=text_color, rotation=0) self.levels_ax.set_ylim([-max_z, max_z]) def on_settings_changed(self): if self.toggle_hssd.value() == 0: logger.debug("draw HSSD 2018") if self.toggle_z.value() == 0: logger.debug("draw depth") if self.toggle_area.value() == 0: logger.debug("West Coast") self.always_dry_min_value.setText("") self.always_dry_max_value.setText("< -0.6096 MHW") self.covers_and_uncovers_min_value.setText(">= -0.6096 MHW") self.covers_and_uncovers_max_value.setText("< -0.6096 MLLW") self.awash_min_value.setText(">= -0.6096 MLLW") self.awash_max_value.setText("< +0.6096 MLLW") self.always_underwater_min_value.setText(">= +0.6096 MLLW") self.always_underwater_max_value.setText("") self.mhw_text.setText("MHW [m]: ") self.mhw_value.setEnabled(True) elif self.toggle_area.value() == 1: logger.debug("Great Lakes") self.always_dry_min_value.setText("") self.always_dry_max_value.setText("< -1.2192 LWD") self.covers_and_uncovers_min_value.setText(">= -1.2192 LWD") self.covers_and_uncovers_max_value.setText("< -0.6096 LWD") self.awash_min_value.setText(">= -0.6096 LWD") self.awash_max_value.setText("< +0.6096 LWD") self.always_underwater_min_value.setText(">= +0.6096 LWD") self.always_underwater_max_value.setText("") self.mhw_text.setText("LWD [m]: ") self.mhw_value.setDisabled(True) self.mhw_value.setText("0.0") elif self.toggle_area.value() == 2: logger.debug("East Coast") self.always_dry_min_value.setText("") self.always_dry_max_value.setText("< -0.3048 MHW") self.covers_and_uncovers_min_value.setText(">= -0.3048 MHW") self.covers_and_uncovers_max_value.setText("< -0.3048 MLLW") self.awash_min_value.setText(">= -0.3048 MLLW") self.awash_max_value.setText("< +0.3048 MLLW") self.always_underwater_min_value.setText(">= +0.3048 MLLW") self.always_underwater_max_value.setText("") self.mhw_text.setText("MHW [m]: ") self.mhw_value.setEnabled(True) else: logger.warning("unknown area") return else: logger.debug("draw elevation") if self.toggle_area.value() == 0: logger.debug("West Coast") self.always_dry_min_value.setText("") self.always_dry_max_value.setText("> +0.6096 MHW") self.covers_and_uncovers_min_value.setText("<= +0.6096 MHW") self.covers_and_uncovers_max_value.setText("> +0.6096 MLLW") self.awash_min_value.setText("<= +0.6096 MLLW") self.awash_max_value.setText("> -0.6096 MLLW") self.always_underwater_min_value.setText("<= -0.6096 MLLW") self.always_underwater_max_value.setText("") self.mhw_text.setText("MHW [m]: ") self.mhw_value.setEnabled(True) elif self.toggle_area.value() == 1: logger.debug("Great Lakes") self.always_dry_min_value.setText("") self.always_dry_max_value.setText("> +1.2192 LWD") self.covers_and_uncovers_min_value.setText("<= +1.2192 LWD") self.covers_and_uncovers_max_value.setText("> +0.6096 LWD") self.awash_min_value.setText("<= +0.6096 LWD") self.awash_max_value.setText("> -0.6096 LWD") self.always_underwater_min_value.setText("<= -0.6096 LWD") self.always_underwater_max_value.setText("") self.mhw_text.setText("LWD [m]: ") self.mhw_value.setDisabled(True) elif self.toggle_area.value() == 2: logger.debug("East Coast") self.always_dry_min_value.setText("") self.always_dry_max_value.setText("> +0.3048 MHW") self.covers_and_uncovers_min_value.setText("<= +0.3048 MHW") self.covers_and_uncovers_max_value.setText("> +0.3048 MLLW") self.awash_min_value.setText("<= +0.3048 MLLW") self.awash_max_value.setText("> -0.3048 MLLW") self.always_underwater_min_value.setText("<= -0.3048 MLLW") self.always_underwater_max_value.setText("") self.mhw_text.setText("MHW [m]: ") self.mhw_value.setEnabled(True) else: logger.warning("unknown area") return else: logger.debug("draw HSSD 2019") if self.toggle_z.value() == 0: logger.debug("draw depth") if self.toggle_area.value() in [0, 2]: logger.debug("East/West Coast") self.always_dry_min_value.setText("") self.always_dry_max_value.setText("< -0.1 MHW") self.covers_and_uncovers_min_value.setText(">= -0.1 MHW") self.covers_and_uncovers_max_value.setText("<= -0.1 MLLW") self.awash_min_value.setText("> -0.1 MLLW") self.awash_max_value.setText("<= +0.1 MLLW") self.always_underwater_min_value.setText("> +0.1 MLLW") self.always_underwater_max_value.setText("") self.mhw_text.setText("MHW [m]: ") self.mhw_value.setEnabled(True) elif self.toggle_area.value() == 1: logger.debug("Great Lakes") self.always_dry_min_value.setText("") self.always_dry_max_value.setText("< -0.1 LWD") self.covers_and_uncovers_min_value.setText(">= -0.1 LWD") self.covers_and_uncovers_max_value.setText("<= -0.1 LWD") self.awash_min_value.setText("> -0.1 LWD") self.awash_max_value.setText("<= +0.1 LWD") self.always_underwater_min_value.setText("> +0.1 LWD") self.always_underwater_max_value.setText("") self.mhw_text.setText("LWD [m]: ") self.mhw_value.setDisabled(True) else: logger.warning("unknown area") return else: logger.debug("draw elevation") if self.toggle_area.value() in [0, 2]: logger.debug("East/West Coast") self.always_dry_min_value.setText("") self.always_dry_max_value.setText("> +0.1 MHW") self.covers_and_uncovers_min_value.setText("<= +0.1 MHW") self.covers_and_uncovers_max_value.setText(">= +0.1 MLLW") self.awash_min_value.setText("< +0.1 MLLW") self.awash_max_value.setText(">= -0.1 MLLW") self.always_underwater_min_value.setText("< -0.1 MLLW") self.always_underwater_max_value.setText("") self.mhw_text.setText("MHW [m]: ") self.mhw_value.setEnabled(True) elif self.toggle_area.value() == 1: logger.debug("Great Lakes") self.always_dry_min_value.setText("") self.always_dry_max_value.setText("> +0.1 LWD") self.covers_and_uncovers_min_value.setText("<= +0.1 LWD") self.covers_and_uncovers_max_value.setText(">= +0.1 LWD") self.awash_min_value.setText("< +0.1 LWD") self.awash_max_value.setText(">= -0.1 LWD") self.always_underwater_min_value.setText("< -0.1 LWD") self.always_underwater_max_value.setText("") self.mhw_text.setText("LWD [m]: ") self.mhw_value.setDisabled(True) self.mhw_value.setText("0.0") else: logger.warning("unknown area") return self.on_calculate() def on_calculate(self): logger.debug("calculate") mhw = float(self.mhw_value.text()) depth = float(self.depth_value.text()) elevation = None watlev = None wl_dict = { "Always Dry": None, "Awash": 5, "Covers & Uncovers": 4, "Always Underwater": 3 } if self.toggle_hssd.value() == 0: logger.debug("draw HSSD 2018") if self.toggle_area.value() == 1: if depth < - 1.2192: logger.debug("Islet") elevation = -depth else: logger.debug("Rock") if depth < -0.6096: watlev = "Covers & Uncovers" elif depth < 0.6096: watlev = "Awash" else: watlev = "Always Underwater" logger.debug("%s [%s]" % (watlev, wl_dict[watlev])) else: if self.toggle_area.value() == 0: if depth < (-mhw - 0.6096): logger.debug("Islet") elevation = -mhw - depth else: logger.debug("Rock") if depth < -0.6096: watlev = "Covers & Uncovers" elif depth < 0.6096: watlev = "Awash" else: watlev = "Always Underwater" logger.debug("%s [%s]" % (watlev, wl_dict[watlev])) else: if depth < (-mhw - 0.3048): logger.debug("Islet") elevation = -mhw - depth else: logger.debug("Rock") if depth < -0.3048: watlev = "Covers & Uncovers" elif depth < 0.3048: watlev = "Awash" else: watlev = "Always Underwater" logger.debug("%s [%s]" % (watlev, wl_dict[watlev])) else: logger.debug("draw HSSD 2019") if self.toggle_area.value() == 1: if depth < - 0.1: logger.debug("Islet") elevation = -depth else: logger.debug("Rock") if depth <= -0.1: watlev = "Covers & Uncovers" elif depth <= 0.1: watlev = "Awash" else: watlev = "Always Underwater" logger.debug("%s [%s]" % (watlev, wl_dict[watlev])) else: if self.toggle_area.value() in [0, 2]: if depth < (-mhw - 0.1): logger.debug("Islet") elevation = -mhw - depth else: logger.debug("Rock") if depth <= -0.1: watlev = "Covers & Uncovers" elif depth <= 0.1: watlev = "Awash" else: watlev = "Always Underwater" logger.debug("%s [%s]" % (watlev, wl_dict[watlev])) if elevation is not None: logger.debug("elevation: %.3f" % elevation) pix = QtGui.QPixmap(os.path.join(self.media, 'islet.png')) self.out_pic_label.setPixmap(pix.scaled(60, 60, QtCore.Qt.KeepAspectRatio)) self.out_main_label.setText("I S L E T") self.out_more_label.setText("ELEVAT=%.3f" % elevation) else: pix = QtGui.QPixmap(os.path.join(self.media, 'rock.png')) self.out_pic_label.setPixmap(pix.scaled(60, 60, QtCore.Qt.KeepAspectRatio)) self.out_main_label.setText("R O C K") self.out_more_label.setText("VALSOU=%.3f, WATLEV=%s[%s]" % (depth, watlev, wl_dict[watlev])) self._draw_levels() self._draw_grid() self.c.draw()
class AppForm(QMainWindow): def __init__(self, parent=None): self.bsz = 5.0 # (arcsec) self.nnn = 500 self.dsx = self.bsz / self.nnn self.xi1 = np.linspace(-self.bsz / 2.0, self.bsz / 2.0, self.nnn) + 0.5 * self.dsx self.xi2 = np.linspace(-self.bsz / 2.0, self.bsz / 2.0, self.nnn) + 0.5 * self.dsx self.xi1, self.xi2 = np.meshgrid(self.xi1, self.xi2) self.file_name = "./ds9_images.png" a_tmp = Image.open(self.file_name) a_tmp = np.array(a_tmp) self.lgals = np.flipud(a_tmp[:, :, 0] / 256.0) self.srcs_name = "./ds9_srcs.png" s_tmp = Image.open(self.srcs_name) s_tmp = np.array(s_tmp) # # sgals_tmp = (s_tmp[:,:,0]+s_tmp[:,:,1]+s_tmp[:,:,2])/256.0/2.0 # # sgals_tmp = (s_tmp[:,:,0])/256.0 # self.sgals = self.lgals*0.0 # xoff = -15 # yoff = -10 # self.sgals[200+xoff:233+xoff,200+yoff:233+yoff] = sgals_tmp self.sgals = np.flipud(s_tmp[:, :, 0] / 256.0) st_re = nbins / 2 st_x1 = nbins / 2 st_x2 = nbins / 2 st_rc = 0 * nbins st_ql = nbins / 2 st_pa = nbins / 3 # self.lpar = np.asarray([(st_x1*self.bsz/nbins-self.bsz/2.0),(st_x2*self.bsz/nbins-self.bsz/2.0),st_re*4.0/nbins,st_rc*0.0,st_ql*1.0/nbins,st_pa*360.0/nbins]) self.lpar = np.asarray([(st_x1 * self.bsz / nbins - self.bsz / 2.0 + self.bsz / nbins / 2.0), (st_x2 * self.bsz / nbins - self.bsz / 2.0 + self.bsz / nbins / 2.0), st_re * 2.0 / nbins, st_rc * 0.0, st_ql * 1.0 / nbins, st_pa * 360.0 / nbins]) #---------------------------------------------------------------------- QMainWindow.__init__(self, parent) self.setWindowTitle('Interactive Lens Modeling') self.create_menu() self.create_main_frame() self.create_status_bar() self.textbox.setText('67.26 0.32 0.68') self.on_draw() #= QLabel("Re = %.2f" % self.lpar[2]) #label_nombre.setText("hola") def save_plot(self): file_choices = "PNG (*.png)|*.png" path = QFileDialog.getSaveFileName(self, 'Save file', '', file_choices) if path: self.canvas.print_figure(path, dpi=self.dpi) self.statusBar().showMessage('Saved to %s' % path, 2000) def on_about(self): msg = """ A demo of using PyQt with matplotlib: * Use the matplotlib navigation bar * Add values to the text box and press Enter (or click "Draw") * Show or hide the grid * Drag the slider to modify the width of the bars * Save the plot to a file using the File menu * Click on a bar to receive an informative message """ QMessageBox.about(self, "About the demo", msg.strip()) def on_pick(self, event): # The event received here is of the type # matplotlib.backend_bases.PickEvent # # It carries lots of information, of which we're using # only a small amount here. # box_points = event.artist.get_bbox().get_points() msg = "You've clicked on a bar with coords:\n %s" % box_points QMessageBox.information(self, "Click!", msg) def on_draw(self): """ Redraws the figure """ l_xcen = self.slider_x1.value( ) * self.bsz / nbins - self.bsz / 2.0 + self.bsz / nbins / 2.0 # x position of center (also try (0.0,0.14) l_ycen = self.slider_x2.value( ) * self.bsz / nbins - self.bsz / 2.0 + self.bsz / nbins / 2.0 # y position of center l_re = self.slider_re.value() * 2.0 / nbins # Einstein radius of lens. l_rc = 0.0 # Core size of lens (in units of Einstein radius). l_axrat = self.slider_ql.value() * 1.0 / nbins # Axis ratio of lens. l_pa = self.slider_la.value() * 360.0 / nbins # Orintation of lens. self.lpar = np.asarray([l_xcen, l_ycen, l_re, l_rc, l_axrat, l_pa]) #---------------------------------------------------------------------- g_amp = 1.0 # peak brightness value g_sig = self.slider_rh.value( ) * 0.5 / nbins # Gaussian "sigma" (i.e., size) g_xcen = self.slider_y1.value( ) * self.bsz / 4.0 / nbins - self.bsz / 8.0 + self.bsz / nbins / 8.0 # x position of center (also try (0.0,0.14) g_ycen = self.slider_y2.value( ) * self.bsz / 4.0 / nbins - self.bsz / 8.0 + self.bsz / nbins / 8.0 # y position of center g_axrat = self.slider_qs.value( ) * 1.0 / nbins # minor-to-major axis ratio g_pa = self.slider_sa.value( ) * 360.0 / nbins # major-axis position angle (degrees) c.c.w. from x axis self.spar = np.asarray([g_xcen, g_ycen, g_sig, g_amp, g_axrat, g_pa]) print "plot***", self.spar #---------------------------------------------------------------------- g_limage, g_source, mua, yi1, yi2 = ll.lensed_images( self.xi1, self.xi2, self.lpar, self.spar) #--------------------------lens images contour------------------------ levels = [ 0.5, ] levels_imgs = [0.0, 0.08, 0.1, 0.2, 0.3, 0.4, 0.5] self.axesa.clear() self.axesa.set_xlim(-self.bsz / 8.0, self.bsz / 8.0) self.axesa.set_ylim(-self.bsz / 8.0, self.bsz / 8.0) self.axesa.set_xticks([-0.4, -0.2, 0.0, 0.2, 0.4]) self.axesa.set_yticks([-0.4, -0.2, 0.0, 0.2, 0.4]) self.axesa.contourf(self.xi1, self.xi2, self.sgals, levels_imgs, cmap=pl.cm.gray) self.axesa.contour(self.xi1, self.xi2, g_source, levels, colors=('deepskyblue')) self.axesa.contour(yi1, yi2, mua, 0, colors=('r'), linewidths=2.0) self.axesb.clear() # pl.xticks([-2.0, -1.0, 0.0, 1.0, 2.0]) # pl.yticks([-2.0, -1.0, 0.0, 1.0, 2.0]) self.axesb.set_xlim(-self.bsz / 2.0, self.bsz / 2.0) self.axesb.set_ylim(-self.bsz / 2.0, self.bsz / 2.0) self.axesb.contourf(self.xi1, self.xi2, self.lgals, levels_imgs, cmap=pl.cm.gray) self.axesb.contour(self.xi1, self.xi2, g_limage, levels, colors=('deepskyblue')) self.axesb.contour(self.xi1, self.xi2, mua, colors=('r'), linewidths=2.0) self.canvas.draw() self.slider_label_re.setText("Re: %.2f" % self.lpar[2]) # print "Drag", self.lpar # @profile def create_main_frame(self): self.main_frame = QWidget() #self.main_frame.resize(800, 400) self.main_frame.setFixedSize(820, 700) self.dpi = 80 self.fig = pl.figure(num=None, figsize=(10, 5), dpi=self.dpi, facecolor='w', edgecolor='k') self.canvas = FigureCanvas(self.fig) self.canvas.setParent(self.main_frame) self.axesa = pl.axes([0.05, 0.1, 0.4, 0.8]) self.axesb = pl.axes([0.55, 0.1, 0.4, 0.8]) # Bind the 'pick' event for clicking on one of the bars # self.canvas.mpl_connect('pick_event', self.on_pick) # Create the navigation toolbar, tied to the canvas # self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame) # Other GUI controls # self.textbox = QLineEdit() self.textbox.setMinimumWidth(200) self.textbox.editingFinished.connect(self.on_draw) self.cb_cosmo = QComboBox() self.cb_cosmo.addItems( ["Planck15", "WMP9", "Concordance", "Einstein-deSitter"]) #self.cb_cosmo.currentIndexChanged.connect(self.selectionchange) self.cb_models = QComboBox() self.cb_models.addItems(["SIE", "NFW", "PIEMD"]) #self.cb_models.currentIndexChanged.connect(self.selectionchange) self.cb_codes = QComboBox() self.cb_codes.addItems( ["Scipy", "Q-Lens", "Lensed", "LensTool", "Gravlens", "Glafic"]) #self.cb.currentIndexChanged.connect(self.selectionchange) self.draw_button = QPushButton("&Optimize") #self.draw_button.clicked.connect(lambda: self.optmization_actions("lensed")) self.draw_button.clicked.connect(self.optimization_actions) #self.grid_cb = QCheckBox("Show &Grid") #self.grid_cb.setChecked(False) #self.grid_cb.stateChanged.connect(self.on_draw) #int self.slider_label_re = QLabel("Re = %.2f" % self.lpar[2]) self.slider_re = QSlider(Qt.Horizontal) self.slider_re.setMinimumWidth(270) self.slider_re.setMaximumWidth(270) self.slider_re.setRange(1, nbins) self.slider_re.setValue(nbins / 2) self.slider_re.setTracking(True) #self.slider_re.setTickPosition(QSlider.TicksBothSides) self.slider_re.valueChanged.connect(self.on_draw) #int slider_label_x1 = QLabel("Lens Position x1") self.slider_x1 = QSlider(Qt.Horizontal) self.slider_x1.setMinimumWidth(270) self.slider_x1.setMaximumWidth(270) self.slider_x1.setRange(1, nbins) self.slider_x1.setValue(nbins / 2) self.slider_x1.setTracking(True) #self.slider_x1.setTickPosition(QSlider.TicksBothSides) self.slider_x1.valueChanged.connect(self.on_draw) #int slider_label_x2 = QLabel("Lens Position x2") self.slider_x2 = QSlider(Qt.Horizontal) self.slider_x2.setMinimumWidth(270) self.slider_x2.setMaximumWidth(270) self.slider_x2.setRange(1, nbins) self.slider_x2.setValue(nbins / 2) self.slider_x2.setTracking(True) #self.slider_x2.setTickPosition(QSlider.TicksBothSides) self.slider_x2.valueChanged.connect(self.on_draw) #int slider_label_ql = QLabel("Ellipticity L") self.slider_ql = QSlider(Qt.Horizontal) self.slider_ql.setMinimumWidth(270) self.slider_ql.setMaximumWidth(270) self.slider_ql.setRange(1, nbins) self.slider_ql.setValue(nbins / 2) self.slider_ql.setTracking(True) #self.slider_ql.setTickPosition(QSlider.TicksBothSides) self.slider_ql.valueChanged.connect(self.on_draw) #int slider_label_la = QLabel("Orintation L") self.slider_la = QSlider(Qt.Horizontal) self.slider_la.setMinimumWidth(270) self.slider_la.setMaximumWidth(270) self.slider_la.setRange(1, nbins) self.slider_la.setValue(nbins / 3) self.slider_la.setTracking(True) #self.slider_la.setTickPosition(QSlider.TicksBothSides) self.slider_la.valueChanged.connect(self.on_draw) #int slider_label_rh = QLabel("Half-light Radius") self.slider_rh = QSlider(Qt.Horizontal) self.slider_rh.setMinimumWidth(270) self.slider_rh.setMaximumWidth(270) self.slider_rh.setRange(1, nbins) self.slider_rh.setValue(nbins / 2) self.slider_rh.setTracking(True) #self.slider_rh.setTickPosition(QSlider.TicksBothSides) self.slider_rh.valueChanged.connect(self.on_draw) #int slider_label_y1 = QLabel("Source Position y1") self.slider_y1 = QSlider(Qt.Horizontal) self.slider_y1.setMinimumWidth(270) self.slider_y1.setMaximumWidth(270) self.slider_y1.setRange(1, nbins) self.slider_y1.setValue(nbins / 2) self.slider_y1.setTracking(True) #self.slider_y1.setTickPosition(QSlider.TicksBothSides) self.slider_y1.valueChanged.connect(self.on_draw) #int slider_label_y2 = QLabel("Source Position y2") self.slider_y2 = QSlider(Qt.Horizontal) self.slider_y2.setMinimumWidth(270) self.slider_y2.setMaximumWidth(270) self.slider_y2.setRange(1, nbins) self.slider_y2.setValue(nbins / 2) self.slider_y2.setTracking(True) #self.slider_y2.setTickPosition(QSlider.TicksBothSides) self.slider_y2.valueChanged.connect(self.on_draw) #int slider_label_qs = QLabel("Ellipticity S") self.slider_qs = QSlider(Qt.Horizontal) self.slider_qs.setMinimumWidth(270) self.slider_qs.setMaximumWidth(270) self.slider_qs.setRange(1, nbins) self.slider_qs.setValue(nbins / 2) self.slider_qs.setTracking(True) #self.slider_qs.setTickPosition(QSlider.TicksBothSides) self.slider_qs.valueChanged.connect(self.on_draw) #int slider_label_sa = QLabel("Orintation S") self.slider_sa = QSlider(Qt.Horizontal) self.slider_sa.setMinimumWidth(270) self.slider_sa.setMaximumWidth(270) self.slider_sa.setRange(1, nbins) self.slider_sa.setValue(nbins / 3) self.slider_sa.setTracking(True) #self.slider_sa.setTickPosition(QSlider.TicksBothSides) self.slider_sa.valueChanged.connect(self.on_draw) #int # # Layout with box sizers # hbox = QHBoxLayout() for w in [ self.textbox, self.cb_cosmo, self.cb_models, self.cb_codes, self.draw_button ]: hbox.addWidget(w) hbox.setAlignment(w, Qt.AlignVCenter) vbox = QVBoxLayout() vbox.addWidget(self.mpl_toolbar) vbox.addWidget(self.canvas) hbox_s1 = QHBoxLayout() for w in [ self.slider_label_re, self.slider_re, slider_label_rh, self.slider_rh ]: hbox_s1.addWidget(w) hbox_s1.setAlignment(w, Qt.AlignLeft) hbox_s2 = QHBoxLayout() for w in [ slider_label_x1, self.slider_x1, slider_label_y1, self.slider_y1 ]: hbox_s2.addWidget(w) hbox_s2.setAlignment(w, Qt.AlignLeft) hbox_s3 = QHBoxLayout() for w in [ slider_label_x2, self.slider_x2, slider_label_y2, self.slider_y2 ]: hbox_s3.addWidget(w) hbox_s3.setAlignment(w, Qt.AlignLeft) hbox_s4 = QHBoxLayout() for w in [ slider_label_ql, self.slider_ql, slider_label_qs, self.slider_qs ]: hbox_s4.addWidget(w) hbox_s4.setAlignment(w, Qt.AlignLeft) hbox_s5 = QHBoxLayout() for w in [ slider_label_la, self.slider_la, slider_label_sa, self.slider_sa ]: hbox_s5.addWidget(w) hbox_s5.setAlignment(w, Qt.AlignLeft) vbox.addLayout(hbox) vbox.addLayout(hbox_s1) vbox.addLayout(hbox_s2) vbox.addLayout(hbox_s3) vbox.addLayout(hbox_s4) vbox.addLayout(hbox_s5) self.main_frame.setLayout(vbox) self.setCentralWidget(self.main_frame) def optimization_actions(self): print "Optimizing..." lpar_new, spar_new = ff.optimize_pars(self.xi1, self.xi2, self.lgals.ravel(), self.lpar, self.spar) g_limage, g_source, mua, yi1, yi2 = ll.lensed_images( self.xi1, self.xi2, lpar_new, spar_new) print "Done." self.slider_re.setValue(round(lpar_new[2] / 2.0 * nbins)) self.slider_x1.setValue( round((lpar_new[0] + self.bsz / 2.0 - self.bsz / nbins / 2.0) / self.bsz * nbins)) self.slider_x2.setValue( round((lpar_new[1] + self.bsz / 2.0 - self.bsz / nbins / 2.0) / self.bsz * nbins)) self.slider_ql.setValue(round(lpar_new[4] * nbins)) self.slider_la.setValue(round(lpar_new[5] / 360.0 * nbins)) self.slider_rh.setValue(round(spar_new[2] / 0.5 * nbins)) self.slider_y1.setValue( round((spar_new[0] + self.bsz / 8.0 - self.bsz / nbins / 8.0) / (self.bsz / 4.0) * nbins)) self.slider_y2.setValue( round((spar_new[1] + self.bsz / 8.0 - self.bsz / nbins / 8.0) / (self.bsz / 4.0) * nbins)) self.slider_qs.setValue(round(spar_new[4] * nbins)) self.slider_sa.setValue(round(spar_new[5] / 360.0 * nbins)) levels = [ 0.5, ] levels_imgs = [0.0, 0.08, 0.1, 0.2, 0.3, 0.4, 0.5] self.axesa.clear() # pl.xticks([-2.0, 1.0, 0.0, 1.0, 2.0]) # pl.yticks([-2.0, 1.0, 0.0, 1.0, 2.0]) self.axesa.set_xlim(-self.bsz / 8.0, self.bsz / 8.0) self.axesa.set_ylim(-self.bsz / 8.0, self.bsz / 8.0) self.axesa.contourf(self.xi1, self.xi2, self.sgals, levels_imgs, cmap=pl.cm.gray) self.axesa.contour(self.xi1, self.xi2, g_source, levels, colors=('deepskyblue')) self.axesa.contour(yi1, yi2, mua, 0, colors=('g'), linewidths=2.0) self.axesb.clear() # pl.xticks([-0.2,-0.1,0.0,0.1,0.2]) # pl.yticks([-0.2,-0.1,0.0,0.1,0.2]) self.axesb.set_xlim(-self.bsz / 2.0, self.bsz / 2.0) self.axesb.set_ylim(-self.bsz / 2.0, self.bsz / 2.0) self.axesb.contourf(self.xi1, self.xi2, self.lgals, levels_imgs, cmap=pl.cm.gray) self.axesb.contour(self.xi1, self.xi2, g_limage, levels, colors=('deepskyblue')) self.axesb.contour(self.xi1, self.xi2, mua, colors=('r'), linewidths=2.0) self.canvas.draw() print "opt----", spar_new def create_status_bar(self): self.status_text = QLabel("This is a statusbar") self.statusBar().addWidget(self.status_text, 1) def create_menu(self): self.file_menu = self.menuBar().addMenu("&File") load_file_action = self.create_action("&Save plot", shortcut="Ctrl+S", slot=self.save_plot, tip="Save the plot") quit_action = self.create_action("&Quit", slot=self.close, shortcut="Ctrl+Q", tip="Close the application") self.add_actions(self.file_menu, (load_file_action, None, quit_action)) self.help_menu = self.menuBar().addMenu("&Help") about_action = self.create_action("&About", shortcut='F1', slot=self.on_about, tip='About the demo') self.add_actions(self.help_menu, (about_action, )) def add_actions(self, target, actions): for action in actions: if action is None: target.addSeparator() else: target.addAction(action) def create_action(self, text, slot=None, shortcut=None, icon=None, tip=None, checkable=False, signal="triggered()"): action = QAction(text, self) if icon is not None: action.setIcon(QIcon(":/%s.png" % icon)) if shortcut is not None: action.setShortcut(shortcut) if tip is not None: action.setToolTip(tip) action.setStatusTip(tip) if slot is not None: action.triggered.connect(slot) if checkable: action.setCheckable(True) return action
class PfGui(QtWidgets.QMainWindow): def __init__(self): super().__init__() self.ui = UiMainWindow(self) self.ui.push_button.setEnabled(False) self.results = { 'peak_intensity_matrix': None, 'index': None, 'square_instances': None } self.instance = Reader.TwoDScan() self.selected_square = [] self.cid_press = None self.cid_release = None self.cid_motion = None os.chdir(os.path.dirname(sys.argv[0])) self.gui_cfg = configparser.ConfigParser() self.gui_cfg.read('GUI.cfg') self.ui.actionOpen_2.triggered.connect(self.open_file) self.ui.actionSave.triggered.connect(self.save_image) self.figure = plt.figure() self.figure.set_size_inches((30, 6)) self.canvas = FigureCanvas(self.figure) self.ui.verticalLayout.addWidget(self.canvas) self.connect_canvas() self.ui.push_button.clicked.connect(self.automatically_detect_peak) def open_file(self): self.results = { 'peak_intensity_matrix': None, 'index': None, 'square_instances': None } dir_item = self.gui_cfg.get('DEFAULT', 'directory') or '\home' raw_file_name = QtWidgets.QFileDialog.getOpenFileName( self, 'Open file', dir_item, "RAW files (*.raw)") raw_file_name = str(raw_file_name[0]) if raw_file_name: raw_instance = Reader.RawFile(raw_file_name).read_data() self.figure.clear() raw_instance.plot(is_show=0, is_save=0) self.canvas.draw() self.ui.push_button.setEnabled(True) self.instance = raw_instance self.gui_cfg.set('DEFAULT', 'directory', os.path.dirname(raw_file_name)) else: pass def save_image(self): supported_file_dict = self.canvas.get_supported_filetypes() supported_file_list = [ "{0} (*.{1})".format(supported_file_dict[i], i) for i in supported_file_dict ] supported_file_str = ";;".join(supported_file_list) dir_item = self.gui_cfg.get('DEFAULT', 'directory') or '\home' image_file_name = QtWidgets.QFileDialog.getSaveFileName( self, 'Open file', dir_item, supported_file_str) image_file_name = str(image_file_name[0]) if image_file_name: self.figure.savefig(image_file_name, bbox_inches='tight') else: return def save_config(self): script_path = os.path.dirname(sys.argv[0]) with open(os.path.join(script_path, 'GUI.cfg'), 'w') as config_file: self.gui_cfg.write(config_file) def automatically_detect_peak(self): if self.results['square_instances']: for i in self.results['square_instances']: i.remove() results_dict = self.instance.plot_square(is_show=0, is_save=0) self.results = results_dict self.canvas.draw() v_fration = self.instance.mt_intensity_to_fraction(results_dict) data_dict = { 'Peak Intensity': results_dict['peak_intensity_matrix'], 'Volume Fraction': v_fration } self.instance.print_result_csv(self.instance.scan_dict['sample'], data_dict) self.update_fraction_list(v_fration) bg_err = (self.instance.get_bg_int() / (self.instance.get_bg_int() + results_dict['peak_intensity_matrix'].mean())) self.ui.statusbar.showMessage("{0}%".format(bg_err * 100)) def connect_canvas(self): self.cid_press = self.canvas.mpl_connect('button_press_event', self.on_press) self.cid_release = self.canvas.mpl_connect('button_release_event', self.on_release) self.cid_motion = self.canvas.mpl_connect('motion_notify_event', self.on_motion) def on_press(self, event): ax_list = self.figure.axes if self.results['square_instances'] is None: return if event.inaxes != ax_list[0]: return for square in self.results['square_instances']: if [event.xdata, event.ydata] in square: self.selected_square.append(square) def on_motion(self, event): if not self.selected_square: return if event.inaxes != self.figure.axes[0]: return [init_mouse_y, init_mouse_x] = self.selected_square[0].cr_list for square in self.selected_square: dy = event.xdata - init_mouse_x + 30 dx = event.ydata - init_mouse_y square.move((dx, dy)) self.canvas.draw() def update_fraction_list(self, results): text_label_list = [ self.ui.mt_a_value, self.ui.mt_d_value, self.ui.mt_c_value, self.ui.mt_b_value ] for (i, j) in zip(text_label_list, results): i.setText(str(j)) def on_release(self, event): if self.results['square_instances'] is None: return self.selected_square = [] outer_index_list = [ i.cr_list for i in self.results['square_instances'][:4] ] results_dict = self.instance.plot_square( is_show=0, is_save=0, is_plot=0, outer_index_list=outer_index_list) results = self.instance.mt_intensity_to_fraction(results_dict) data_dict = { 'Peak Intensity': results_dict['peak_intensity_matrix'], 'Volume Fraction': results } self.instance.print_result_csv(self.instance.scan_dict['sample'], data_dict) self.update_fraction_list(results) def disconnect(self): self.canvas.mpl_disconnect(self.cid_press) self.canvas.mpl_disconnect(self.cid_release) self.canvas.mpl_disconnect(self.cid_motion)
class LogTab(QWidget): def __init__(self): super(LogTab, self).__init__() # Class variables. # self.graphXValueList = [] # self.graphYValueList = [] # self.counter = 0 self.currentlySelectedRoastLog = {} self.currentlySelectedRoastLogPath = "" # Create the tab ui. self.create_ui() def create_ui(self): # Create the main layout for the roast tab. self.layout = QGridLayout() # Create log browser. self.create_log_browser() self.layout.addWidget(self.logBrowser, 0, 0) # Create graph widget. self.create_graph() self.layout.addWidget(self.graphWidget, 0, 0) self.layout.setColumnStretch(0, 1) # Create right pane. # self.rightPane = self.create_right_pane() # self.layout.addLayout(self.rightPane, 0, 1) # Set main layout for widget. self.setLayout(self.layout) def create_log_browser(self): """Creates the side panel to browse all the files in the log folder.""" # Creates model with all information about the files in ./recipes self.model = LogModel() self.model.setRootPath(os.path.expanduser('~/Documents/Roastero/log/')) # Create a TreeView to view the information from the model self.logBrowser = QTreeView() self.logBrowser.setModel(self.model) self.logBrowser.setRootIndex(self.model.index(os.path.expanduser('~/Documents/Roastero/log/'))) self.logBrowser.setFocusPolicy(Qt.NoFocus) self.logBrowser.header().close() self.logBrowser.setAnimated(True) self.logBrowser.setIndentation(0) # Hides all the unecessary columns created by the model self.logBrowser.setColumnHidden(0, True) self.logBrowser.setColumnHidden(1, True) self.logBrowser.setColumnHidden(2, True) self.logBrowser.setColumnHidden(3, True) self.logBrowser.clicked.connect(self.on_logBrowser_clicked) def create_graph(self): # Create the graph widget. self.graphWidget = QWidget(self) self.graphWidget.setObjectName("graph") # Style attributes of matplotlib. plt.rcParams['lines.linewidth'] = 3 plt.rcParams['lines.color'] = '#2a2a2a' plt.rcParams['font.size'] = 10. self.graphFigure = plt.figure(facecolor='#444952') self.graphCanvas = FigureCanvas(self.graphFigure) # Add graph widgets to layout for graph. graphVerticalBox = QVBoxLayout() graphVerticalBox.addWidget(self.graphCanvas) self.graphWidget.setLayout(graphVerticalBox) # # Animate the the graph with new data # animateGraph = animation.FuncAnimation(self.graphFigure, # self.graph_draw, interval=1000) def graph_draw(self, graphXValueList = None, graphYValueList = None): self.graphFigure.clear() self.graphAxes = self.graphFigure.add_subplot(111) self.graphAxes.plot_date(graphXValueList, graphYValueList, '#8ab71b') # Add formatting to the graphs. self.graphAxes.set_ylabel('TEMPERATURE (°F)') self.graphAxes.set_xlabel('TIME') self.graphFigure.subplots_adjust(bottom=0.2) ax = self.graphAxes.get_axes() ax.xaxis.set_major_formatter(DateFormatter('%M:%S')) ax.set_axis_bgcolor('#23252a') self.graphCanvas.draw() def on_logBrowser_clicked(self, index): """This method is used when a log is selected in the left column.""" indexItem = self.model.index(index.row(), 0, index.parent()) self.selectedFilePath = self.model.filePath(indexItem) # Allow single click expanding of folders if os.path.isdir(self.selectedFilePath): if self.logBrowser.isExpanded(indexItem): self.logBrowser.collapse(indexItem) else: self.logBrowser.expand(indexItem) # Handles when a file is clicked else: # Load roast log information from file self.load_roast_log_file(self.selectedFilePath) def load_roast_log_file(self, filePath): """Used to load file from a path into selected roast log object.""" with open(filePath) as json_data: roastLogObject = json.load(json_data) self.currentlySelectedRoastLog = roastLogObject self.currentlySelectedRoastLogPath = filePath
class Window(QtWidgets.QDialog): def __init__(self, parent=None): super(Window, self).__init__(parent) self.runStatus = False self.setGeometry(100, 100, 1200, 700) self.setFixedSize(1200, 700) self.setWindowTitle('1D Forward Modeling Magnetotelluric') self.setWindowIcon(QtGui.QIcon('../images/icon.png')) self.figure = Figure() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas, self) self.buttonPlot = QtWidgets.QPushButton('Run') self.buttonPlot.clicked.connect(self.get_data) self.buttonAbout = QtWidgets.QPushButton('About') self.buttonAbout.clicked.connect(self.form_about) self.buttonSModel = QtWidgets.QPushButton('Save Model') self.buttonSModel.clicked.connect(self.save_model) self.buttonSData = QtWidgets.QPushButton('Save Data') self.buttonSData.clicked.connect(self.save_data) textMaxPeriode = QtWidgets.QLabel('Maximum Period:') textNumDec = QtWidgets.QLabel('Number of Decade:') textPerDec = QtWidgets.QLabel('Periode per Decade:') self.lineEditMaxPeriode = QtWidgets.QLineEdit('1000', self) self.lineEditNumDec = QtWidgets.QLineEdit('6', self) self.lineEditPerDec = QtWidgets.QLineEdit('10', self) textRes = QtWidgets.QLabel('Resistivity:') textThi = QtWidgets.QLabel('Thickness:') self.lineEditRes = QtWidgets.QLineEdit('100, 10, 1000', self) self.lineEditThi = QtWidgets.QLineEdit('1000, 2000', self) horizontalLayout1 = QtWidgets.QHBoxLayout() horizontalLayout1.addWidget(textMaxPeriode) horizontalLayout1.addWidget(self.lineEditMaxPeriode) horizontalLayout1.addWidget(textNumDec) horizontalLayout1.addWidget(self.lineEditNumDec) horizontalLayout1.addWidget(textPerDec) horizontalLayout1.addWidget(self.lineEditPerDec) horizontalLayout2 = QtWidgets.QHBoxLayout() horizontalLayout2.addWidget(textRes) horizontalLayout2.addWidget(self.lineEditRes) horizontalLayout2.addWidget(textThi) horizontalLayout2.addWidget(self.lineEditThi) horizontalLayout3 = QtWidgets.QHBoxLayout() horizontalLayout3.addWidget(self.buttonPlot) horizontalLayout3.addWidget(self.buttonSModel) horizontalLayout3.addWidget(self.buttonSData) horizontalLayout3.addWidget(self.buttonAbout) verticalLayout = QtWidgets.QVBoxLayout() verticalLayout.addLayout(horizontalLayout1) verticalLayout.addLayout(horizontalLayout2) verticalLayout.addWidget(self.toolbar) verticalLayout.addWidget(self.canvas) verticalLayout.addLayout(horizontalLayout3) self.setLayout(verticalLayout) def form_about(self): QtWidgets.QMessageBox.information( self, '1DForModMT', '1D Forward Modeling Magnetotelluric is created by:' '\n' '\nEvi Muharoroh \tUnila \t\[email protected]' '\nArif Darmawan \tElnusa \t\[email protected]' '\n \t\tRiflab \t\[email protected]' '\n' '\nThis is free and opensource software under GNU General Public Licensed.' '\nUse at your own risk but enjoy if it works for you' '\nOther softwares can be downloaded at https://github.com/riflab/' '\n' '\nVersion 1.0_20171121' '\nDate: 21 November 2017' '\n' '\nReference:' '\nGrandis, H. (1999). An alternative algorithm for one-dimensional magnetotelluric response calculation. Computer & Geoscienes 25 (1999) 199-125. ', QtWidgets.QMessageBox.Ok) def get_data(self): self.runStatus = True # get input ---------------------------------------------------------- # min_freq = 1/ float(self.lineEditMaxPeriode.text()) try: self.min_freq = 1 / float(self.lineEditMaxPeriode.text()) except ValueError: self.runStatus = False QtWidgets.QMessageBox.warning( self, "Warning", "%s" % ('Wrong input!.\nMaximum period must be integer or float')) try: self.total_dec = int(self.lineEditNumDec.text()) except ValueError: self.runStatus = False QtWidgets.QMessageBox.warning( self, "Warning", "%s" % ('Wrong input!.\nNumber of decade must be integer')) try: self.freq_per_dec = int(self.lineEditPerDec.text()) except ValueError: self.runStatus = False QtWidgets.QMessageBox.warning( self, "Warning", "%s" % ('Wrong input!.\nFrequency per decade must be integer')) try: res = (self.lineEditRes.text()).split(',') self.ress = [] for i in range(0, len(res)): self.ress.append(float(res[i])) except ValueError: self.runStatus = False QtWidgets.QMessageBox.warning( self, "Warning", "%s" % ('Wrong input!.\nResistivity must be integer or float')) try: thi = (self.lineEditThi.text()).split(',') self.thii = [] for i in range(0, len(thi)): self.thii.append(float(thi[i])) except ValueError: self.runStatus = False QtWidgets.QMessageBox.warning( self, "Warning", "%s" % ('Wrong input!.\nThickness must be integer or float')) self.compute() def compute(self): # compute periode ---------------------------------------------------------- nfreq = self.total_dec * self.freq_per_dec + 1 frac = np.exp(np.log(10) / self.freq_per_dec) freq = [] freq.append(self.min_freq) for i in range(1, nfreq): freq.append(freq[i - 1] * frac) self.per = [] nper = len(freq) for i in range(0, nper): self.per.append(1 / freq[i]) # compute depth ---------------------------------------------------------- self.depth = [] self.depth.append(1.0) a = 0 for i in range(len(self.thii)): a += self.thii[i] self.depth.append(a) self.depth.append(a) self.depth.append(a * 1000000) # 1000000 denotes infinity # compute ress self.resss = [] for i in range(len(self.ress)): self.resss.append(self.ress[i]) self.resss.append(self.ress[i]) # compute forward 1D ---------------------------------------------------------- self.rho, self.phas = FFMT1D.ffmt1d(self.ress, self.thii, self.per) self.plot() def plot(self): # create an axis ax1 = self.figure.add_subplot(1, 4, 1) ax2 = self.figure.add_subplot(2, 4, (2, 4)) ax3 = self.figure.add_subplot(2, 4, (6, 8)) # discards the old graph ax1.clear() ax2.clear() ax3.clear() # plot data ax1.loglog(self.resss, self.depth, '-', linewidth=0.7) ax1.set_xlabel('Resistivity (ohm meter)', fontsize=8) ax1.set_ylabel('Depth (m)', fontsize=8) ax1.set_title('Model', fontsize=8) ax1.set_ylim(1, max(self.depth) / 100000) ax1.invert_yaxis() ax2.loglog(self.per, self.rho, '*-', linewidth=0.7, markersize=4) ax2.set_ylim(1, 1000) ax2.set_xlabel('Period (s)', fontsize=8) ax2.set_ylabel('Ohm meter', fontsize=8) ax2.set_title('Apparent Resistivity', fontsize=8) ax3.semilogx(self.per, self.phas, '*-', linewidth=0.7, markersize=4) ax3.set_ylim(0, 90) ax3.set_xlabel('Period (s)', fontsize=8) ax3.set_ylabel('Degree', fontsize=8) ax3.set_title('Phase', fontsize=8) self.figure.tight_layout() self.canvas.draw() def save_model(self): if self.runStatus == True: fileModel = QtWidgets.QFileDialog.getSaveFileName( self, 'Save Model File') text_file = open(fileModel, "w") text_file.write('%-15s %s\n' % ('Depth (m)', 'Resistivity')) for i in range(len(self.resss) - 1): text_file.write('%-15s %s\n' % (self.depth[i], self.resss[i])) text_file.write('%-15s %s\n' % ('infinity', self.resss[len(self.resss) - 1])) text_file.close() QtWidgets.QMessageBox.information( self, "Success", "%s" % ('Write model file, done!')) else: QtWidgets.QMessageBox.warning( self, "Warning", "%s" % ('You must run 1D Forward before save the Model')) def save_data(self): if self.runStatus == True: fileData = QtWidgets.QFileDialog.getSaveFileName( self, 'Save Data File') text_fileD = open(fileData, "w") text_fileD.write('%-15s %-15s %-15s\n' % ('Period (s)', 'App. Res.', 'Phase')) for i in range(len(self.per)): text_fileD.write('%-15.2f %-15.2f %-15.2f\n' % (self.per[i], self.rho[i], self.phas[i])) text_fileD.close() QtWidgets.QMessageBox.information( self, "Success", "%s" % ('Write model file, done!')) else: QtWidgets.QMessageBox.warning( self, "Warning", "%s" % ('You must run 1D Forward before save the Data'))
class Window(QDialog): def __init__(self, params_object, library_object, group, parent=None): QDialog.__init__(self, parent) self.params = params_object self.library = library_object self.group = group matplotlib.projections.register_projection(My_Axes) self.region_colors = {0:'gray', 1:'red', 2:'green', 3:'orange', 4:'teal', 5:'pink', 6:'cyan', 7:'magenta', 8:'gold'} if self.group == 'ALL': self.plural_group = "s" else: self.plural_group = "" self.setWindowTitle("NMRmix: Peaks Histogram for %s Group%s" % (self.group, self.plural_group)) self.scale = 1.05 self.setAttribute(Qt.WA_DeleteOnClose, True) self.createMainFrame() def createMainFrame(self): self.fig = plt.gcf() self.fig.patch.set_facecolor('white') self.canvas = FigureCanvas(self.fig) self.canvas.setParent(self) self.canvas.setFocusPolicy(Qt.StrongFocus) self.canvas.setFocus() self.canvas.setMinimumHeight(100) self.canvas.setMinimumWidth(100) self.mpl_toolbar = NavigationToolbar2(self.canvas, self) self.mpl_toolbar.hide() self.mpl_toolbar.pan() self.canvas.mpl_connect('scroll_event', self.zooming) ins = "Left-click+drag to pan x-axis / Right-click+drag to zoom x-axis" self.instructionLabel = QLabel(ins) self.instructionLabel.setStyleSheet('QLabel{qproperty-alignment: AlignCenter; font-size: 12px;}') self.showignoredregionsCheckBox = QCheckBox("Show Ignored Regions") self.showignoredregionsCheckBox.setChecked(True) self.showignoredregionsCheckBox.setToolTip("Tooltip") # TODO: Tooltip self.showignoredregionsCheckBox.stateChanged.connect(self.handleIgnored) self.closeButton = QPushButton("Close") self.closeButton.setStyleSheet("QPushButton{color: red; font-weight: bold;}") self.closeButton.clicked.connect(self.closeEvent) self.saveButton = QPushButton("Save") self.saveButton.setStyleSheet("QPushButton{color: green; font-weight: bold;}") self.saveButton.clicked.connect(self.saveResults) self.resetButton = QPushButton("Reset") self.resetButton.setStyleSheet("QPushButton{color: blue; font-weight: bold;}") self.resetButton.clicked.connect(self.resetGraph) self.calculateAllHistogram() self.calculateIntenseHistogram() self.drawIgnoredRegions() winLayout = QVBoxLayout(self) winLayout.addWidget(self.canvas) winLayout.addWidget(self.instructionLabel) winLayout.addWidget(self.showignoredregionsCheckBox) buttonLayout = QHBoxLayout() buttonLayout.addWidget(self.closeButton) buttonLayout.addWidget(self.resetButton) buttonLayout.addWidget(self.saveButton) winLayout.addLayout(buttonLayout) winLayout.setAlignment(self.showignoredregionsCheckBox, Qt.AlignCenter) self.fig.tight_layout(pad=3) self.canvas.draw() def calculateAllHistogram(self): self.ax1 = self.fig.add_subplot(211, projection="My_Axes") self.ax1.set_title("Peaks Histogram for %s Group%s" % (self.group, self.plural_group), fontweight='bold') self.ax1.set_xlabel("Chemical Shift (ppm)", fontweight='bold') self.ax1.set_ylabel("Number of Peaks", fontweight='bold') data = list(self.library.stats[self.group]['Peaklist']) y, binEdges = np.histogram(data, bins=np.arange(-1, 12, 0.02)) bincenters = 0.5 * (binEdges[1:] + binEdges[:-1]) self.ax1.set_xlim(self.params.shift_range[self.params.nuclei]) self.upper_ylim_all = max(y)+(math.ceil(max(y)*0.05)) self.ax1.set_ylim([0, self.upper_ylim_all]) self.ax1.plot(bincenters, y, '-', color='blue') def calculateIntenseHistogram(self): self.ax2 = self.fig.add_subplot(212, sharex=self.ax1, projection="My_Axes") self.ax2.set_title("Intense Peaks Histogram for %s Group%s" % (self.group, self.plural_group), fontweight='bold') self.ax2.set_xlabel("Chemical Shift (ppm)", fontweight='bold') self.ax2.set_ylabel("Number of Peaks", fontweight='bold') data = list(self.library.stats[self.group]['Intense Peaklist']) y, binEdges = np.histogram(data, bins=np.arange(-1, 12, 0.02)) bincenters = 0.5 * (binEdges[1:] + binEdges[:-1]) self.ax2.set_xlim([12, -1]) self.upper_ylim_intense = max(y)+(math.ceil(max(y)*0.05)) self.ax2.set_ylim([0, self.upper_ylim_intense]) self.ax2.plot(bincenters, y, '-', color='purple') def resetGraph(self): self.mpl_toolbar.home() def drawIgnoredRegions(self): groups = ['ALL'] if self.group != 'ALL': groups.append(self.group) for region in self.library.ignored_regions: group = self.library.ignored_regions[region][2] if self.group == 'ALL': if group not in groups: groups.append(group) for region in self.library.ignored_regions: lower_bound = self.library.ignored_regions[region][0] upper_bound = self.library.ignored_regions[region][1] group = self.library.ignored_regions[region][2] if group in groups: color = self.region_colors[groups.index(group)] bar_width = abs(upper_bound - lower_bound) bar_center = (lower_bound + upper_bound) / 2 self.ax1.bar(bar_center, self.upper_ylim_all, width=bar_width, color=color, align='center', edgecolor=color, linewidth=1, alpha=0.4) self.ax2.bar(bar_center, self.upper_ylim_intense, width=bar_width, color=color, align='center', edgecolor=color, linewidth=1, alpha=0.4) else: continue def handleIgnored(self): if self.showignoredregionsCheckBox.isChecked(): self.fig.clear() self.calculateAllHistogram() self.calculateIntenseHistogram() self.drawIgnoredRegions() self.canvas.draw() else: self.fig.clear() self.calculateAllHistogram() self.calculateIntenseHistogram() self.canvas.draw() def zooming(self, event): cur_ylim1 = self.ax1.get_ylim() cur_ylim2 = self.ax2.get_ylim() cur_yrange1 = (cur_ylim1[1] - cur_ylim1[0]) cur_yrange2 = (cur_ylim2[1] - cur_ylim2[0]) if event.button == 'up': scale_factor = self.scale elif event.button == 'down': scale_factor = 1/self.scale else: scale_factor = 1 self.ax1.set_ylim([0, (cur_yrange1*scale_factor)]) self.ax2.set_ylim([0, (cur_yrange2*scale_factor)]) self.canvas.draw() def saveResults(self): filename = "peakstats.png" filepath = os.path.join(self.params.work_dir, filename) filestype = "static (*.png *.jpg *.svg)" fileObj = QFileDialog.getSaveFileName(self, caption="Save Peak Stats Plot", directory=filepath, filter=filestype) if fileObj[0]: self.fig.set_size_inches(12, 8) plt.savefig(fileObj[0], dpi=200) def closeEvent(self, event=False): self.fig.clear() QDialog.reject(self)
class App(QMainWindow): def __init__(self): super(App, self).__init__() self.title = 'Histogram Equalization' self.inputLoaded = False self.targetLoaded = False self.initUI() def initUI(self): # Write GUI initialization code menubar = self.menuBar() fileMenu = menubar.addMenu('File') self.groupBox1 = QGroupBox(self) self.groupBox2 = QGroupBox(self) self.groupBox3 = QGroupBox(self) self.groupBox1.setTitle("Input") self.groupBox1.resize(500, 1000) self.groupBox1.move(100, 50) self.groupBox2.setTitle("Target") self.groupBox2.resize(500, 1000) self.groupBox2.move(700, 50) self.groupBox3.setTitle("Output") self.groupBox3.resize(500, 1000) self.groupBox3.move(1300, 50) mainLayout = QHBoxLayout(self) mainLayout.addStretch(1) mainLayout.addWidget(self.groupBox1) mainLayout.addWidget(self.groupBox2) mainLayout.addWidget(self.groupBox3) impAct1 = QAction('Open Input', self) impAct1.triggered.connect(self.openInputImage) impAct2 = QAction('Open Target', self) impAct2.triggered.connect(self.openTargetImage) impAct3 = QAction('Exit', self) impAct3.setShortcut('Ctrl+Q') impAct3.triggered.connect(self.quitProgram) fileMenu.addAction(impAct1) fileMenu.addAction(impAct2) fileMenu.addAction(impAct3) eqAct = QAction('Equalize Histogram', self) eqAct.triggered.connect(self.histogramButtonClicked) self.toolbar = self.addToolBar('Equalize Histogram') self.toolbar.addAction(eqAct) self.setWindowTitle('Histogram Equalization') self.setLayout(mainLayout) self.show() def openInputImage(self): # This function is called when the user clicks File->Input Image. #The QLabel where we can display an Image self.label = QLabel(self) self.boxLayout = QVBoxLayout(self.groupBox1) self.boxLayout.addWidget(self.label) self.imagePath, _ = QFileDialog.getOpenFileName(self, 'OpenFile') self.pixmap = QPixmap(self.imagePath) self.label.setPixmap(self.pixmap) #Histogram of image self.histimage = cv2.imread(self.imagePath) self.hist1 = histogram(self.histimage) self.canvas0 = FigureCanvas(Figure(figsize=(5, 3))) self.canvas1 = FigureCanvas(Figure(figsize=(5, 3))) self.canvas2 = FigureCanvas(Figure(figsize=(5, 3))) self.boxLayout.addWidget(self.canvas0) self.boxLayout.addWidget(self.canvas1) self.boxLayout.addWidget(self.canvas2) self.canvas0_plot = self.canvas0.figure.subplots() self.canvas0_plot.axes.bar(range(0, 256), self.hist1[:, 2], color="red") self.canvas0.draw() self.canvas1_plot = self.canvas1.figure.subplots() self.canvas1_plot.axes.bar(range(0, 256), self.hist1[:, 1], color="green") self.canvas1.draw() self.canvas2_plot = self.canvas2.figure.subplots() self.canvas2_plot.axes.bar(range(0, 256), self.hist1[:, 0], color="blue") self.canvas2.draw() self.label.setAlignment(Qt.AlignCenter) self.inputLoaded = True def openTargetImage(self): # This function is called when the user clicks File->Target Image. # The QLabel where we can display an Image self.label2 = QLabel(self) self.boxLayout2 = QVBoxLayout(self.groupBox2) self.boxLayout2.addWidget(self.label2) # The image self.imagePath2, _ = QFileDialog.getOpenFileName(self, 'OpenFile') self.pixmap2 = QPixmap(self.imagePath2) self.label2.setPixmap(self.pixmap2) # Histogram of image self.histimage2 = cv2.imread(self.imagePath2) self.hist2 = histogram(self.histimage2) self.canvas3 = FigureCanvas(Figure(figsize=(5, 3))) self.canvas4 = FigureCanvas(Figure(figsize=(5, 3))) self.canvas5 = FigureCanvas(Figure(figsize=(5, 3))) self.boxLayout2.addWidget(self.canvas3) self.boxLayout2.addWidget(self.canvas4) self.boxLayout2.addWidget(self.canvas5) self.canvas3_plot = self.canvas3.figure.subplots() self.canvas3_plot.axes.bar(range(0, 256), self.hist2[:, 2], color="red") self.canvas3.draw() self.canvas4_plot = self.canvas4.figure.subplots() self.canvas4_plot.axes.bar(range(0, 256), self.hist2[:, 1], color="green") self.canvas4.draw() self.canvas5_plot = self.canvas5.figure.subplots() self.canvas5_plot.axes.bar(range(0, 256), self.hist2[:, 0], color="blue") self.canvas5.draw() self.label2.setAlignment(Qt.AlignCenter) self.targetLoaded = True def histogramButtonClicked(self): if not self.inputLoaded and not self.targetLoaded: # Error: "First load input and target images" in MessageBox QMessageBox.about(self, "Error", "First load input and target images") elif not self.inputLoaded: # Error: "Load input image" in MessageBox QMessageBox.about(self, "Error", "Load input image") elif not self.targetLoaded: # Error: "Load target image" in MessageBox QMessageBox.about(self, "Error", "Load target image") else: self.label3 = QLabel(self) self.boxLayout3 = QVBoxLayout(self.groupBox3) self.boxLayout3.addWidget(self.label3) # The image self.image1 = cv2.imread(self.imagePath) self.image2 = cv2.imread(self.imagePath2) self.h1 = histogram(self.image1) self.h2 = histogram(self.image2) c1_0 = cdf(self.h1[:, 0]) c2_0 = cdf(self.h2[:, 0]) c1_1 = cdf(self.h1[:, 1]) c2_1 = cdf(self.h2[:, 1]) c1_2 = cdf(self.h1[:, 2]) c2_2 = cdf(self.h2[:, 2]) LUT0 = lookup_table(c1_0, c2_0) LUT1 = lookup_table(c1_1, c2_1) LUT2 = lookup_table(c1_2, c2_2) out_im0 = histogram_match(LUT0, self.image1, 0) out_im1 = histogram_match(LUT1, self.image1, 1) out_im2 = histogram_match(LUT2, self.image1, 2) self.out_im = np.dstack((out_im0, out_im1, out_im2)) self.hist3 = histogram(self.out_im) self.out_im = np.divide(self.out_im, 255) self.output_image = self.out_im[..., ::-1] plt.imsave("outputt.png", self.output_image) self.pixmap3 = QPixmap("outputt.png") self.label3.setPixmap(self.pixmap3) # Histogram of image self.canvas6 = FigureCanvas(Figure(figsize=(5, 3))) self.canvas7 = FigureCanvas(Figure(figsize=(5, 3))) self.canvas8 = FigureCanvas(Figure(figsize=(5, 3))) self.boxLayout3.addWidget(self.canvas6) self.boxLayout3.addWidget(self.canvas7) self.boxLayout3.addWidget(self.canvas8) self.canvas6_plot = self.canvas6.figure.subplots() self.canvas6_plot.axes.bar(range(0, 256), self.hist3[:, 2], color="red") self.canvas6.draw() self.canvas7_plot = self.canvas7.figure.subplots() self.canvas7_plot.axes.bar(range(0, 256), self.hist3[:, 1], color="green") self.canvas7.draw() self.canvas8_plot = self.canvas8.figure.subplots() self.canvas8_plot.axes.bar(range(0, 256), self.hist3[:, 0], color="blue") self.canvas8.draw() self.label3.setAlignment(Qt.AlignCenter) self.label3.show() def quitProgram(self): return QApplication.exit(0)
class new_Dialog(QDialog, UI2.Ui_Data_Dialog): def __init__(self, parent): super(new_Dialog, self).__init__(parent) self.setupUi(self) self.w = parent.w self.h = parent.h self.setFixedSize(self.w, self.h) self.data = parent.series_1 self.r = parent.r self.c = parent.c self.colum = self.c self.colum_arr = [x for x in range(self.c)] self.fig = plt.Figure() self.canvas = FigureCanvas(self.fig) self.graph_view.addWidget(self.canvas) self.graph_frame.addLayout(self.graph_view) self.setLayout(self.graph_frame) self.setupUI(self.data, self.r, self.c) self.show() def setupUI(self, data, r, c): self.origin_data = self.data self.origin_col = self.c self.changeheader() self.Save_Button.clicked.connect(self.saveFunction) self.Training_Button.clicked.connect(self.training_btn) self.formLayout_3 = QFormLayout(self.scrollAreaWidgetContents) self.formLayout_3.setObjectName("formLayout_3") for i in range(c): self.checkbox = QCheckBox(self.scrollAreaWidgetContents) self.checkbox.setMinimumSize(QSize(0, 30)) self.checkbox.setObjectName(f"checkbox_{i}") self.checkbox.setText(data.columns[i]) self.formLayout_3.setWidget(i, QFormLayout.LabelRole, self.checkbox) self.del_Col.clicked.connect(self.del_columns) self.reset_Col.clicked.connect( lambda state, origin_data=self.origin_data: self.all_reset( state, self.origin_data, self.origin_col)) self.draw_graph() # 결측치 처리 self.text = self.data.isnull().sum() self.formLayout_2 = QFormLayout(self.scrollAreaWidgetContents_3) self.formLayout_2.setObjectName("formLayout_2") for i in range(c): self.label = QLabel(self.scrollAreaWidgetContents_3) self.label.setMinimumSize(QSize(0, 30)) self.label.setObjectName(f'label_{i}') self.formLayout_2.setWidget(i, QFormLayout.LabelRole, self.label) self.label.setText(data.columns[i]) self.combo = QComboBox(self.scrollAreaWidgetContents_3) self.combo.setMinimumHeight(30) self.combo.setObjectName(f'comboBox_{i}') self.combo.addItem('제거') self.combo.addItem('0으로 대체') self.combo.addItem('평균값으로 대체') self.combo.addItem('중앙값으로 대체') self.formLayout_2.setWidget(i, QFormLayout.FieldRole, self.combo) self.radioButton.setChecked(True) self.process_Button.clicked.connect( lambda state, origin_col=self.origin_col: self.process_btn( state, self.origin_col)) self.reset_Button.clicked.connect( lambda state, origin_data=self.origin_data: self.reset_btn( state, self.origin_data)) column_headers = data.columns self.tableWidget.resize(500, 300) if r >= 200: r = 200 self.tableWidget.setRowCount(r) self.tableWidget.setColumnCount(c) self.tableWidget.setHorizontalHeaderLabels(column_headers) for i in range(r): for j in range(c): self.tableWidget.setItem( i, j, QTableWidgetItem(str(data.iloc[i, j]))) self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers) self.groupBox.setMinimumWidth(self.w // 3 * 0.9) self.groupBox_2.setMinimumWidth(self.w // 3 * 0.9) self.groupBox_3.setMinimumWidth(self.w // 3 * 0.9) self.groupBox_4.setMinimumWidth(self.w // 2 * 0.9) self.groupBox_5.setMinimumWidth(self.w // 2 * 0.9) def changeheader(self): # 컬럼명 변경 self.formLayout = QFormLayout(self.scrollAreaWidgetContents_2) self.formLayout.setObjectName("formLayout") for idx in range(self.c): self.label = QLabel(self.scrollAreaWidgetContents_2) self.label.setMinimumSize(QSize(0, 30)) self.label.setObjectName(f"label_{idx}") self.formLayout.setWidget(idx, QFormLayout.LabelRole, self.label) self.label.setText(self.data.columns[idx]) self.lineEdit = QLineEdit(self.scrollAreaWidgetContents_2) self.lineEdit.setMinimumSize(QSize(0, 30)) self.lineEdit.setObjectName(f"lineEdit_{idx}") self.formLayout.setWidget(idx, QFormLayout.FieldRole, self.lineEdit) self.pushButton = QPushButton('변경', self.groupBox_2) self.pushButton.setObjectName("changeButton") self.pushButton.clicked.connect(self.changeTextFunction) self.pushButton.setMaximumWidth(100) self.gridLayout_4.addWidget(self.pushButton, 2, 0, 1, 1, Qt.AlignRight) # 컬럼 header 변경 def changeTextFunction(self): cnt = 0 for i in self.colum_arr: try: text = self.findChild(QLineEdit, f"lineEdit_{i}").text() if text != '': # self.data.columns.values[cnt] = text self.data.rename( columns={self.data.columns.values[cnt]: text}, inplace=True) self.findChild(QCheckBox, f"checkbox_{i}").setText(text) cnt += 1 self.findChild(QLineEdit, f"lineEdit_{i}").clear() except: pass self.tableWidget.setHorizontalHeaderLabels(self.data.columns) # Tabel cell 내용 변경 def changeTableCells(self, r, c): for i in range(r): for j in range(c): self.tableWidget.setItem( i, j, QTableWidgetItem(str(self.data.iloc[i, j]))) self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers) # 전처리 def process_btn(self, state, origin_col): if self.radioButton.isChecked(): if self.all_comboBox.currentText() == '제거': self.data = self.data.dropna() self.r = self.data.shape[0] self.c = self.data.shape[1] elif self.all_comboBox.currentText() == '0으로 대체': self.data = self.data.fillna(0) elif self.all_comboBox.currentText() == '평균값으로 대체': self.data = round(self.data.fillna(self.data.mean())) elif self.all_comboBox.currentText() == '중앙값으로 대체': self.data = round(self.data.fillna(self.data.median())) else: n = 0 for i in range(origin_col): combo = self.findChild(QComboBox, f"comboBox_{i}") if combo == None: n += 1 if combo != None: combo = combo.currentText() if combo == '제거': self.data = self.data.dropna( subset=[self.data.columns[i - n]]) self.r = self.data.shape[0] elif combo == '0으로 대체': self.data[self.data.columns[i - n]] = self.data[ self.data.columns[i - n]].fillna(0) elif combo == '평균값으로 대체': self.data[self.data.columns[i - n]] = self.data[ self.data.columns[i - n]].fillna( self.data[self.data.columns[i - n]].mean()) elif combo == '중앙값으로 대체': self.data[self.data.columns[i - n]] = round( self.data[self.data.columns[i - n]].fillna( self.data[self.data.columns[i - n]].median())) return self.changeTableCells(self.r, self.c), self.draw_graph() # graph 그리기 def draw_graph(self): self.fig.clear() ax = self.fig.add_subplot(1, 1, 1) missing = self.data.isnull().sum() x_val = [] y_val = [] for i in range(self.data.shape[1]): cnt = self.data[self.data.columns[i]].isnull().sum() try: if cnt: x_val.append(self.data.columns[i]) y_val.append(cnt) else: x_val.append(self.data.columns[i]) y_val.append(0) except: pass try: missing = missing[missing > 0] missing.sort_values(inplace=True) ax.bar(x_val, y_val) ax.set_ylabel('개수') for i, v in enumerate(x_val): ax.text(v, y_val[i], str(y_val[i])) plt.bar(x_val, y_val) plt.close() except: ax.bar(x_val, y_val) ax.set_xlabel('Column') ax.set_ylabel('개수') for i, v in enumerate(x_val): ax.text(y_val[i], v, str(y_val[i])) ax.grid() self.canvas.draw() # column 삭제 def del_columns(self): cnt = 0 for i in range(self.colum): try: if self.findChild(QCheckBox, f"checkbox_{i}").isChecked(): col_name = self.findChild(QCheckBox, f"checkbox_{i}").text() self.data = self.data.drop(col_name, axis=1) cnt += 1 label = self.formLayout.labelForField( self.findChild(QLineEdit, f"lineEdit_{i}")) label.deleteLater() self.findChild(QLineEdit, f"lineEdit_{i}").deleteLater() combo_label = self.formLayout_2.labelForField( self.findChild(QComboBox, f"comboBox_{i}")) combo_label.deleteLater() self.findChild(QComboBox, f"comboBox_{i}").deleteLater() self.findChild(QCheckBox, f"checkbox_{i}").deleteLater() self.colum_arr.remove(i) except: pass self.c -= cnt self.tableWidget.clear() self.tableWidget.setHorizontalHeaderLabels(self.data.columns) return self.changeTableCells(self.r, self.c), self.draw_graph() # 데이터 초기화 def reset_btn(self, state, origin_data): self.data = origin_data self.colum = self.c self.colum_arr = [x for x in range(self.c)] return self.changeTableCells(self.r, self.c), self.draw_graph() # column 초기화 def all_reset(self, state, origin_data, origin_col): self.data = origin_data self.c = origin_col self.colum = self.c self.colum_arr = [x for x in range(self.c)] for i in range(self.c): if self.findChild(QLabel, f"label_{i}") == None: self.label = QLabel(self.scrollAreaWidgetContents_2) self.label.setMinimumSize(QSize(0, 30)) self.label.setObjectName(f"label_{i}") self.formLayout.setWidget(i, QFormLayout.LabelRole, self.label) self.label.setText(self.data.columns[i]) self.lineEdit = QLineEdit(self.scrollAreaWidgetContents_2) self.lineEdit.setMinimumSize(QSize(0, 30)) self.lineEdit.setObjectName(f"lineEdit_{i}") self.formLayout.setWidget(i, QFormLayout.FieldRole, self.lineEdit) self.label = QLabel(self.scrollAreaWidgetContents_3) self.label.setMinimumSize(QSize(0, 30)) self.label.setObjectName(f'label_{i}') self.formLayout_2.setWidget(i, QFormLayout.LabelRole, self.label) self.label.setText(self.data.columns[i]) self.combo = QComboBox(self.scrollAreaWidgetContents_3) self.combo.setMinimumHeight(30) self.combo.setObjectName(f'comboBox_{i}') self.combo.addItem('제거') self.combo.addItem('0으로 대체') self.combo.addItem('평균값으로 대체') self.combo.addItem('중앙값으로 대체') self.formLayout_2.setWidget(i, QFormLayout.FieldRole, self.combo) self.checkbox = QCheckBox(self.scrollAreaWidgetContents) self.checkbox.setMinimumSize(QSize(0, 30)) self.checkbox.setObjectName(f"checkbox_{i}") self.checkbox.setText(self.data.columns[i]) self.formLayout_3.setWidget(i, QFormLayout.LabelRole, self.checkbox) self.tableWidget.setHorizontalHeaderLabels(self.data.columns) return self.changeTableCells(self.r, self.c), self.draw_graph() # 데이터 저장 def saveFunction(self): try: csv = self.data savefile = QFileDialog.getSaveFileName(self, '파일저장', '', '(*.csv)') csv.to_csv(savefile[0], index=False) except: return # training과 연동 def training_btn(self): self.series_1 = self.data Train_Dialog.Train_Dialog(self) self.close()
def draw(self): if self.limitsSet: self.ax.set_xlim(self.xmin, self.xmax) self.ax.set_ylim(self.ymin, self.ymax) FigureCanvas.draw(self)
class Window(QDialog): def __init__(self, parent=None): super(Window, self).__init__(parent) self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas, self) self.button = QPushButton('Start Scan') self.button.clicked.connect(self.plot) layout = QVBoxLayout() layout.addWidget(self.toolbar) layout.addWidget(self.canvas) layout.addWidget(self.button) self.setLayout(layout) def plot(self): n = 1 posY = 0 posX = 0 x1 = np.arange(0, 32, 1) y1 = np.arange(0, 50, 1) xs1, ys1 = np.meshgrid(x1, y1) zz1 = np.array([ [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #1 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #2 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #3 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #4 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #5 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #6 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #7 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #8 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #9 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #10 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #11 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #12 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #13 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #14 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #15 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #16 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #17 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #18 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #19 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #20 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #21 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #22 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #23 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #24 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #25 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #26 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #27 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #28 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #29 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #30 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #31 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #32 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #33 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #34 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #35 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #36 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #37 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #37 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #39 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #40 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #41 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #42 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #43 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #44 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #45 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #46 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #47 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #48 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], #49 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] ]) #50 for y in zz1: # Y Ganjil -> dari kiri ke kanan if (n == 1): posX = 0 for x in y: # lakukan scan ultrasonic zz1[posY][posX] = get_range() print(zz1[posY][posX]) posX += 1 self.figure.clear() ax = Axes3D(self.figure) ax.plot_surface(xs1, ys1, zz1, rstride=1, cstride=1, cmap=cm.coolwarm) self.canvas.draw() self.canvas.flush_events() stepA(True, 1000, 100) n = 0 stepB(True, 1000, 100) # Y Genap -> dari kanan ke kiri else: posX -= 1 for x in reversed(y): # lakukan scan ultrasonic zz1[posY][posX] = get_range() print(zz1[posY][posX]) posX -= 1 self.figure.clear() ax = Axes3D(self.figure) ax.plot_surface(xs1, ys1, zz1, rstride=1, cstride=1, cmap=cm.coolwarm) self.canvas.draw() self.canvas.flush_events() stepA(False, 1000, 100) n = 1 stepB(True, 1000, 100) posY += 1 print(zz1) reset()
class DetachablePlotFrame(QtWidgets.QFrame): def __init__(self, parent): super().__init__(parent) self.figure = None self.canvas = None self.toolbar = None self.btn_detach = QtWidgets.QPushButton(self) self.btn_detach.setIcon(QtGui.QIcon.fromTheme('document-new-symbolic')) self.btn_detach.clicked.connect(self.detach_plot) self.btn_export = QtWidgets.QPushButton(self) self.btn_export.setIcon(QtGui.QIcon.fromTheme('document-save-symbolic')) self.btn_export.clicked.connect(self.save_plot) self.layout = QtWidgets.QGridLayout(self) self.layout.setRowStretch(0, 1) self.layout.addWidget(self.btn_export, 1, 1, 1, 1) self.btn_export.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.MinimumExpanding) self.layout.addWidget(self.btn_detach, 0, 1, 1, 1) self.btn_detach.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) self.resize(600, 400) def save_plot(self): filepath, ok = QtWidgets.QFileDialog.getSaveFileName(self, 'Enregistrer le graphique', filter='*.png') if ok: self.figure.savefig(filepath, bbox_inches='tight') def detach_plot(self): new_window = QtWidgets.QMainWindow(self) new_window.setWindowTitle('Graphique détaché') frame = QtWidgets.QFrame(new_window) canvas = FigureCanvas(self.figure) canvas.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) canvas.updateGeometry() canvas.draw() toolbar = NavigationToolbar(canvas, frame) layout = QtWidgets.QVBoxLayout(frame) layout.addWidget(canvas, 1) layout.addWidget(toolbar, 0) new_window.setCentralWidget(frame) new_window.show() return new_window def update_figure(self, figure): self.figure = figure if self.canvas is not None: self.layout.removeWidget(self.canvas) self.layout.removeWidget(self.toolbar) self.canvas.deleteLater() self.canvas = FigureCanvas(self.figure) self.canvas.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) self.canvas.updateGeometry() self.canvas.draw() self.layout.addWidget(self.canvas, 0, 0, 2, 1)
class MyWindow(QWidget): def __init__(self): super().__init__() # plus 상태 체크 if InitPlusCheck() == False: exit() # 기본 변수들 self.chartData = {} self.code = '' self.isRq = False self.objChart = CpFutureChart() self.sizeControl() # 선물 종목 코드 추가 for i in range(g_objFutureMgr.GetCount()): code = g_objFutureMgr.GetData(0, i) self.comboStg.addItem(code) self.comboStg.setCurrentIndex(0) def sizeControl(self): # 윈도우 버튼 배치 self.setWindowTitle("PLUS API TEST") self.setGeometry(50, 50, 1200, 600) self.comboStg = QComboBox() # self.comboStg.move(20, nH) self.comboStg.currentIndexChanged.connect(self.comboChanged) # self.comboStg.resize(100, 30) self.label = QLabel('종목코드') # self.label.move(140, nH) # Figure 를 먼저 만들고 레이아웃에 들어 갈 sub axes 를 생성 한다. self.fig = plt.Figure() self.canvas = FigureCanvas(self.fig) # top layout topLayout = QHBoxLayout() topLayout.addWidget(self.comboStg) topLayout.addWidget(self.label) topLayout.addStretch(1) # topLayout.addSpacing(20) chartlayout = QVBoxLayout() chartlayout.addWidget(self.canvas) layout = QVBoxLayout() layout.addLayout(topLayout) layout.addLayout(chartlayout) layout.setStretchFactor(topLayout, 0) layout.setStretchFactor(chartlayout, 1) self.setLayout(layout) # 분차트 받기 def RequestMinchart(self): if self.objChart.RequestMT(self.code, ord('m'), 100, self) == False: exit() def makeMovingAverage(self, maData, interval): # maData = [] for i in range(0, len(self.chartData[C_DT])): if (i < interval): maData.append(float('nan')) continue sum = 0 for j in range(0, interval): sum += self.chartData[C_CP][i - j] ma = sum / interval maData.append(ma) # print(maData) def drawMinchart(self): # 기존 거 지운다. self.fig.clf() # 211 - 2(행) * 1(열) 배치 1번째 self.ax1 = self.fig.add_subplot(2, 1, 1) # 212 - 2(행) * 1(열) 배치 2번째 self.ax2 = self.fig.add_subplot(2, 1, 2) ############################################### # 봉차트 그리기 # self.ax1.xaxis.set_major_formatter(ticker.FixedFormatter(schartData[C_TM])) matfin.candlestick2_ohlc(self.ax1, self.chartData[C_OP], self.chartData[C_HP], self.chartData[C_LP], self.chartData[C_CP], width=0.8, colorup='r', colordown='b') ############################################### # x 축 인덱스 만들기 - 기본 순차 배열 추가 x_tick_raw = [i for i in range(len(self.chartData[C_DT]))] # x 축 인덱스 만들기 - 실제 화면에 표시될 텍스트 만들기 x_tick_labels = [] startDate = 0 dateChanged = True for i in range(len(self.chartData[C_DT])): # 날짜 변경 된 경우 날짜 정보 저장 date = self.chartData[C_DT][i] if (date != startDate): yy, mm = divmod(date, 10000) mm, dd = divmod(mm, 100) sDate = '%2d/%d ' % (mm, dd) print(sDate) startDate = date dateChanged = True # 0 분 또는 30분 단위로 시간 표시 hhh, mmm = divmod(self.chartData[C_TM][i], 100) stime = '%02d:%02d' % (hhh, mmm) if (mmm == 0 or mmm == 30): if dateChanged == True: sDate += stime x_tick_labels.append(sDate) dateChanged = False else: x_tick_labels.append(stime) else: x_tick_labels.append('') ############################################### # 이동 평균 그리기 self.ax1.plot(x_tick_raw, self.chartData[C_MA5], label='ma5') self.ax1.plot(x_tick_raw, self.chartData[C_MA10], label='ma10') self.ax1.plot(x_tick_raw, self.chartData[C_MA20], label='ma20') ############################################### # 거래량 그리기 self.ax2.bar(x_tick_raw, self.chartData[C_VL]) ############################################### # x 축 가로 인덱스 지정 self.ax1.set(xticks=x_tick_raw, xticklabels=x_tick_labels) self.ax2.set(xticks=x_tick_raw, xticklabels=x_tick_labels) self.ax1.grid() self.ax2.grid() plt.tight_layout() self.ax1.legend(loc='upper left') self.canvas.draw() def comboChanged(self): if self.isRq == True: return self.isRq = True self.code = self.comboStg.currentText() self.name = g_objFutureMgr.CodetoName(self.code) self.label.setText(self.name) self.RequestMinchart() self.makeMovingAverage(self.chartData[C_MA5], 5) self.makeMovingAverage(self.chartData[C_MA10], 10) self.makeMovingAverage(self.chartData[C_MA20], 20) self.drawMinchart() self.isRq = False
class FigureTab: cursors = [15000, 45000] colors = ['orange', 'violet'] def __init__(self, layout, vna): # create figure self.figure = Figure() if sys.platform != 'win32': self.figure.set_facecolor('none') self.canvas = FigureCanvas(self.figure) layout.addWidget(self.canvas) # create navigation toolbar self.toolbar = NavigationToolbar(self.canvas, None, False) self.toolbar.layout().setSpacing(6) # remove subplots action actions = self.toolbar.actions() if int(matplotlib.__version__[0]) < 2: self.toolbar.removeAction(actions[7]) else: self.toolbar.removeAction(actions[6]) self.toolbar.addSeparator() self.cursorLabels = {} self.cursorValues = {} self.cursorMarkers = {} self.cursorPressed = {} for i in range(len(self.cursors)): self.cursorMarkers[i] = None self.cursorPressed[i] = False self.cursorLabels[i] = QLabel('Cursor %d, kHz' % (i + 1)) self.cursorLabels[i].setStyleSheet('color: %s' % self.colors[i]) self.cursorValues[i] = QSpinBox() self.cursorValues[i].setMinimumSize(90, 0) self.cursorValues[i].setSingleStep(10) self.cursorValues[i].setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self.toolbar.addWidget(self.cursorLabels[i]) self.toolbar.addWidget(self.cursorValues[i]) self.cursorValues[i].valueChanged.connect(partial(self.set_cursor, i)) self.canvas.mpl_connect('button_press_event', partial(self.press_marker, i)) self.canvas.mpl_connect('motion_notify_event', partial(self.move_marker, i)) self.canvas.mpl_connect('button_release_event', partial(self.release_marker, i)) self.toolbar.addSeparator() self.plotButton = QPushButton('Rescale') self.toolbar.addWidget(self.plotButton) layout.addWidget(self.toolbar) self.plotButton.clicked.connect(self.plot) self.mode = None self.vna = vna def add_cursors(self, axes): if self.mode == 'gain_short' or self.mode == 'gain_open': columns = ['Freq., kHz', 'G, dB', r'$\angle$ G, deg'] else: columns = ['Freq., kHz', 'Re(Z), \u03A9', 'Im(Z), \u03A9', '|Z|, \u03A9', r'$\angle$ Z, deg', 'SWR', r'|$\Gamma$|', r'$\angle$ $\Gamma$, deg', 'RL, dB'] y = len(self.cursors) * 0.04 + 0.01 for i in range(len(columns)): self.figure.text(0.19 + 0.1 * i, y, columns[i], horizontalalignment = 'right') self.cursorRows = {} for i in range(len(self.cursors)): y = len(self.cursors) * 0.04 - 0.03 - 0.04 * i self.figure.text(0.01, y, 'Cursor %d' % (i + 1), color = self.colors[i]) self.cursorRows[i] = {} for j in range(len(columns)): self.cursorRows[i][j] = self.figure.text(0.19 + 0.1 * j, y, '', horizontalalignment = 'right') if self.mode == 'smith': self.cursorMarkers[i], = axes.plot(0.0, 0.0, marker = 'o', color = self.colors[i]) else: self.cursorMarkers[i] = axes.axvline(0.0, color = self.colors[i], linewidth = 2) self.set_cursor(i, self.cursorValues[i].value()) def set_cursor(self, index, value): FigureTab.cursors[index] = value marker = self.cursorMarkers[index] if marker is None: return row = self.cursorRows[index] freq = value gamma = self.vna.gamma(freq) if self.mode == 'smith': marker.set_xdata(gamma.real) marker.set_ydata(gamma.imag) else: marker.set_xdata(freq) row[0].set_text('%d' % freq) if self.mode == 'gain_short': gain = self.vna.gain_short(freq) magnitude = 20.0 * np.log10(np.absolute(gain)) angle = np.angle(gain, deg = True) row[1].set_text(unicode_minus('%.1f' % magnitude)) row[2].set_text(unicode_minus('%.1f' % angle)) elif self.mode == 'gain_open': gain = self.vna.gain_open(freq) magnitude = 20.0 * np.log10(np.absolute(gain)) angle = np.angle(gain, deg = True) row[1].set_text(unicode_minus('%.1f' % magnitude)) row[2].set_text(unicode_minus('%.1f' % angle)) else: swr = self.vna.swr(freq) z = self.vna.impedance(freq) rl = 20.0 * np.log10(np.absolute(gamma)) if rl > -0.01: rl = 0.0 row[1].set_text(metric_prefix(z.real)) row[2].set_text(metric_prefix(z.imag)) row[3].set_text(metric_prefix(np.absolute(z))) angle = np.angle(z, deg = True) if np.abs(angle) < 0.1: angle = 0.0 row[4].set_text(unicode_minus('%.1f' % angle)) row[5].set_text(unicode_minus('%.2f' % swr)) row[6].set_text(unicode_minus('%.2f' % np.absolute(gamma))) angle = np.angle(gamma, deg = True) if np.abs(angle) < 0.1: angle = 0.0 row[7].set_text(unicode_minus('%.1f' % angle)) row[8].set_text(unicode_minus('%.2f' % rl)) self.canvas.draw() def press_marker(self, index, event): if not event.inaxes: return if self.mode == 'smith': return marker = self.cursorMarkers[index] if marker is None: return contains, misc = marker.contains(event) if not contains: return self.cursorPressed[index] = True def move_marker(self, index, event): if not event.inaxes: return if self.mode == 'smith': return if not self.cursorPressed[index]: return self.cursorValues[index].setValue(event.xdata) def release_marker(self, index, event): self.cursorPressed[index] = False def xlim(self, freq): start = freq[0] stop = freq[-1] min = np.minimum(start, stop) max = np.maximum(start, stop) margin = (max - min) / 50 return (min - margin, max + margin) def plot(self): getattr(self, 'plot_%s' % self.mode)() def update(self, mode): start = self.vna.dut.freq[0] stop = self.vna.dut.freq[-1] min = np.minimum(start, stop) max = np.maximum(start, stop) for i in range(len(self.cursors)): value = self.cursors[i] self.cursorValues[i].setRange(min, max) self.cursorValues[i].setValue(value) self.set_cursor(i, value) getattr(self, 'update_%s' % mode)() def plot_curves(self, freq, data1, label1, limit1, data2, label2, limit2): matplotlib.rcdefaults() matplotlib.rcParams['axes.formatter.use_mathtext'] = True self.figure.clf() bottom = len(self.cursors) * 0.04 + 0.13 self.figure.subplots_adjust(left = 0.16, bottom = bottom, right = 0.84, top = 0.96) axes1 = self.figure.add_subplot(111) axes1.cla() axes1.xaxis.grid() axes1.set_xlabel('kHz') axes1.set_ylabel(label1) xlim = self.xlim(freq) axes1.set_xlim(xlim) if limit1 is not None: axes1.set_ylim(limit1) self.curve1, = axes1.plot(freq, data1, color = 'blue', label = label1) self.add_cursors(axes1) if data2 is None: self.canvas.draw() return axes1.tick_params('y', color = 'blue', labelcolor = 'blue') axes1.yaxis.label.set_color('blue') axes2 = axes1.twinx() axes2.spines['left'].set_color('blue') axes2.spines['right'].set_color('red') axes2.set_ylabel(label2) axes2.set_xlim(xlim) if limit2 is not None: axes2.set_ylim(limit2) axes2.tick_params('y', color = 'red', labelcolor = 'red') axes2.yaxis.label.set_color('red') self.curve2, = axes2.plot(freq, data2, color = 'red', label = label2) self.canvas.draw() def plot_gain(self, gain): freq = self.vna.dut.freq data1 = 20.0 * np.log10(np.absolute(gain)) data2 = np.angle(gain, deg = True) self.plot_curves(freq, data1, 'G, dB', (-110, 110.0), data2, r'$\angle$ G, deg', (-198, 198)) def plot_gain_short(self): self.mode = 'gain_short' self.plot_gain(self.vna.gain_short(self.vna.dut.freq)) def plot_gain_open(self): self.mode = 'gain_open' self.plot_gain(self.vna.gain_open(self.vna.dut.freq)) def update_gain(self, gain, mode): if self.mode == mode: self.curve1.set_xdata(self.vna.dut.freq) self.curve1.set_ydata(20.0 * np.log10(np.absolute(gain))) self.curve2.set_xdata(self.vna.dut.freq) self.curve2.set_ydata(np.angle(gain, deg = True)) self.canvas.draw() else: self.mode = mode self.plot_gain(gain) def update_gain_short(self): self.update_gain(self.vna.gain_short(self.vna.dut.freq), 'gain_short') def update_gain_open(self): self.update_gain(self.vna.gain_open(self.vna.dut.freq), 'gain_open') def plot_magphase(self, freq, data, label, mode): self.mode = mode data1 = np.absolute(data) data2 = np.angle(data, deg = True) max = np.fmax(0.01, data1.max()) label1 = r'|%s|' % label label2 = r'$\angle$ %s, deg' % label self.plot_curves(freq, data1, label1, (-0.05 * max, 1.05 * max), data2, label2, (-198, 198)) def update_magphase(self, freq, data, label, mode): if self.mode == mode: self.curve1.set_xdata(freq) self.curve1.set_ydata(np.absolute(data)) self.curve2.set_xdata(freq) self.curve2.set_ydata(np.angle(data, deg = True)) self.canvas.draw() else: self.plot_magphase(freq, data, label, mode) def plot_open(self): self.plot_magphase(self.vna.open.freq, self.vna.open.data, 'open', 'open') def update_open(self): self.update_magphase(self.vna.open.freq, self.vna.open.data, 'open', 'open') def plot_short(self): self.plot_magphase(self.vna.short.freq, self.vna.short.data, 'short', 'short') def update_short(self): self.update_magphase(self.vna.short.freq, self.vna.short.data, 'short', 'short') def plot_load(self): self.plot_magphase(self.vna.load.freq, self.vna.load.data, 'load', 'load') def update_load(self): self.update_magphase(self.vna.load.freq, self.vna.load.data, 'load', 'load') def plot_dut(self): self.plot_magphase(self.vna.dut.freq, self.vna.dut.data, 'dut', 'dut') def update_dut(self): self.update_magphase(self.vna.dut.freq, self.vna.dut.data, 'dut', 'dut') def plot_smith_grid(self, axes, color): load = 50.0 ticks = np.array([0.0, 0.2, 0.5, 1.0, 2.0, 5.0]) for tick in ticks * load: axis = np.logspace(-4, np.log10(1.0e3), 200) * load z = tick + 1.0j * axis gamma = (z - load)/(z + load) axes.plot(gamma.real, gamma.imag, color = color, linewidth = 0.4, alpha = 0.3) axes.plot(gamma.real, -gamma.imag, color = color, linewidth = 0.4, alpha = 0.3) z = axis + 1.0j * tick gamma = (z - load)/(z + load) axes.plot(gamma.real, gamma.imag, color = color, linewidth = 0.4, alpha = 0.3) axes.plot(gamma.real, -gamma.imag, color = color, linewidth = 0.4, alpha = 0.3) if tick == 0.0: axes.text(1.0, 0.0, u'\u221E', color = color, ha = 'left', va = 'center', clip_on = True, fontsize = 'x-large') axes.text(-1.0, 0.0, u'0\u03A9', color = color, ha = 'left', va = 'bottom', clip_on = True) continue lab = u'%d\u03A9' % tick x = (tick - load) / (tick + load) axes.text(x, 0.0, lab, color = color, ha = 'left', va = 'bottom', clip_on = True) lab = u'j%d\u03A9' % tick z = 1.0j * tick gamma = (z - load)/(z + load) * 1.05 x = gamma.real y = gamma.imag angle = np.angle(gamma) * 180.0 / np.pi - 90.0 axes.text(x, y, lab, color = color, ha = 'center', va = 'center', clip_on = True, rotation = angle) lab = u'\u2212j%d\u03A9' % tick axes.text(x, -y, lab, color = color, ha = 'center', va = 'center', clip_on = True, rotation = -angle) def plot_smith(self): self.mode = 'smith' matplotlib.rcdefaults() self.figure.clf() bottom = len(self.cursors) * 0.04 + 0.05 self.figure.subplots_adjust(left = 0.0, bottom = bottom, right = 1.0, top = 1.0) axes1 = self.figure.add_subplot(111) self.plot_smith_grid(axes1, 'blue') gamma = self.vna.gamma(self.vna.dut.freq) self.curve1, = axes1.plot(gamma.real, gamma.imag, color = 'red') axes1.axis('equal') axes1.set_xlim(-1.12, 1.12) axes1.set_ylim(-1.12, 1.12) axes1.xaxis.set_visible(False) axes1.yaxis.set_visible(False) for loc, spine in axes1.spines.items(): spine.set_visible(False) self.add_cursors(axes1) self.canvas.draw() def update_smith(self): if self.mode == 'smith': gamma = self.vna.gamma(self.vna.dut.freq) self.curve1.set_xdata(gamma.real) self.curve1.set_ydata(gamma.imag) self.canvas.draw() else: self.plot_smith() def plot_imp(self): self.mode = 'imp' freq = self.vna.dut.freq z = self.vna.impedance(freq) data1 = np.fmin(9.99e4, np.absolute(z)) data2 = np.angle(z, deg = True) max = np.fmax(0.01, data1.max()) self.plot_curves(freq, data1, '|Z|, \u03A9', (-0.05 * max, 1.05 * max), data2, r'$\angle$ Z, deg', (-198, 198)) def update_imp(self): if self.mode == 'imp': freq = self.vna.dut.freq z = self.vna.impedance(freq) data1 = np.fmin(9.99e4, np.absolute(z)) data2 = np.angle(z, deg = True) self.curve1.set_xdata(freq) self.curve1.set_ydata(data1) self.curve2.set_xdata(freq) self.curve2.set_ydata(data2) self.canvas.draw() else: self.plot_imp() def plot_swr(self): self.mode = 'swr' freq = self.vna.dut.freq data1 = self.vna.swr(freq) self.plot_curves(freq, data1, 'SWR', (0.9, 3.1), None, None, None) def update_swr(self): if self.mode == 'swr': self.curve1.set_xdata(self.vna.dut.freq) self.curve1.set_ydata(self.vna.swr(self.vna.dut.freq)) self.canvas.draw() else: self.plot_swr() def plot_gamma(self): self.plot_magphase(self.vna.dut.freq, self.vna.gamma(self.vna.dut.freq), r'$\Gamma$', 'gamma') def update_gamma(self): self.update_magphase(self.vna.dut.freq, self.vna.gamma(self.vna.dut.freq), r'$\Gamma$', 'gamma') def plot_rl(self): self.mode = 'rl' freq = self.vna.dut.freq gamma = self.vna.gamma(freq) data1 = 20.0 * np.log10(np.absolute(gamma)) self.plot_curves(freq, data1, 'RL, dB', (-105, 5.0), None, None, None) def update_rl(self): if self.mode == 'rl': freq = self.vna.dut.freq gamma = self.vna.gamma(freq) data1 = 20.0 * np.log10(np.absolute(gamma)) self.curve1.set_xdata(freq) self.curve1.set_ydata(data1) self.canvas.draw() else: self.plot_rl()
class Window(QtWidgets.QMainWindow, Data_to_plot): def __init__(self, parent=None): super().__init__(parent) wid = QWidget(self) self.setCentralWidget(wid) self.figure = plt.figure() self.axes = self.figure.add_subplot(111) # We want the axes cleared every time plot() is called self.axes.hold(False) self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas, self) self.button_to_plot = QtWidgets.QPushButton('Plot') self.button_to_plot.clicked.connect(self.plot) self.button_to_plot_twinx = QtWidgets.QPushButton('Plot twinx') self.button_to_plot_twinx.clicked.connect(self.plot_twinx) self.button_to_zoom = QtWidgets.QPushButton('Zoom') self.button_to_zoom.clicked.connect(self.zoom) self.button_to_home = QtWidgets.QPushButton('Home') self.button_to_home.clicked.connect(self.home) self.button_to_save_fig = QtWidgets.QPushButton('Save') self.button_to_save_fig.clicked.connect(self.save_fig) self.button_to_set_xlabel = QtWidgets.QPushButton('Set xlabel') self.button_to_set_xlabel.clicked.connect(self.set_xlabel) self.text_xlable = QtWidgets.QLineEdit() self.button_to_set_ylabel = QtWidgets.QPushButton('Set ylabel') self.button_to_set_ylabel.clicked.connect(self.set_ylabel) self.text_ylable = QtWidgets.QLineEdit() self.button_to_set_title = QtWidgets.QPushButton('Set title') self.button_to_set_title.clicked.connect(self.set_title) self.text_title = QtWidgets.QLineEdit() self.button_to_import_data = QtWidgets.QPushButton('import data x,y') self.button_to_import_data.clicked.connect(self.import_data) self.textEdit = QtWidgets.QTextEdit() self.button_to_import_data_xyz = QtWidgets.QPushButton( 'import data x,y,z') # set the layout layout = QtWidgets.QVBoxLayout() layout.addWidget(self.toolbar) layout.addWidget(self.canvas) btnlayout1 = QtWidgets.QHBoxLayout() btnlayout1.addWidget(self.button_to_plot) btnlayout1.addWidget(self.button_to_plot_twinx) btnlayout1.addWidget(self.button_to_zoom) btnlayout1.addWidget(self.button_to_home) btnlayout1.addWidget(self.button_to_save_fig) btnlayout2 = QtWidgets.QHBoxLayout() btnlayout2.addWidget(self.button_to_set_xlabel) btnlayout2.addWidget(self.button_to_set_ylabel) btnlayout2.addWidget(self.button_to_set_title) btnlayout3 = QtWidgets.QHBoxLayout() btnlayout3.addWidget(self.text_xlable) btnlayout3.addWidget(self.text_ylable) btnlayout3.addWidget(self.text_title) btnlayout4 = QtWidgets.QHBoxLayout() btnlayout4.addWidget(self.button_to_import_data) btnlayout4.addWidget(self.textEdit) btnlayout4.addWidget(self.button_to_import_data_xyz) qw = QtWidgets.QWidget(self) qw.setLayout(btnlayout1) qw2 = QtWidgets.QWidget(self) qw2.setLayout(btnlayout2) qw3 = QtWidgets.QWidget(self) qw3.setLayout(btnlayout3) qw4 = QtWidgets.QWidget(self) qw4.setLayout(btnlayout4) layout.addWidget(qw) layout.addWidget(qw2) layout.addWidget(qw3) layout.addWidget(qw4) wid.setLayout(layout) def home(self): self.toolbar.home() def zoom(self): self.toolbar.zoom() def import_data(self): fname = QtWidgets.QFileDialog.getOpenFileName(self, 'Open file', os.getcwd()) if fname[0]: try: self.x, self.y = np.loadtxt(fname[0], unpack=True, skiprows=1) with open(fname[0], 'r') as f: data = f.read() self.textEdit.setText(data) except Exception as err: print(err) def import_data_xyz(self): fname = QtWidgets.QFileDialog.getOpenFileName(self, 'Open file', os.getcwd()) if fname[0]: try: self.x, self.y, self.z = np.loadtxt(fname[0], unpack=True, skiprows=1) with open(fname[0], 'r') as f: data = f.read() self.textEdit.setText(data) except Exception as err: print(err) def plot(self): self.axes.plot(self.x, self.y, 'bo') self.canvas.draw() def plot_twinx(self): self.axes.plot(self.x, self.y, 'bo') self.axes2 = self.axes.twinx() self.axes2.plot(self.x, self.z, 'r<') self.canvas.draw() def set_title(self): self.title = self.text_title.text() self.axes.set_title(self.title) self.canvas.draw() def set_xlabel(self): self.xlabel = self.text_xlable.text() self.axes.set_xlabel(self.xlabel) self.canvas.draw() def set_ylabel(self): self.ylabel = self.text_ylable.text() self.axes.set_ylabel(self.ylabel) self.canvas.draw() def save_fig(self): path_to_save_fig = os.path.join(os.getcwd(), "wykres.jpg") plt.savefig(path_to_save_fig)
class PlotWindow(QtWidgets.QDialog): def __init__(self, parent=None, figure=None): super().__init__(parent) # a figure instance to plot on self.setWindowTitle('Plot Window') if not figure: self.figure = plt.figure() else: self.figure = figure self.time_subplot = self.figure.add_subplot(221) self.freq_subplot = self.figure.add_subplot(222) self.glue_subplot = self.figure.add_subplot(223) self.int_subplot = self.figure.add_subplot(224) # this is the Canvas Widget that displays the `figure` # it takes the `figure` instance as a parameter to __init__ self.canvas = FigureCanvas(self.figure) # this is the Navigation widget # it takes the Canvas widget and a parent self.toolbar = NavigationToolbar(self.canvas, self) # Get data button self.get_time_button = QtWidgets.QPushButton('Get Time Data', self) self.get_freq_button = QtWidgets.QPushButton('Get Freq Data', self) self.get_glue_button = QtWidgets.QPushButton('Get Glue Data', self) self.get_int_button = QtWidgets.QPushButton('Get Int Data', self) self.get_time_button.clicked.connect(self.show_time_data) self.get_freq_button.clicked.connect(self.show_freq_data) self.get_glue_button.clicked.connect(self.show_glue_data) self.get_int_button.clicked.connect(self.show_int_data) # set the layout layout = QtWidgets.QVBoxLayout(self) layout.addWidget(self.toolbar) layout.addWidget(self.canvas) hlayout = QtWidgets.QHBoxLayout(self) hlayout.addWidget(self.get_time_button) hlayout.addWidget(self.get_freq_button) hlayout.addWidget(self.get_glue_button) hlayout.addWidget(self.get_int_button) layout.addLayout(hlayout) self.setLayout(layout) # data self.time_data = None self.freq_data = None self.glue_data = None self.int_data = None def plot_time(self, dic, data, title='Time', x_label='Time'): # discards the old graph self.time_subplot.hold(False) uc = ng.pipe.make_uc(dic, data) [re, im, ab] = self.time_subplot.plot(uc.us_scale(), data.real, 'r-', uc.us_scale(), data.imag, 'g-', uc.us_scale(), np.absolute(data), 'm--') re.set_label('Real Part') im.set_label('Imag Part') ab.set_label('Absolute') self.time_subplot.legend() self.time_subplot.set_title(title) self.time_subplot.set_xlabel(x_label + ' / ' + 'us') # refresh canvas self.canvas.draw() # refresh data self.time_data = [uc.us_scale(), data.real, data.imag, np.absolute(data)] def show_time_data(self): self.show_data_dialog('time') def show_freq_data(self): self.show_data_dialog('freq') def show_glue_data(self): self.show_data_dialog('glue') def show_int_data(self): self.show_data_dialog('int') def show_data_dialog(self, data_type): message_widget = QtWidgets.QDialog(self) if data_type == 'time': message = self.format_data(header = 'Time/us\tRealPart\tImagPart\tAbs', data_list=self.time_data) if data_type == 'freq': message = self.format_data(header = 'Freq/hz\tRealPart\tImagPart\tAbs', data_list=self.freq_data) if data_type == 'glue': message = self.format_data(header = 'Freq/hz\tRealPart\tImagPart\tAbs', data_list=self.glue_data) if data_type == 'int': message = self.format_data(header = 'X0\tRealPart\tImagPart\tAbs\tX1\tRealPart\tImagPart\tAbs\tX2\tRealPart\tImagPart\tAbs\tX3\tRealPart\tImagPart\tAbs\t', data_list=self.int_data) message_box = QtWidgets.QTextEdit(message_widget) message_box.setText(message) layout = QtWidgets.QVBoxLayout(message_widget) layout.addWidget(message_box) message_widget.setLayout(layout) message_widget.setWindowTitle('Data') message_widget.show() def format_data(self, header, data_list): zipped_list = list(zip(*[data for data in data_list if any(data)])) out_text = StringIO() out_text.write(header+'\n') for item in zipped_list: out_text.write('\t'.join((str(item_item) for item_item in item))+'\n') return out_text.getvalue() def plot_freq(self, dic, data, title='Spectrum', x_label='Frequency Deviation'): # discards the old graph self.freq_subplot.hold(False) uc = ng.pipe.make_uc(dic, data) (re, im, ab) = self.freq_subplot.plot(uc.hz_scale(), data.real, 'r-', uc.hz_scale(), data.imag, 'g-', uc.hz_scale(), np.core.umath.absolute(data), 'm--') re.set_label('Real Part') im.set_label('Imag Part') ab.set_label('Absolute') self.freq_subplot.legend() self.freq_subplot.set_title(title) self.freq_subplot.set_xlabel(x_label + ' / ' + 'hz') # refresh canvas self.canvas.draw() # refresh data self.freq_data = [uc.hz_scale(), data.real, data.imag, np.absolute(data)] def plot_glue(self, x, y, y_list, title='Glue', x_label='Frequency', show = 'sum'): # discards the old graph self.glue_subplot.hold(False) if show == 'sum': (re, im, ab) = self.glue_subplot.plot(x, y.real, 'r-', x, y.imag, 'g-', x, np.core.umath.absolute(y), 'm--') re.set_label('Real Part') im.set_label('Imag Part') ab.set_label('Absolute') # refresh data self.glue_data = [x, y.real, y.imag, np.absolute(y)] else: self.glue_subplot.plot(x, y_list) self.glue_subplot.legend() self.glue_subplot.set_xlabel(x_label + ' / ' + 'hz') self.glue_subplot.set_title(title) # refresh canvas self.canvas.draw() def plot_int(self, int_plot_dic, title='Integral', x_label='No X Label'): # discards the old graph self.int_subplot.hold(False) (int_0_re, int_0_im, int_0_ab, int_1_re, int_1_im, int_1_ab, int_2_re, int_2_im, int_2_ab, int_3_re, int_3_im, int_3_ab,) = self.int_subplot.plot(int_plot_dic[0][0], np.asarray(int_plot_dic[0][1]).real, 'r--', int_plot_dic[0][0], np.asarray(int_plot_dic[0][1]).imag, 'r-.', int_plot_dic[0][0], np.core.umath.absolute(int_plot_dic[0][1]), 'r-', int_plot_dic[1][0], np.asarray(int_plot_dic[1][1]).real, 'k--', int_plot_dic[1][0], np.asarray(int_plot_dic[1][1]).imag, 'k-.', int_plot_dic[1][0], np.core.umath.absolute(int_plot_dic[1][1]), 'k-', int_plot_dic[2][0], np.asarray(int_plot_dic[2][1]).real, 'g--', int_plot_dic[2][0], np.asarray(int_plot_dic[2][1]).imag, 'g-.', int_plot_dic[2][0], np.core.umath.absolute(int_plot_dic[2][1]), 'g-', int_plot_dic[3][0], np.asarray(int_plot_dic[3][1]).real, 'm--', int_plot_dic[3][0], np.asarray(int_plot_dic[3][1]).imag, 'm-.', int_plot_dic[3][0], np.core.umath.absolute(int_plot_dic[3][1]), 'm-') int_0_re.set_label('Integral 0 Re') int_0_im.set_label('Integral 0 Im') int_0_ab.set_label('Integral 0 ABS') int_1_re.set_label('Integral 1 Re') int_1_im.set_label('Integral 1 Im') int_1_ab.set_label('Integral 1 ABS') int_2_re.set_label('Integral 2 Re') int_2_im.set_label('Integral 2 Im') int_2_ab.set_label('Integral 2 ABS') int_3_re.set_label('Integral 3 Re') int_3_im.set_label('Integral 3 Im') int_3_ab.set_label('Integral 3 ABS') self.int_subplot.legend() self.int_subplot.set_title(title) self.int_subplot.set_xlabel(x_label) # refresh canvas self.canvas.draw() # refresh data self.int_data = [int_plot_dic[0][0], np.asarray(int_plot_dic[0][1]).real, np.asarray(int_plot_dic[0][1]).imag, np.core.umath.absolute(int_plot_dic[0][1]), int_plot_dic[1][0], np.asarray(int_plot_dic[1][1]).real, np.asarray(int_plot_dic[1][1]).imag, np.core.umath.absolute(int_plot_dic[1][1]), int_plot_dic[2][0], np.asarray(int_plot_dic[2][1]).real, np.asarray(int_plot_dic[2][1]).imag, np.core.umath.absolute(int_plot_dic[2][1]), int_plot_dic[3][0], np.asarray(int_plot_dic[3][1]).real, np.asarray(int_plot_dic[3][1]).imag, np.core.umath.absolute(int_plot_dic[3][1])]
class RoastGraphWidget(): def __init__(self, graphXValueList = None, graphYValueList = None, animated = False, updateMethod = None, animatingMethod = None): self.graphXValueList = graphXValueList or [] self.graphYValueList = graphYValueList or [] self.counter = 0 self.updateMethod = updateMethod self.animated = animated self.animatingMethod = animatingMethod # Check if graph should continue to graph def create_graph(self): # Create the graph widget. graphWidget = QWidget() graphWidget.setObjectName("graph") # Style attributes of matplotlib. plt.rcParams['lines.linewidth'] = 3 plt.rcParams['lines.color'] = '#2a2a2a' plt.rcParams['font.size'] = 10. self.graphFigure = plt.figure(facecolor='#444952') self.graphCanvas = FigureCanvas(self.graphFigure) # Add graph widgets to layout for graph. graphVerticalBox = QVBoxLayout() graphVerticalBox.addWidget(self.graphCanvas) graphWidget.setLayout(graphVerticalBox) # Animate the the graph with new data if self.animated: animateGraph = animation.FuncAnimation(self.graphFigure, self.graph_draw, interval=1000) else: self.graph_draw() return graphWidget def graph_draw(self, *args, **kwargs): # Start graphing the roast if the roast has started. if self.animatingMethod(): self.updateMethod() self.graphFigure.clear() self.graphAxes = self.graphFigure.add_subplot(111) self.graphAxes.plot_date(self.graphXValueList, self.graphYValueList, '#8ab71b') # Add formatting to the graphs. self.graphAxes.set_ylabel('TEMPERATURE (°F)') self.graphAxes.set_xlabel('TIME') self.graphFigure.subplots_adjust(bottom=0.2) ax = self.graphAxes.get_axes() ax.xaxis.set_major_formatter(DateFormatter('%M:%S')) ax.set_axis_bgcolor('#23252a') self.graphCanvas.draw() def append_x(self, xCoord): self.counter += 1 currentTime = datetime.datetime.fromtimestamp(self.counter) self.graphXValueList.append(matplotlib.dates.date2num(currentTime)) self.graphYValueList.append(xCoord) def clear_graph(self): self.graphXValueList = [] self.graphYValueList = [] self.counter = 0 self.graphFigure.clear() def save_roast_graph(self): userDesktop = os.path.expanduser('~/Desktop') fileName = os.path.join(userDesktop + "/Roast_Graph") i = 0 while os.path.exists('{}{:d}.png'.format(fileName, i)): i += 1 self.graphFigure.savefig('{}{:d}.png'.format(fileName, i))
class Compressor(QtWidgets.QMainWindow): def __init__(self): super(Compressor, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.input_file_name = '' self.output_file_name = '' self.ui.pushButton.clicked.connect(self.file_btn_click) self.ui.compButton.clicked.connect(self.compress_btn_click) self.ui.dirButton.clicked.connect(self.saveFileDialog) self.ui.decompButton.clicked.connect(self.decompress_btn_click) self.ui.comp_decomp_btn.clicked.connect(self.analise_click) self.clear_table() def autolabel(self, rects, ax, rotation): for rect in rects: height = rect.get_height() ax.annotate('{}'.format(height), xy=(rect.get_x() + rect.get_width() / 2, height / 2), xytext=(0, 3), textcoords="offset points", ha='center', va='bottom', rotation=rotation) def show_one_graph(self, uncomp, comp): self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.ui.verticalLayout.addWidget(self.canvas) color = "#" + ''.join( [random.choice('0123456789ABCDEF') for j in range(6)]) axs = self.figure.subplots(gridspec_kw={'right': 0.9, 'left': 0.2}) axs.set_title('Default/Compressed') axs.set_ylabel('Size, Kb') rects = axs.bar(['Default', 'Compressed'], [uncomp, comp], color=color) self.autolabel(rects, axs, 0) def show_graphs(self, size, comp_time, decomp_time, coeff): self.figure = plt.figure() self.figure0 = plt.figure() self.canvas = FigureCanvas(self.figure) self.canvas_0 = FigureCanvas(self.figure0) self.ui.verticalLayout.addWidget(self.canvas) self.ui.verticalLayout.addWidget(self.canvas_0) size_names = list(size.keys()) size_values = list(size.values()) comp_time_names = list(comp_time.keys()) comp_time_values = list(comp_time.values()) decomp_time_names = list(decomp_time.keys()) decomp_time_values = list(decomp_time.values()) coeff_names = list(coeff.keys()) coeff_values = list(coeff.values()) width = 0.6 axs = self.figure.subplots(1, 2, gridspec_kw={ 'wspace': 0.3, 'right': 0.97 }) rects1 = axs[0].bar(size_names, size_values, color='red', width=width) axs[0].set_title('Compressed Sizes') axs[0].set_ylabel('Size, Kb') rects2 = axs[1].bar(coeff_names, coeff_values, color='green', width=width) axs[1].set_title('Compression Ratio') axs0 = self.figure0.subplots(1, 2, gridspec_kw={ 'wspace': 0.3, 'right': 0.97 }) rects0_1 = axs0[0].bar(comp_time_names, comp_time_values, color='blue', width=width) axs0[0].set_title('Compressing') axs0[0].set_ylabel('Time, sec') rects0_2 = axs0[1].bar(decomp_time_names, decomp_time_values, color='yellow', width=width) axs0[1].set_title('Decompressing') self.figure0.suptitle('Time') self.autolabel(rects1, axs[0], 90) self.autolabel(rects2, axs[1], 90) self.autolabel(rects0_1, axs0[0], 90) self.autolabel(rects0_2, axs0[1], 90) self.canvas.draw() self.canvas_0.draw() def clear_table(self): self.ui.tableWidget.clear() self.ui.tableWidget.setRowCount(3) self.ui.tableWidget.setColumnCount(6) self.ui.tableWidget.setHorizontalHeaderLabels( ('Uncompressed', 'Compressed', 'Compression Ratio', 'Compression Time', 'Decompression Time', ' Size Percentage ')) self.ui.tableWidget.setVerticalHeaderLabels(('LZW', 'LZ77', 'LZ78')) self.ui.tableWidget.resizeColumnsToContents() def clear_graphs(self): for i in reversed(range(self.ui.verticalLayout.count())): widgetToRemove = self.ui.verticalLayout.itemAt(i).widget() self.ui.verticalLayout.removeWidget(widgetToRemove) widgetToRemove.setParent(None) def analise_click(self): self.ui.infoLabel.setText('') file = self.input_file_name.replace('Compressor', '') self.clear_graphs() self.ui.checkBoxW.setChecked(True) self.ui.checkBox77.setChecked(True) self.ui.checkBox78.setChecked(True) uncompressedW, compressedW, ratio_w, c_stop_time_w, percantage_w, steps_w = \ self.compressW(self.ui.textEdit.toPlainText(), self.ui.spinBox_LZW.value(), self.output_file_name) _, _, _, d_stop_time_w, _ = self.decompressW( self.input_file_name + '.lzw', self.ui.spinBox_LZW.value()) self.ui.listWidget.clear() self.show_one_table_row([ uncompressedW, compressedW, ratio_w, c_stop_time_w, d_stop_time_w, percantage_w ], 0) self.show_steps(steps_w, 1) uncompressed77, compressed77, ratio_77, c_stop_time_77, percantage_77, steps_77 = \ self.compress77(self.ui.textEdit.toPlainText(), self.ui.spinBox_LZ77.value(), self.output_file_name) _, _, _, d_stop_time_77, _ = self.decompress77( self.input_file_name + '.lz77', self.ui.spinBox_LZ77.value()) self.ui.listWidget.clear() self.show_one_table_row([ uncompressed77, compressed77, ratio_77, c_stop_time_77, d_stop_time_77, percantage_77 ], 1) self.show_steps(steps_w, 1) self.ui.listWidget_2.clear() self.show_steps(steps_77, 2) uncompressed78, compressed78, ratio_78, c_stop_time_78, percantage_78, steps_78 = \ self.compress78(self.ui.textEdit.toPlainText(), self.output_file_name) _, _, _, d_stop_time_78, _ = self.decompress78(self.input_file_name + '.lz78') self.ui.listWidget_3.clear() self.show_one_table_row([ uncompressed78, compressed78, ratio_78, c_stop_time_78, d_stop_time_78, percantage_78 ], 2) self.show_steps(steps_78, 3) sizes = { 'Default': round(os.path.getsize(file + '.txt') / 1024, 1), 'LZW': round(compressedW / 1024, 1), 'LZ77': round(compressed77 / 1024, 1), 'LZ78': round(compressed78 / 1024, 1) } comp_times = { 'LZW': round(c_stop_time_w, 1), 'LZ77': round(c_stop_time_77, 1), 'LZ78': round(c_stop_time_78, 1) } decomp_times = { 'LZW': round(d_stop_time_w, 1), 'LZ77': round(d_stop_time_77, 1), 'LZ78': round(d_stop_time_78, 1) } coeff = { 'LZW': round(ratio_w, 1), 'LZ77': round(ratio_77, 1), 'LZ78': round(ratio_78, 1) } self.show_graphs(sizes, comp_times, decomp_times, coeff) self.ui.tableWidget.resizeColumnsToContents() def show_one_table_row(self, data, row): i = 0 data[-1] = round(data[-1], 10) for item in data: cellinfo = QTableWidgetItem(str(item)) cellinfo.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.ui.tableWidget.setItem(row, i, cellinfo) i += 1 def show_steps(self, data, number): if number == 1: for step in data: item = QtWidgets.QListWidgetItem() item.setText( str(step[0]) + ': <' + str(step[1]) + ', ' + str(step[2]) + '>') item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsSelectable | Qt.ItemIsDragEnabled) self.ui.listWidget.addItem(item) elif number == 2: for step in data: item = QtWidgets.QListWidgetItem() item.setText('<' + str(step[0]) + ', ' + str(step[1]) + ', ' + str(step[2]) + '>') item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsSelectable | Qt.ItemIsDragEnabled) self.ui.listWidget_2.addItem(item) else: for step in data: item = QtWidgets.QListWidgetItem() item.setText(str(step[0]) + ': <' + str(step[1]) + '>') item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsSelectable | Qt.ItemIsDragEnabled) self.ui.listWidget_3.addItem(item) def compress_btn_click(self): self.ui.infoLabel.setText('') try: self.clear_graphs() self.clear_table() self.ui.listWidget.clear() self.ui.listWidget_3.clear() self.ui.listWidget_2.clear() if self.ui.checkBoxW.isChecked(): data_w = self.compressW(self.ui.textEdit.toPlainText(), self.ui.spinBox_LZW.value(), self.output_file_name) new_data = list(data_w) new_data.insert(4, '- ' * 15) self.show_steps(new_data[6], 1) self.show_one_graph(data_w[0], data_w[1]) self.show_one_table_row(new_data[:6], 0) if self.ui.checkBox77.isChecked(): data_77 = self.compress77(self.ui.textEdit.toPlainText(), self.ui.spinBox_LZ77.value(), self.output_file_name) new_data = list(data_77) new_data.insert(4, '- ' * 15) self.show_steps(new_data[6], 2) self.show_one_graph(data_77[0], data_77[1]) self.show_one_table_row(new_data[:6], 1) if self.ui.checkBox78.isChecked(): data_78 = self.compress78(self.ui.textEdit.toPlainText(), self.output_file_name) new_data = list(data_78) new_data.insert(4, '- ' * 15) self.show_steps(new_data[6], 3) self.show_one_graph(data_78[0], data_78[1]) self.show_one_table_row(new_data[:6], 2) if not self.ui.checkBoxW.isChecked( ) and not self.ui.checkBox77.isChecked( ) and not self.ui.checkBox78.isChecked(): self.ui.infoLabel.setText( 'None of algorithms is chosen\nChose one of the algorithm to continue!' ) self.ui.tableWidget.resizeColumnsToContents() except: self.ui.infoLabel.setText( 'Something went wrong...\nCheck settings and try again!') def decompress_btn_click(self): self.ui.infoLabel.setText('') try: self.clear_graphs() self.clear_table() self.ui.listWidget.clear() self.ui.listWidget_3.clear() self.ui.listWidget_2.clear() if self.ui.checkBoxW.isChecked(): data_w = self.decompressW(self.input_file_name, self.ui.spinBox_LZW.value()) new_list = list(data_w) new_list.insert(3, '- ' * 15) self.show_one_graph(data_w[0], data_w[1]) self.show_one_table_row(new_list, 0) if self.ui.checkBox78.isChecked(): data_78 = self.decompress78(self.input_file_name) new_list = list(data_78) new_list.insert(3, '- ' * 15) self.show_one_graph(data_78[0], data_78[1]) self.show_one_table_row(new_list, 2) if self.ui.checkBox77.isChecked(): data_77 = self.decompress77(self.input_file_name, self.ui.spinBox_LZ77.value()) new_list = list(data_77) new_list.insert(3, '- ' * 15) self.show_one_graph(data_77[0], data_77[1]) self.show_one_table_row(new_list, 1) if not self.ui.checkBoxW.isChecked( ) and not self.ui.checkBox77.isChecked( ) and not self.ui.checkBox78.isChecked(): self.ui.infoLabel.setText( 'None of algorithms is chosen\nChose one of the algorithm to continue!' ) self.ui.tableWidget.resizeColumnsToContents() except: self.ui.infoLabel.setText( 'Something went wrong...\nCheck settings and try again!') def file_btn_click(self): self.ui.infoLabel.setText('') self.ui.checkBoxW.setChecked(False) self.ui.checkBox78.setChecked(False) self.ui.checkBox77.setChecked(False) try: file_name = self.openFileNameDialog() if file_name[-4:] == '.lzw': self.ui.textEdit.setText('Decompress: ' + file_name) self.ui.checkBoxW.setChecked(True) self.input_file_name = file_name elif file_name[-5:] == '.lz77': self.ui.textEdit.setText('Decompress: ' + file_name) self.ui.checkBox77.setChecked(True) self.input_file_name = file_name elif file_name[-5:] == '.lz78': self.ui.checkBox78.setChecked(True) self.input_file_name = file_name self.ui.textEdit.setText('Decompress: ' + file_name) else: try: with open(file_name, 'r') as file: self.ui.textEdit.setText(file.read()) except: with open(file_name, 'r', encoding='utf-8') as file: self.ui.textEdit.setText(file.read()) except: file_name = '' def openFileNameDialog(self): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getOpenFileName( self, "Choose File", "", "All Files (*);;Python Files (*.py)", options=options) if fileName: self.output_file_name = fileName.replace('.txt', '').replace( '.lzw', '').replace('.lz78', '').replace('.lz77', '').replace( 'Compressor', '') + 'Compressor' self.ui.outEdit.setText(self.output_file_name) self.input_file_name = fileName.replace('.txt', '') + 'Compressor' return fileName def saveFileDialog(self): self.ui.infoLabel.setText('') options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog dirName = QFileDialog.getExistingDirectory(self, "Choose directory", options=options) if dirName: if self.input_file_name: self.output_file_name = dirName + '/' + self.input_file_name else: self.output_file_name = dirName + '/Compressor' self.ui.outEdit.setText(self.output_file_name) def LZ77_search(self, search, look_ahead): ls = len(search) llh = len(look_ahead) if (ls == 0): return (0, 0, look_ahead[0]) if (llh) == 0: return (-1, -1, "") best_length = 0 best_offset = 0 buf = search + look_ahead search_pointer = ls for i in range(0, ls): length = 0 while buf[i + length] == buf[search_pointer + length]: length = length + 1 if search_pointer + length == len(buf): length = length - 1 break if i + length >= search_pointer: break if length > best_length: best_offset = i best_length = length return (best_offset, best_length, buf[search_pointer + best_length]) def compress77(self, input, win_size, output_file): start_time = time.time() #extra credit x = 16 MAXSEARCH = int(win_size) MAXLH = int(math.pow(2, (x - (math.log(MAXSEARCH, 2))))) file = open(output_file + '.lz77', "wb") searchiterator, lhiterator = 0, 0 steps = [] while lhiterator < len(input): search = input[searchiterator:lhiterator] look_ahead = input[lhiterator:lhiterator + MAXLH] (offset, length, char) = self.LZ77_search(search, look_ahead) steps.append([offset, length, char]) shifted_offset = offset << 6 offset_and_length = shifted_offset + length placeholder = ' ' try: ol_bytes = pack(">Hc", offset_and_length, bytes(char, 'utf-8')) except: ol_bytes = pack(">Hc", offset_and_length, bytes(placeholder, 'utf-8')) file.write(ol_bytes) lhiterator = lhiterator + length + 1 searchiterator = lhiterator - MAXSEARCH if searchiterator < 0: searchiterator = 0 file.close() return os.path.getsize(output_file.replace('Compressor', '') + '.txt'), \ os.path.getsize(output_file + '.lz77'), os.path.getsize(output_file.replace('Compressor', '') + '.txt')/\ os.path.getsize(output_file + '.lz77'), time.time() - start_time, os.path.getsize(output_file + '.lz77')/\ os.path.getsize(output_file.replace('Compressor', '') + '.txt')*100, steps def decompress77(self, input_file, search): start_time = time.time() try: processed = open(self.output_file_name + 'LZ77.txt', "wb") except: processed = open(self.output_file_name + 'LZ77.txt', "wb", encoding='utf-8') MAX_SEARCH = search file = open(input_file, "rb") input = file.read() chararray = bytearray() i = 0 while i < len(input): (offset_and_length, char) = unpack(">Hc", input[i:i + 3]) offset = offset_and_length >> 6 length = offset_and_length - (offset << 6) i = i + 3 if (offset == 0) and (length == 0): chararray += char else: iterator = len(chararray) - MAX_SEARCH if iterator < 0: iterator = offset else: iterator += offset for pointer in range(length): chararray += bytes(chr(chararray[iterator + pointer]), 'utf-8') chararray += char processed.write(chararray) return os.path.getsize(self.output_file_name + 'LZ77.txt'), \ os.path.getsize(input_file), os.path.getsize(self.output_file_name + 'LZ77.txt')/\ os.path.getsize(input_file), time.time() - start_time, os.path.getsize(input_file)/\ os.path.getsize(self.output_file_name + 'LZ77.txt')*100 def compressW(self, data, dictionary_size, output_file): start_time = time.time() n = 256 maximum_table_size = pow(2, int(n)) data = data.replace('—', '-').replace('…', '...').replace('–', '-')\ .replace('№', '!n').replace('’', '\'').replace('‘', '\'').replace('“', '\'')\ .replace('”', '\'').replace('„', '\'') dictionary = {chr(i): i for i in range(dictionary_size)} string = "" compressed_data = [] steps = [] for symbol in data: string_plus_symbol = string + symbol if string_plus_symbol in dictionary: string = string_plus_symbol else: compressed_data.append(dictionary[string]) if (len(dictionary) <= maximum_table_size): dictionary[string_plus_symbol] = dictionary_size dictionary_size += 1 string = symbol try: steps.append([symbol, string, dictionary[string]]) except: string = ' ' steps.append([symbol, string, dictionary[string]]) if string in dictionary: compressed_data.append(dictionary[string]) out_file = open(output_file + ".lzw", "wb") for data in compressed_data: out_file.write(pack('>L', int(data))) out_file.close() print(output_file) return os.path.getsize(output_file.replace('Compressor', '') + '.txt'), \ os.path.getsize(output_file + '.lzw'), os.path.getsize(output_file.replace('Compressor', '') + '.txt')/\ os.path.getsize(output_file + '.lzw'), time.time() - start_time, os.path.getsize(output_file + '.lzw')/\ os.path.getsize(output_file.replace('Compressor', '') + '.txt')*100, steps def decompressW(self, input_file, dictionary_size): start_time = time.time() compressed_data = [] file = open(input_file, "rb") while True: rec = file.read(4) if len(rec) != 4: break (data, ) = unpack('>L', rec) compressed_data.append(data) compressed = compressed_data dictionary = dict([(x, chr(x)) for x in range(dictionary_size)]) result = StringIO() w = chr(compressed.pop(0)) result.write(w) for k in compressed: if k in dictionary: entry = dictionary[k] elif k == dictionary_size: entry = w + w[0] else: raise ValueError('Bad compressed k: %s' % k) result.write(entry) dictionary[dictionary_size] = w + entry[0] dictionary_size += 1 w = entry write_file = open(self.output_file_name + 'LZW.txt', 'w', encoding='ANSI') write_file.write(result.getvalue()) return os.path.getsize(self.output_file_name + 'LZW.txt'), \ os.path.getsize(input_file), os.path.getsize(self.output_file_name + 'LZW.txt')/\ os.path.getsize(input_file), time.time() - start_time, os.path.getsize(input_file)/\ os.path.getsize(self.output_file_name + 'LZW.txt')*100 def compress78(self, data, output_file): start_time = time.time() encoded_file = open(output_file + '.lz78', 'wb') text_from_file = data text_from_file = text_from_file.replace('1', '!a').replace('2', '!b').replace('3', '!c')\ .replace('4', '!d').replace('5', '!e').replace('6', '!f')\ .replace('7', '!g').replace('8', '!h').replace('9', '!i').replace('0', '!g').replace('…', '')\ .replace('–', '-').replace('№', '!n').replace('’', '\'').replace('‘', '\'').replace('“', '\'')\ .replace('”', '\'').replace('„', '\'').replace('«', '\'').replace('»', '\'').replace('°', '\'') dict_of_codes = {text_from_file[0]: '1'} encoded_file.write(pack('>Ic', 0, bytes(text_from_file[0], 'utf-8'))) text_from_file = text_from_file[1:] combination = '' code = 2 result = '' steps = [] for char in text_from_file: combination += char if combination not in dict_of_codes: dict_of_codes[combination] = str(code) if len(combination) == 1: step = '0' + combination step_num = 0 encoded_file.write(pack('>Ic', 0, bytes(char, 'utf-8'))) result += step else: step = dict_of_codes[combination[0:-1]] + combination[-1] step_num = int(dict_of_codes[combination[0:-1]]) encoded_file.write( pack('>Ic', step_num, bytes(char, 'utf-8'))) result += step code += 1 combination = '' steps.append([char, step]) encoded_file.close() return os.path.getsize(output_file.replace('Compressor', '') + '.txt'), \ os.path.getsize(output_file + '.lz78'), os.path.getsize(output_file.replace('Compressor', '') + '.txt')/\ os.path.getsize(output_file + '.lz78'), time.time() - start_time, os.path.getsize(output_file + '.lz78')/\ os.path.getsize(output_file.replace('Compressor', '') + '.txt')*100, steps def decompress78(self, input_file): start_time = time.time() output_file = self.output_file_name try: decoded_file = open(output_file + 'LZ78.txt', 'w', encoding='utf=8') except: decoded_file = open(output_file + 'LZ78.txt', 'w') file = open(input_file, "rb") input = file.read() text_from_file = '' i = 0 while i < len(input): (num, char) = unpack(">Ic", input[i:i + 5]) i = i + 5 text_from_file += str(num) + char.decode() dict_of_codes = {'0': '', '1': text_from_file[1]} decoded_file.write(dict_of_codes['1']) text_from_file = text_from_file[2:] combination = '' code = 2 decoded_text = '' for char in text_from_file: if char in '1234567890': combination += char else: dict_of_codes[str(code)] = dict_of_codes[combination] + char decoded_text += dict_of_codes[combination] + char combination = '' code += 1 decoded_text = decoded_text.replace('!a', '1').replace('!b', '2').replace('!c', '3')\ .replace('!d', '4').replace('!e', '5').replace('!f', '6')\ .replace('!g', '7').replace('!h', '8').replace('!i', '9').replace('!g', '0') decoded_file.write(decoded_text) decoded_file.close() return os.path.getsize(self.output_file_name + 'LZ78.txt'), \ os.path.getsize(input_file), os.path.getsize(self.output_file_name + 'LZ78.txt')/\ os.path.getsize(input_file), time.time() - start_time, os.path.getsize(input_file)/\ os.path.getsize(self.output_file_name + 'LZ78.txt')*100
class Window(QDialog): # https://stackoverflow.com/questions/12459811/how-to-embed-matplotlib-in-pyqt-for-dummies def __init__(self, parent=None): super(Window, self).__init__(parent) # a figure instance to plot on self.figure = plt.figure() # this is the Canvas Widget that displays the `figure` # it takes the `figure` instance as a parameter to __init__ self.canvas = FigureCanvas(self.figure) # this is the Navigation widget # it takes the Canvas widget and a parent self.toolbar = NavigationToolbar(self.canvas, self) # Just some button connected to `plot` method self.button1 = QPushButton('Plot') self.button1.clicked.connect(self.plot) # Just some button connected to `imshow` method self.button2 = QPushButton('Imshow') self.button2.clicked.connect(self.imshow) # set the layout layout = QVBoxLayout() # layout.addWidget(self.toolbar) layout.addWidget(self.canvas) layout.addWidget(self.button1) layout.addWidget(self.button2) self.setLayout(layout) self.num = 10 def plot(self): ''' plot some random stuff ''' print("plot...") # random data data = [random.random() for i in range(self.num)] # instead of ax.hold(False) self.figure.clear() # create an axis ax = self.figure.add_subplot(111) # discards the old graph # ax.hold(False) # deprecated, see above # plot data # ax.imshow(hbt.dist(self.num)) ax.plot(data, '*-') # refresh canvas self.canvas.draw() def imshow(self): ''' plot some random stuff ''' print('Imshow...') # instead of ax.hold(False) self.figure.clear() # create an axis ax = self.figure.add_subplot(111) # plot data ax.imshow(hbt.dist(self.num)) # ax.plot(data, '*-') # refresh canvas self.canvas.draw() def keyPressEvent(self, event): # http://zetcode.com/gui/pyqt5/eventssignals/ print ("Key hit: {}".format(event.key())) if event.key() == Qt.Key_Escape: self.close() if event.key() == Qt.Key_Left: self.num -= 1 self.plot() if event.key() == Qt.Key_Right: self.num += 1 self.plot()
class GraphTab(QWidget): def __init__(self, parent=None, tabs=None, tab_name="Graph Tab"): super(GraphTab, self).__init__(parent) logger.debug("Setting up Graph Tab.") self.root = parent self.tabs = tabs self.tab_name = tab_name self.data_list = [] self.init_ui() def init_ui(self): self.graph_tab = QWidget() self.tabs.addTab(self.graph_tab, self.tab_name) logger.debug("Making Attribution Box") attribution_box = QGroupBox("Event Attribution Data") tab_layout = QGridLayout() self.graph_tab.setLayout(tab_layout) self.event_name_label = QLabel("Name of Event: ") self.ecm_rtc_label = QLabel("ECM Real Time Clock at Event: ") self.actual_rtc_label = QLabel("Actual Real Time Clock at Event: ") self.engine_hours_label = QLabel("Engine Hours at Event: ") self.odometer_label = QLabel("Distance Reading at Event: ") attribution_layout = QVBoxLayout() attribution_layout.addWidget(self.event_name_label) attribution_layout.addWidget(self.ecm_rtc_label) attribution_layout.addWidget(self.actual_rtc_label) attribution_layout.addWidget(self.engine_hours_label) attribution_layout.addWidget(self.odometer_label) attribution_box.setLayout(attribution_layout) logger.debug("Finished Setting Attribution Layout") self.data_table = QTableWidget() self.data_table.setSelectionBehavior(QAbstractItemView.SelectColumns) logger.debug("Finished with Data Table") self.csv_button = QPushButton("Export CSV") self.csv_button.clicked.connect(self.export_csv) logger.debug("Finished with CSV") self.figure = mpl.Figure(figsize=(7, 9)) self.canvas = FigureCanvas(self.figure) self.top_axis = self.figure.add_subplot(3, 1, 1) self.top_axis.set_ylabel("Road Speed (mph)") self.middle_axis = self.figure.add_subplot(3, 1, 2) self.middle_axis.set_ylabel("Throttle Position (%)") self.bottom_axis = self.figure.add_subplot(3, 1, 3) self.bottom_axis.set_ylabel("Brake Switch Status") self.bottom_axis.set_xlabel("Event Time (sec)") self.canvas.draw() self.toolbar = NavigationToolbar(self.canvas, self.graph_tab) logger.debug("Finished with toolbar") # set the layout tab_layout.addWidget(attribution_box, 0, 0, 1, 1) tab_layout.addWidget(self.data_table, 1, 0, 1, 1) tab_layout.addWidget(self.csv_button, 2, 0, 1, 1) tab_layout.addWidget(self.canvas, 0, 1, 2, 1) tab_layout.addWidget(self.toolbar, 2, 1, 1, 1) logger.debug("Finished with UI for Tab {}".format(self.tab_name)) def export_csv(self): logger.debug("Export CSV") filters = "Comma Separated Values (*.csv);;All Files (*.*)" selected_filter = "Comma Separated Values (*.csv)" fname = QFileDialog.getSaveFileName(self, 'Export CSV', self.tab_name + ".csv", filters, selected_filter) if fname[0]: if fname[0][-4:] == ".csv": filename = fname[0] else: filename = fname[0] + ".csv" try: with open(filename, 'w', newline='') as csv_file: writer = csv.writer(csv_file) writer.writerow(["The University of Tulsa"]) writer.writerow([ "Date of Creation:", "{}".format(get_local_time_string(time.time())) ]) writer.writerows(['', ["Vehicle Component Information"]]) writer.writerows( get_list_from_dict( self.root.data_package["Component Information"])) writer.writerows(['', ["Vehicle Distance Information"]]) writer.writerows( get_list_from_dict( self.root.data_package["Distance Information"])) writer.writerows(['', ["Vehicle Time Information"]]) writer.writerows( get_list_from_dict( self.root.data_package["ECU Time Information"])) writer.writerows(['', ["Event Attribution Data"]]) writer.writerow([''] + self.event_name_label.text().split(": ")) writer.writerow([''] + self.ecm_rtc_label.text().split(": ")) writer.writerow([''] + self.actual_rtc_label.text().split(": ")) writer.writerow([''] + self.engine_hours_label.text().split(": ")) writer.writerow([''] + self.odometer_label.text().split(": ")) writer.writerows(['', ["Event Table Data"]]) writer.writerows(self.data_list) writer.writerows(['', ["User Data"]]) writer.writerows(self.root.user_data.get_user_data_list()) self.root.sign_file(filename) base_name = os.path.basename(filename) QMessageBox.information( self, "Export Success", "The comma separated values file\n{}\nwas successfully exported. A verification signature was also saved as\n{}." .format(base_name, base_name + ".signature")) except PermissionError: logger.info( "Permission Error - Please close the file and try again.") QMessageBox.warning( self, "Permission Error", "Permission Error\nThe file may be open in another application.\nPlease close the file and try again." ) def update_plot_xy(self): for key, value in self.data.items(): self.ax.plot(value["X"], value["Y"], value["Marker"], label=key) self.ax.grid(True) self.ax.legend() [xmin, xmax, ymin, ymax] = self.ax.axis() try: self.ax.axis([xmin, xmax, self.ymin, self.ymax]) except: pass self.ax.set_xlabel(self.x_label) self.ax.set_ylabel(self.y_label) self.ax.set_title(self.title) if self.update_button.isChecked(): self.canvas.draw()
class RoastGraphWidget(): def __init__(self, graphXValueList=None, graphYValueList=None, animated=False, updateMethod=None, animatingMethod=None): self.graphXValueList = graphXValueList or [] self.graphYValueList = graphYValueList or [] self.counter = 0 self.updateMethod = updateMethod self.animated = animated # Check if graph should continue to graph. self.animatingMethod = animatingMethod self.widget = self.create_graph() def create_graph(self): # Create the graph widget. graphWidget = QtWidgets.QWidget() graphWidget.setObjectName("graph") # Style attributes of matplotlib. plt.rcParams['lines.linewidth'] = 3 plt.rcParams['lines.color'] = '#2a2a2a' plt.rcParams['font.size'] = 10. self.graphFigure = plt.figure(facecolor='#444952') self.graphCanvas = FigureCanvas(self.graphFigure) # Add graph widgets to layout for graph. graphVerticalBox = QtWidgets.QVBoxLayout() graphVerticalBox.addWidget(self.graphCanvas) graphWidget.setLayout(graphVerticalBox) # Animate the the graph with new data if self.animated: animateGraph = animation.FuncAnimation(self.graphFigure, self.graph_draw, interval=1000) else: self.graph_draw() return graphWidget def graph_draw(self, *args, **kwargs): # Start graphing the roast if the roast has started. if self.animatingMethod is not None: if self.animatingMethod(): self.updateMethod() self.graphFigure.clear() self.graphAxes = self.graphFigure.add_subplot(111) self.graphAxes.plot_date(self.graphXValueList, self.graphYValueList, '#8ab71b') # Add formatting to the graphs. self.graphAxes.set_ylabel('TEMPERATURE (°F)') self.graphAxes.set_xlabel('TIME') self.graphFigure.subplots_adjust(bottom=0.2) ax = self.graphAxes.get_axes() ax.xaxis.set_major_formatter(DateFormatter('%M:%S')) ax.set_axis_bgcolor('#23252a') self.graphCanvas.draw() def append_x(self, xCoord): self.counter += 1 currentTime = datetime.datetime.fromtimestamp(self.counter) self.graphXValueList.append(matplotlib.dates.date2num(currentTime)) self.graphYValueList.append(xCoord) def clear_graph(self): self.graphXValueList = [] self.graphYValueList = [] self.counter = 0 self.graphFigure.clear() def save_roast_graph(self): try: file_name = QtWidgets.QFileDialog.getSaveFileName( QtWidgets.QWidget(), 'Save Roast Graph', os.path.expanduser('~/'), 'Graph (*.png);;All Files (*)') self.graphFigure.savefig(file_name[0], bbox_inches='tight') except FileNotFoundError: # Occurs if file browser is canceled pass else: pass
class GraphDialog(QDialog): def __init__(self, parent=None, title="Graph"): super(GraphDialog, self).__init__(parent) self.setWindowTitle(title) self.figure = mpl.Figure() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas, self) self.data = {} self.ax = self.figure.add_subplot(111) self.ymin = None self.ymax = None self.x_label = "" self.y_label = "" self.title = "" self.update_button = QCheckBox("Dynamically Update Table") self.update_button.setChecked(True) # set the layout layout = QVBoxLayout() layout.addWidget(self.canvas) layout.addWidget(self.update_button) layout.addWidget(self.toolbar) self.setLayout(layout) #self.show() def plot(self): ''' plot data ''' self.ax.cla() #self.ax.hold(False) for key, value in self.data.items(): self.ax.plot(value["X"], value["Y"], value["Marker"], label=key) self.ax.grid(True) self.ax.legend() [xmin, xmax, ymin, ymax] = self.ax.axis() try: self.ax.axis([xmin, xmax, self.ymin, self.ymax]) except: pass xfmt = md.DateFormatter('%Y-%m-%d %H:%M:%S') self.ax.xaxis.set_major_formatter(xfmt) self.figure.autofmt_xdate() self.ax.set_xlabel(self.x_label) self.ax.set_ylabel(self.y_label) self.ax.set_title(self.title) if self.update_button.isChecked(): self.canvas.draw() def plot_xy(self): self.ax.cla() #self.ax.hold(False) for key, value in self.data.items(): self.ax.plot(value["X"], value["Y"], value["Marker"], label=key) self.ax.grid(True) self.ax.legend() [xmin, xmax, ymin, ymax] = self.ax.axis() try: self.ax.axis([xmin, xmax, self.ymin, self.ymax]) except: pass self.ax.set_xlabel(self.x_label) self.ax.set_ylabel(self.y_label) self.ax.set_title(self.title) if self.update_button.isChecked(): self.canvas.draw() def add_data(self, data, marker='*-', label=""): x, y = zip(*data) #unpacks a list of tuples dates = [dt.datetime.fromtimestamp(ts) for ts in x] self.data[label] = {"X": dates, "Y": y, "Marker": marker} def add_xy_data(self, data, marker='*-', label=""): x, y = zip(*data) #unpacks a list of tuples # logger.debug("X data:") # logger.debug(x) # logger.debug("Y data:") # logger.debug(y) self.data[label] = { "X": [float(val) for val in x], "Y": [float(val) for val in y], "Marker": marker } def set_yrange(self, min_y, max_y): self.ymax = max_y self.ymin = min_y def set_xlabel(self, label): self.x_label = label def set_ylabel(self, label): self.y_label = label def set_title(self, label): self.title = label
class Window(QDialog): def __init__(self, params_object, compound_object, library_object, editable=False, parent=None): QDialog.__init__(self, parent) self.params = params_object self.compound = compound_object self.library = library_object self.editable = editable self.modified = False self.setWindowTitle("NMRmix: Information for Compound %s" % self.compound.id) self.createWidgets() self.layoutWidgets() self.createConnections() self.drawData() self.setTable() def createWidgets(self): self.compoundTabs = QTabWidget() self.compoundTabs.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) self.compoundTabs.setStyleSheet('QTabBar {font-weight: bold;}' 'QTabBar::tab {color: black;}' 'QTabBar::tab:selected {color: red;}') self.initInfo() self.initSpectrum() self.initPeaklistTable() def initInfo(self): # Compound Info Tab self.compoundtab1 = QWidget() self.compoundtab1.setStyleSheet("QWidget{background-color: white;}") self.idLabel = QLabel("<h2><font color='red'>%s</font></h2>" % self.compound.id) self.idLabel.setAlignment(Qt.AlignCenter) self.nameLabel = QLabel("<b>Name:</b> %s" % self.compound.name) self.groupLabel = QLabel("<b>Group:</b> %s" % self.compound.group) self.bmrbLabel = QLabel("<b>BMRB ID:</b> %s" % self.compound.bmrb_id) self.bmrbLabel.setTextInteractionFlags(Qt.LinksAccessibleByMouse) self.bmrbLabel.setOpenExternalLinks(True) self.hmdbLabel = QLabel("<b>HMDB ID:</b> %s" % self.compound.hmdb_id) self.hmdbLabel.setTextInteractionFlags(Qt.LinksAccessibleByMouse) self.hmdbLabel.setOpenExternalLinks(True) self.pubchemLabel = QLabel("<b>PubChem CID:</b> <a href='https://pubchem.ncbi.nlm.nih.gov/compound/%s'>%s</a>" % (self.compound.pubchem_id, self.compound.pubchem_id)) self.pubchemLabel.setTextInteractionFlags(Qt.LinksAccessibleByMouse) self.pubchemLabel.setOpenExternalLinks(True) self.keggLabel = QLabel("<b>KEGG ID:</b> <a href='http://www.genome.jp/dbget-bin/www_bget?cpd:%s'>%s</a>" % (self.compound.kegg_id, self.compound.kegg_id)) self.keggLabel.setTextInteractionFlags(Qt.LinksAccessibleByMouse) self.keggLabel.setOpenExternalLinks(True) self.structureLabel = QLabel("<b>Structure: </b>") self.structure = QLabel() if self.compound.smiles: self.smilesLabel = QLabel("<b>SMILES:</b> %s" % self.compound.smiles) try: self.compound.set2DStructure() molformula = "" for count, i in enumerate(self.compound.molformula): try: if count > 0: if self.compound.molformula[count-1] == "-" or self.compound.molformula[count-1] == "+": j = "<sup>%d</sup>" % int(i) else: j = "<sub>%d</sub>" % int(i) else: j = i except: if i == "-" or i == "+": j = "<sup>%s</sup>" % i else: j = i molformula += j if self.compound.molwt and self.compound.molformula: self.molformulaLabel = QLabel("<b>Mol. Formula:</b> %s" % molformula) self.molwtLabel = QLabel("<b>Mol. Weight:</b> %0.3f" % self.compound.molwt) else: self.molformulaLabel = QLabel("<b>Mol. Formula:</b> Unknown") self.molwtLabel = QLabel("<b>Mol. Weight:</b> Unknown") if self.compound.structure_image: self.pixmap = QPixmap.fromImage(self.compound.structure_qt) self.structure.setText("") self.structure.setPixmap(self.pixmap) self.structure.setAlignment(Qt.AlignCenter) else: self.structure.setText("No Structure Available") self.structure.setAlignment(Qt.AlignCenter) except: self.molformulaLabel = QLabel("<b>Mol. Formula:</b> Unknown") self.molwtLabel = QLabel("<b>Mol. Weight:</b> Unknown") self.structure.setText("No Structure Available") self.structure.setAlignment(Qt.AlignCenter) else: self.smilesLabel = QLabel("<b>SMILES:</b> Unknown") self.molformulaLabel = QLabel("<b>Mol. Formula:</b> Unknown") self.molwtLabel = QLabel("<b>Mol. Weight:</b> Unknown") self.structure.setText("No Structure Available") self.structure.setAlignment(Qt.AlignCenter) self.editinfoButton = QPushButton('Edit Compound Info') self.editinfoButton.setToolTip("Opens a window to edit compound information") # TODO: Set tooltip self.restoreinfoButton = QPushButton('Restore Compound Info') self.restoreinfoButton.setToolTip("Resets compound information to original imported values") # TODO: Set tooltip self.savestructureButton = QPushButton('Save Structure Image') self.savestructureButton.setToolTip("Tooltip") # TODO: Set tooltip def initSpectrum(self): # Compound Spectrum Tab matplotlib.projections.register_projection(My_Axes) self.scale = 1.05 self.show_ignored = True self.show_ignored_peaks = True self.compoundtab2 = QWidget() self.compoundtab2.setStyleSheet("QWidget{background-color: white;}") self.fig = plt.gcf() self.fig.patch.set_facecolor('white') self.canvas = FigureCanvas(self.fig) self.canvas.setParent(self) self.canvas.setFocusPolicy(Qt.StrongFocus) self.canvas.setFocus() self.canvas.setMinimumHeight(100) self.canvas.setMinimumWidth(100) self.mpl_toolbar = NavigationToolbar2(self.canvas, self) self.mpl_toolbar.hide() self.mpl_toolbar.pan() self.canvas.mpl_connect('scroll_event', self.zooming) ins = "Left-click+drag to pan x-axis / Right-click+drag to zoom x-axis / Scroll-wheel to change intensity scale" self.instructionLabel = QLabel(ins) self.instructionLabel.setStyleSheet('QLabel{qproperty-alignment: AlignCenter; font-size: 10px;}') self.showignoredregionsCheckBox = QCheckBox("Show Ignored Regions") self.showignoredregionsCheckBox.setToolTip("Shows the ranges set by the solvent/buffer ignore regions, if any.") self.showignoredregionsCheckBox.setLayoutDirection(Qt.RightToLeft) self.showignoredregionsCheckBox.setChecked(True) self.showignoredpeaksCheckBox = QCheckBox("Show Ignored Peaks") self.showignoredpeaksCheckBox.setToolTip("Shows any compound peaks that are in the solvent/buffer ignore regions, if any.\n" "These peaks are ignored and are not evaluated during mixing.") self.showignoredpeaksCheckBox.setLayoutDirection(Qt.RightToLeft) self.showignoredpeaksCheckBox.setChecked(True) self.resetviewButton = QPushButton("Reset View") self.resetviewButton.setToolTip("Resets the spectrum to the default view.") self.savespectrumButton = QPushButton("Save Spectrum") self.savespectrumButton.setToolTip("Saves the image in the spectrum window.") def initPeaklistTable(self): # Compound Peaklist Tab self.compoundtab3 = QWidget() self.compoundtab3.setStyleSheet("QWidget{background-color: white;}") self.peakTable = QTableWidget(0, 4, self) # self.peakTable.setMinimumWidth(400) self.peakTable.setSelectionMode(QAbstractItemView.NoSelection) self.peakTable.setSelectionBehavior(QAbstractItemView.SelectRows) self.peakTable.setSelectionMode(QAbstractItemView.SingleSelection) self.peakTable.setSortingEnabled(True) self.peakTable.sortByColumn(1, Qt.AscendingOrder) self.peakTable.setEditTriggers(QAbstractItemView.NoEditTriggers) self.peakTable.setColumnWidth(0, 100) self.peakTable.setColumnWidth(1, 200) self.peakTable.setColumnWidth(2, 150) self.peakTable.setColumnWidth(3, 100) self.peakTable.horizontalHeader().setStretchLastSection(True) self.tableheader = ['Status', 'Chemical Shift', 'Intensity', 'Width'] self.peakTable.setHorizontalHeaderLabels(self.tableheader) self.peakTable.horizontalHeader().setStyleSheet("QHeaderView {font-weight: bold;}") self.peakTable.verticalHeader().setStyleSheet("QHeaderView {font-weight: bold;}") self.addButton = QPushButton("Add") self.addButton.setToolTip("Opens a window to add a new peak to the table") self.editButton = QPushButton("Edit") self.editButton.setToolTip("Opens a window to edit the currently selected peak.") self.removeButton = QPushButton("Remove") self.removeButton.setToolTip("Inactivates the currently selected peak.") self.restorepeaklistButton = QPushButton("Restore") self.restorepeaklistButton.setToolTip("Restores the original peak list.") self.savepeaksButton = QPushButton("Save") self.savepeaksButton.setToolTip("Saves the current peak list as a custom peak list file.\n" "This file can be used as the peak list for future library imports.") if not self.editable: self.removeButton.hide() self.restorepeaklistButton.hide() self.savepeaksButton.hide() self.editButton.hide() self.addButton.hide() self.closeButton = QPushButton("Close") self.closeButton.setStyleSheet("QPushButton{color: red; font-weight:bold;}") self.closeButton.setFixedWidth(200) def layoutWidgets(self): winLayout = QVBoxLayout(self) infoLayout = QVBoxLayout(self.compoundtab1) infoLayout.addWidget(self.idLabel) infoLayout.addWidget(self.nameLabel) infoLayout.addWidget(self.groupLabel) infoLayout.addWidget(self.bmrbLabel) infoLayout.addWidget(self.hmdbLabel) infoLayout.addWidget(self.pubchemLabel) infoLayout.addWidget(self.keggLabel) infoLayout.addWidget(self.smilesLabel) infoLayout.addWidget(self.molformulaLabel) infoLayout.addWidget(self.molwtLabel) infoLayout.addWidget(self.structureLabel) infoLayout.addItem(QSpacerItem(400, 20, QSizePolicy.Maximum, QSizePolicy.Maximum)) infoLayout.addWidget(self.structure) infoLayout.addItem(QSpacerItem(400, 20, QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)) infobuttonLayout = QHBoxLayout() infobuttonLayout.addWidget(self.editinfoButton) infobuttonLayout.addWidget(self.restoreinfoButton) infobuttonLayout.addWidget(self.savestructureButton) infoLayout.addLayout(infobuttonLayout) self.compoundtab1.setLayout(infoLayout) self.compoundTabs.addTab(self.compoundtab1, "Compound Info") spectraLayout = QVBoxLayout(self.compoundtab2) spectraLayout.addWidget(self.canvas) spectraLayout.addWidget(self.instructionLabel) spectraCheckBoxLayout = QHBoxLayout() spectraCheckBoxLayout.addItem(QSpacerItem(0,0, QSizePolicy.MinimumExpanding)) spectraCheckBoxLayout.addWidget(self.showignoredregionsCheckBox) spectraCheckBoxLayout.addItem(QSpacerItem(15, 0, QSizePolicy.Maximum)) spectraCheckBoxLayout.addWidget(self.showignoredpeaksCheckBox) spectraCheckBoxLayout.addItem(QSpacerItem(0,0, QSizePolicy.MinimumExpanding)) spectraLayout.addLayout(spectraCheckBoxLayout) spectraButtonLayout = QHBoxLayout() spectraButtonLayout.addWidget(self.resetviewButton) spectraButtonLayout.addWidget(self.savespectrumButton) spectraLayout.addLayout(spectraButtonLayout) self.compoundtab2.setLayout(spectraLayout) self.compoundTabs.addTab(self.compoundtab2, "Simulated Spectrum") tableLayout = QVBoxLayout() tableLayout.addWidget(self.peakTable) tablebuttonLayout = QHBoxLayout() tablebuttonLayout.addWidget(self.addButton) tablebuttonLayout.addWidget(self.editButton) tablebuttonLayout.addWidget(self.removeButton) tablebuttonLayout.addWidget(self.restorepeaklistButton) tablebuttonLayout.addWidget(self.savepeaksButton) tableLayout.addLayout(tablebuttonLayout) self.compoundtab3.setLayout(tableLayout) self.compoundTabs.addTab(self.compoundtab3, "Peaklist Table") winLayout.addWidget(self.compoundTabs) winLayout.addItem(QSpacerItem(0, 20, QSizePolicy.Maximum)) winLayout.addWidget(self.closeButton) winLayout.setAlignment(self.closeButton, Qt.AlignCenter) def createConnections(self): self.editinfoButton.clicked.connect(self.editInfo) self.restoreinfoButton.clicked.connect(self.restoreInfo) self.savestructureButton.clicked.connect(self.saveStructure) self.showignoredregionsCheckBox.stateChanged.connect(self.handleIgnored) self.showignoredpeaksCheckBox.stateChanged.connect(self.handleIgnoredPeaks) self.resetviewButton.clicked.connect(self.resetSpectra) self.savespectrumButton.clicked.connect(self.saveSpectra) self.addButton.clicked.connect(self.addPeak) self.removeButton.clicked.connect(self.removePeak) self.editButton.clicked.connect(self.editPeak) self.restorepeaklistButton.clicked.connect(self.resetPeakList) self.savepeaksButton.clicked.connect(self.savePeakList) self.closeButton.clicked.connect(self.closeEvent) def editInfo(self): editinfo_win = InfoWindow(self.params, self.compound) if editinfo_win.exec_(): self.modified = True self.updateInfo() def restoreInfo(self): self.compound.restoreOriginalDescriptors() self.modified = True self.updateInfo() def saveStructure(self): filename = "%s.png" % self.compound.id filepath = os.path.join(self.params.work_dir, filename) filestype = "static (*.png *.jpg *.svg)" fileObj = QFileDialog.getSaveFileName(self, "Save Structure Image", directory=filepath, filter=filestype) if fileObj[0]: self.compound.structure_image.save(fileObj[0]) def handleIgnored(self): if self.showignoredregionsCheckBox.isChecked(): self.show_ignored = True self.drawData() else: self.show_ignored = False self.drawData() def handleIgnoredPeaks(self): if self.showignoredpeaksCheckBox.isChecked(): self.show_ignored_peaks = True self.drawData() else: self.show_ignored_peaks = False self.drawData() def resetSpectra(self): self.mpl_toolbar.home() self.drawData() def saveSpectra(self): filename = "%s.png" % self.compound.id filepath = os.path.join(self.params.work_dir, filename) filestype = "static (*.png *.jpg *.svg)" fileObj = QFileDialog.getSaveFileName(self, caption="Save Simulated Compound Spectrum", directory=filepath, filter=filestype) if fileObj[0]: self.fig.set_size_inches(12, 8) plt.savefig(fileObj[0], dpi=200) def addPeak(self): addpeak_win = PeakWindow(self.params, self.compound) if addpeak_win.exec_(): self.compound.addPeak(tuple(addpeak_win.table_values)) self.setTable() self.modified = True self.drawData() def editPeak(self): selected = self.peakTable.currentRow() # status = self.peakTable.item(selected, 0).text() chemshift = float(self.peakTable.item(selected, 1).text()) intensity = float(self.peakTable.item(selected, 2).text()) width = self.peakTable.item(selected, 3).text() if width != 'Default': curr_peak = (chemshift, intensity, float(width)) else: curr_peak = (chemshift, intensity) editpeak_win = PeakWindow(self.params, self.compound, curr_peak) if editpeak_win.exec_(): self.compound.editPeak(tuple(editpeak_win.table_values)) self.setTable() self.modified = True self.drawData() def removePeak(self): try: selected = self.peakTable.currentRow() # status = self.peakTable.item(selected, 0).text() chemshift = float(self.peakTable.item(selected, 1).text()) intensity = float(self.peakTable.item(selected, 2).text()) width = self.peakTable.item(selected, 3).text() peak_list = self.compound.mix_peaklist + self.compound.ignored_peaklist if width != 'Default': curr_peak = (chemshift, intensity, float(width)) else: curr_peak = (chemshift, intensity) min_diff = 9999999 min_i = 9999999 for i, peak in enumerate(peak_list): diff = abs(float(peak[1]) - float(curr_peak[1])) if diff < min_diff: min_diff = diff min_i = i matched_peak = peak_list[min_i] self.compound.removePeak(matched_peak) self.setTable() self.modified = True self.drawData() except Exception as e: # print(e) pass def resetPeakList(self): self.compound.resetPeakList() self.setTable() self.modified = True self.drawData() def savePeakList(self): filename = "%s_custom.csv" % self.compound.id filepath = os.path.join(self.params.peaklist_dir, filename) filestype = "static (*.csv)" fileObj = QFileDialog.getSaveFileName(self, caption="Save Custom Peak List", directory=filepath, filter=filestype) if fileObj[0]: filename = os.path.basename(fileObj[0]) peak_list = self.compound.mix_peaklist + self.compound.ignored_peaklist with open(fileObj[0], 'w') as peaks_csv: writer = csv.writer(peaks_csv) header = ['ChemShift', 'Intensity', 'Width'] writer.writerow(header) writer.writerows(peak_list) for i, row in enumerate(self.library.library_csv): if row[1] == self.compound.id: self.library.library_csv[i][5] = filename self.library.library_csv[i][6] = 'USER' def lorentzian(self, mu, hwhm, intensity): def f(x): numerator = hwhm ** 2 denominator = pow((x - mu), 2) + (hwhm ** 2) total = intensity * (numerator / denominator) return(total) return(f) def drawPeakData(self, peaks, color="red", alpha=1.0): for peak in peaks: if len(peak) == 3: width = peak[2] * 3 hwhm = peak[2] * self.params.peak_display_width else: width = self.params.peak_range * 3 hwhm = self.params.peak_range * self.params.peak_display_width mean = peak[0] intensity = peak[1] shifts = (np.arange(mean-width, mean+width, 0.001)) f = self.lorentzian(mean, hwhm, intensity) y = ([f(x) for x in shifts]) self.ax.plot(shifts, y, color=color, linewidth=1, alpha=alpha) def drawIgnoredRegions(self, ignored_list): updated_ignored = list(set(ignored_list)) for ignored in updated_ignored: ignored_width = abs(ignored[1] - ignored[0]) ignored_center = (ignored[1] + ignored[0]) / 2 self.ax.bar(ignored_center, 100, width=ignored_width, color='gray', align='center', edgecolor='gray', linewidth=1, alpha=0.6, picker=True) self.ax.bar(ignored_center, -100, width=ignored_width, color='gray', align='center', edgecolor='gray', linewidth=1, alpha=0.6, picker=True) def drawData(self): self.fig.clear() self.ax = self.fig.add_subplot(111, projection="My_Axes") ignored_regions = [] pos_peaks = self.compound.mix_peaklist ignored_peaks = self.compound.ignored_peaklist ignored_regions += list(self.compound.ignored_regions.values()) self.drawPeakData(pos_peaks) if self.show_ignored_peaks: self.drawPeakData(ignored_peaks, color='gray', alpha=0.8) if self.show_ignored: self.drawIgnoredRegions(ignored_regions) self.ax.xaxis.set_minor_locator(matplotlib.ticker.AutoMinorLocator()) self.ax.spines['bottom'].set_position('zero') self.ax.get_xaxis().tick_bottom() self.ax.get_yaxis().tick_left() self.ax.set_xlim(self.params.shift_range[self.params.nuclei]) self.ax.set_ylim([0, 1]) self.ax.set_xlabel('Chemical Shift (ppm)', fontweight='bold') self.ax.set_ylabel('Intensity (Normalized)', fontweight='bold') self.fig.tight_layout() self.canvas.draw() def clearTable(self): """Deletes all rows in the table.""" while self.peakTable.rowCount() > 0: self.peakTable.removeRow(0) def setTable(self): self.peakTable.setSortingEnabled(False) self.clearTable() tablesize = len(self.compound.mix_peaklist) + len(self.compound.ignored_peaklist) self.peakTable.setRowCount(tablesize) for row, peak in enumerate(self.compound.mix_peaklist): self.peakTable.setRowHeight(row, 50) active = QTableWidgetItem("ACTIVE") active.setTextAlignment(Qt.AlignCenter) self.peakTable.setItem(row, 0, active) chemshift = QTableWidgetItem() chemshift.setTextAlignment(Qt.AlignCenter) chemshift.setData(Qt.DisplayRole, "%0.3f" % peak[0]) self.peakTable.setItem(row, 1, chemshift) intensity = QTableWidgetItem() intensity.setTextAlignment(Qt.AlignCenter) intensity.setData(Qt.DisplayRole, "%0.3f" % peak[1]) self.peakTable.setItem(row, 2, intensity) width = QTableWidgetItem() width.setTextAlignment(Qt.AlignCenter) if len(peak) == 3: width.setData(Qt.DisplayRole, "%0.3f" % peak[2]) else: width.setText('Default') self.peakTable.setItem(row, 3, width) if len(self.compound.mix_peaklist) > 0: next_row = len(self.compound.mix_peaklist) else: next_row = 0 for row, peak in enumerate(self.compound.ignored_peaklist, start=next_row): self.peakTable.setRowHeight(row, 40) active = QTableWidgetItem("IGNORED") active.setTextAlignment(Qt.AlignCenter) self.peakTable.setItem(row, 0, active) chemshift = QTableWidgetItem() chemshift.setTextAlignment(Qt.AlignCenter) chemshift.setData(Qt.DisplayRole, "%0.3f" % peak[0]) self.peakTable.setItem(row, 1, chemshift) intensity = QTableWidgetItem() intensity.setTextAlignment(Qt.AlignCenter) intensity.setData(Qt.DisplayRole, "%0.3f" % peak[1]) self.peakTable.setItem(row, 2, intensity) width = QTableWidgetItem() width.setTextAlignment(Qt.AlignCenter) if len(peak) == 3: width.setData(Qt.DisplayRole, "%0.3f" % peak[2]) else: width.setText('Default') self.peakTable.setItem(row, 3, width) if len(self.compound.mix_peaklist)+len(self.compound.ignored_peaklist) > 0: next_row = len(self.compound.mix_peaklist)+len(self.compound.ignored_peaklist) else: next_row = 0 for row, peak in enumerate(self.compound.removed_peaklist, start=next_row): self.peakTable.setRowHeight(row, 40) active = QTableWidgetItem("REMOVED") active.setTextAlignment(Qt.AlignCenter) self.peakTable.setItem(row, 0, active) chemshift = QTableWidgetItem() chemshift.setTextAlignment(Qt.AlignCenter) chemshift.setData(Qt.DisplayRole, float("%0.3f" % peak[0])) self.peakTable.setItem(row, 1, chemshift) intensity = QTableWidgetItem() intensity.setTextAlignment(Qt.AlignCenter) intensity.setData(Qt.DisplayRole, float("%0.3f" % peak[1])) self.peakTable.setItem(row, 2, intensity) if len(peak) == 3: width = QTableWidgetItem() width.setTextAlignment(Qt.AlignCenter) width.setData(Qt.DisplayRole, float("%0.3f" % peak[2])) self.peakTable.setItem(row, 3, width) self.peakTable.setSortingEnabled(True) self.peakTable.selectRow(0) def updateInfo(self): self.nameLabel.setText("<b>Name:</b> %s" % self.compound.name) self.groupLabel.setText("<b>Group:</b> %s" % self.compound.group) self.pubchemLabel.setText("<b>PubChem CID:</b> <a href='https://pubchem.ncbi.nlm.nih.gov/compound/%s'>%s</a>" % (self.compound.pubchem_id, self.compound.pubchem_id)) self.pubchemLabel.setTextInteractionFlags(Qt.LinksAccessibleByMouse) self.pubchemLabel.setOpenExternalLinks(True) self.keggLabel.setText("<b>KEGG ID:</b> <a href='http://www.genome.jp/dbget-bin/www_bget?cpd:%s'>%s</a>" % (self.compound.kegg_id, self.compound.kegg_id)) self.keggLabel.setTextInteractionFlags(Qt.LinksAccessibleByMouse) self.keggLabel.setOpenExternalLinks(True) if self.compound.smiles: self.smilesLabel.setText("<b>SMILES:</b> %s" % self.compound.smiles) try: self.compound.set2DStructure() molformula = "" for count, i in enumerate(self.compound.molformula): try: if count > 0: if self.compound.molformula[count-1] == "-" or self.compound.molformula[count-1] == "+": j = "<sup>%d</sup>" % int(i) else: j = "<sub>%d</sub>" % int(i) else: j = i except: if i == "-" or i == "+": j = "<sup>%s</sup>" % i else: j = i molformula += j self.molformulaLabel.setText("<b>Mol. Formula:</b> %s" % molformula) self.molwtLabel.setText("<b>Mol. Weight:</b> %0.3f" % self.compound.molwt) if self.compound.structure_image: self.pixmap = QPixmap.fromImage(self.compound.structure_qt) self.structure.setText("") self.structure.setPixmap(self.pixmap) self.structure.setAlignment(Qt.AlignCenter) else: self.structure.setText("No Structure Available") self.structure.setAlignment(Qt.AlignCenter) except: self.molformulaLabel.setText("<b>Mol. Formula:</b> Unknown") self.molwtLabel.setText("<b>Mol. Weight:</b> Unknown") else: self.smilesLabel.setText("<b>SMILES:</b> Unknown") self.molformulaLabel.setText("<b>Mol. Formula:</b> Unknown") self.molwtLabel.setText("<b>Mol. Weight:</b> Unknown") self.structure.setText("No Structure Available") self.structure.setAlignment(Qt.AlignCenter) for i, row in enumerate(self.library.library_csv): if row[1] == self.compound.id: self.library.library_csv[i][2] = self.compound.name self.library.library_csv[i][3] = self.compound.bmrb_id self.library.library_csv[i][4] = self.compound.hmdb_id self.library.library_csv[i][8] = self.compound.pubchem_id self.library.library_csv[i][9] = self.compound.kegg_id self.library.library_csv[i][10] = self.compound.smiles def zooming(self, event): cur_ylim = self.ax.get_ylim() cur_yrange = (cur_ylim[1] - cur_ylim[0]) if event.button == 'up': scale_factor = self.scale elif event.button == 'down': scale_factor = 1/self.scale else: scale_factor = 1 self.ax.set_ylim([0, (cur_yrange*scale_factor)]) self.canvas.draw() def acceptChanges(self): pass def closeEvent(self, event=False): self.fig.clear() QDialog.accept(self)
class univariaterowDlg(QtWidgets.QDialog, Ui_univariaterowDialog): def __init__(self, parent=None): super(univariaterowDlg, self).__init__(parent) self.setupUi(self) self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowCloseButtonHint | QtCore.Qt.WindowMaximizeButtonHint) self.XcomboBox.addItems(DS.Lr[DS.Ir]) self.XcomboBox.setCurrentIndex(0) self.histogramradioButton.setChecked(True) self.spinBox.setDisabled(True) self.TcheckBox.setChecked(True) self.XGcheckBox.setChecked(False) self.YGcheckBox.setChecked(False) self.XMcheckBox.setChecked(True) self.YMcheckBox.setChecked(True) self.XcheckBox.setChecked(True) self.YcheckBox.setChecked(True) self.ApplyButton.clicked.connect(self.redraw) self.ResetButton.clicked.connect(self.reset) self.BootmeanradioButton.clicked.connect(self.deactivate) self.BootsdradioButton.clicked.connect(self.deactivate) self.BoxCoxradioButton.clicked.connect(self.deactivate1) self.histogramradioButton.clicked.connect(self.activate) self.NormalityradioButton.clicked.connect(self.activate) self.PPCCradioButton.clicked.connect(self.activate) self.BoxradioButton.clicked.connect(self.activate) fig = Figure() ax = fig.add_subplot(111) ax.plot(np.array(0)) ax.set_xlim([0, 1]) ax.set_ylim([0, 1]) self.addmpl(fig) def activate(self): self.spinBox.setDisabled(True) self.TcheckBox.setDisabled(False) self.XcheckBox.setDisabled(False) self.YcheckBox.setDisabled(False) self.XMcheckBox.setDisabled(False) self.YMcheckBox.setDisabled(False) self.XGcheckBox.setDisabled(False) self.YGcheckBox.setDisabled(False) def deactivate(self): self.TcheckBox.setDisabled(True) self.XcheckBox.setDisabled(True) self.YcheckBox.setDisabled(True) self.XMcheckBox.setDisabled(True) self.YMcheckBox.setDisabled(True) self.XGcheckBox.setDisabled(True) self.YGcheckBox.setDisabled(True) self.spinBox.setDisabled(False) def deactivate1(self): self.TcheckBox.setDisabled(True) self.XcheckBox.setDisabled(True) self.YcheckBox.setDisabled(True) self.XMcheckBox.setDisabled(True) self.YMcheckBox.setDisabled(True) self.XGcheckBox.setDisabled(True) self.YGcheckBox.setDisabled(True) def redraw(self): def bootstrap(data, num_samples, statistic, alpha): n = len(data) idx = random.randint(0, n, (num_samples, n)) samples = data[idx] stat = np.sort(statistic(samples, 1)) return (stat[int((alpha / 2.0) * num_samples)], stat[int( (1 - alpha / 2.0) * num_samples)], samples) if self.XcomboBox.currentText( ) == 'all' and not self.trendradioButton.isChecked(): QtWidgets.QMessageBox.critical( self, 'Error', "All rows can be plotted \n only using : Trend !", QtWidgets.QMessageBox.Ok) return () color = 'blue' data = DS.Raw.iloc[DS.Ir, DS.Ic] data = pd.DataFrame(data.T) data.columns = np.array(data.columns, dtype='<U25') data = data.assign(Lc=DS.Lc[DS.Ic]) data = data.assign(Cc=DS.Cc[DS.Ic]) data = data[[self.XcomboBox.currentText(), 'Lc', 'Cc']] if data.shape[1] != 3: QtWidgets.QMessageBox.critical(self,'Error',"More rows have the same name",\ QtWidgets.QMessageBox.Ok) return () Nnan = data.isnull().sum().sum() > 0 data = data.dropna() Lc = data['Lc'].values Cc = data['Cc'].values data = data.drop('Lc', axis=1) data = data.drop('Cc', axis=1) Y = data.values.ravel() if Y.dtype == 'float' and Y.dtype == 'int': QtWidgets.QMessageBox.critical(self,'Error',"Some values are not numbers!",\ QtWidgets.QMessageBox.Ok) return () if self.CcheckBox.isChecked(): color = Cc[self.XcomboBox.currentIndex()] fig = Figure() ax = fig.add_subplot(111) if (self.BoxradioButton.isChecked()): medianprops = dict(marker='D', markeredgecolor='black', markerfacecolor=color) ax.boxplot(Y, vert=1, medianprops=medianprops) if self.YcheckBox.isChecked(): if self.YlineEdit.text(): ax.set_ylabel(self.YlineEdit.text()) if self.XcheckBox.isChecked(): if self.XlineEdit.text(): ax.set_xlabel(self.YlineEdit.text()) if Nnan: ax.annotate('NaN present', xy=(0.80, 0.95), xycoords='axes fraction') elif (self.NormalityradioButton.isChecked()): stats.probplot(Y, plot=ax) if self.XcheckBox.isChecked(): if self.XlineEdit.text(): ax.set_xlabel('Normal N(0,1) Statistic Medians') if self.YcheckBox.isChecked(): if self.YlineEdit.text(): ax.set_ylabel('Ordered Responce') if Nnan: ax.annotate('NaN present', xy=(0.05, 0.95), xycoords='axes fraction') elif (self.PPCCradioButton.isChecked()): stats.ppcc_plot(Y, -6, 6, plot=ax) if self.XcheckBox.isChecked(): if self.XlineEdit.text(): ax.set_xlabel('Shape Values') if self.YcheckBox.isChecked(): if self.YlineEdit.text(): ax.set_ylabel('Prob.Plot.Corr.Coef.') if Nnan: ax.annotate('NaN present', xy=(0.05, 0.95), xycoords='axes fraction') elif (self.BoxCoxradioButton.isChecked()): fig = Figure() if not (Y > 0).all(): QtWidgets.QMessageBox.critical(self,'Error',"Data must be strictly positive!",\ QtWidgets.QMessageBox.Ok) return () bins = np.linspace(Y.min(), Y.max(), 21) ax1 = fig.add_subplot(2, 2, 1, title="Original " + self.XcomboBox.currentText()) ax1.hist(Y, bins=bins, histtype='bar', color=color, alpha=0.5, orientation="vertical", label="x") if Nnan: ax1.annotate('NaN present', xy=(0.80, 0.95), xycoords='figure fraction') trans_y, lambda_ = stats.boxcox(Y) ax2 = fig.add_subplot(2, 2, 2, title='Transformed Data (lambda=' + str(round(lambda_, 2)) + ')') bins = np.linspace(np.amin(trans_y), np.amax(trans_y), 21) ax2.hist(trans_y, bins=bins, histtype='bar', color=color, alpha=0.5, orientation="vertical", label="x Transformed") ax3 = fig.add_subplot(2, 2, 3, title="Original " + self.XcomboBox.currentText()) stats.probplot(Y, dist='norm', plot=ax3) ax4 = fig.add_subplot(2, 2, 4) stats.probplot(trans_y, dist='norm', plot=ax4) ax4.set_title('Transformed Data (lambda=' + str(round(lambda_, 2)) + ')') elif (self.logisticradioButton.isChecked()): stats.probplot(Y, dist=stats.logistic, plot=ax) ax.set_xlabel('Quantiles') ax.set_ylabel("Ordered " + self.XcomboBox.currentText()) ax.set_title('Logistic', fontsize=12) if Nnan: ax.annotate('NaN present', xy=(0.80, 0.95), xycoords='axes fraction') elif (self.laplaceradioButton.isChecked()): stats.probplot(Y, dist=stats.laplace, plot=ax) ax.set_xlabel('Quantiles') ax.set_ylabel('Ordered ' + self.XcomboBox.currentText()) ax.set_title('Laplace', fontsize=12) if Nnan: ax.annotate('NaN present', xy=(0.80, 0.95), xycoords='axes fraction') elif (self.logammaradioButton.isChecked()): shape = float(self.logammadoubleSpinBox.value()) stats.probplot(Y, dist=stats.loggamma, sparams=shape, plot=ax) ax.set_xlabel('Quantiles') ax.set_ylabel("Ordered " + self.XcomboBox.currentText()) ax.set_title('Log Gamma with shape ' + str(shape), fontsize=12) if Nnan: ax.annotate('NaN present', xy=(0.80, 0.95), xycoords='axes fraction') elif (self.lognormalradioButton.isChecked()): shape = float(self.lognormdoubleSpinBox.value()) / 10. stats.probplot(Y, dist=stats.lognorm, sparams=(shape), plot=ax) ax.set_xlabel('Quantiles') ax.set_ylabel("Ordered " + self.XcomboBox.currentText()) ax.set_title('Log norm with shape ' + str(shape), fontsize=12) if Nnan: ax.annotate('NaN present', xy=(0.80, 0.95), xycoords='axes fraction') elif (self.BootmeanradioButton.isChecked()): fig = Figure() ax1 = fig.add_subplot(1, 2, 1, title="Historgram of " + self.XcomboBox.currentText()) low, high, samples = bootstrap(Y, self.spinBox.value(), np.mean, 0.05) points = np.mean(samples, 1) ax1.hist(points, 50, histtype='step') if Nnan: ax1.annotate('NaN present', xy=(0.80, 0.95), xycoords='figure fraction') ax2 = fig.add_subplot(1, 2, 2, title='Bootstrap 95% CI for mean') ax2.scatter(0.1 * (random.random(len(points)) - 0.5), points) ax2.plot([0.19, 0.21], [low, low], 'r', linewidth=2) ax2.plot([0.19, 0.21], [high, high], 'r', linewidth=2) ax2.plot([0.2, 0.2], [low, high], 'r', linewidth=2) ax2.set_xlim([-0.2, 0.3]) elif (self.BootsdradioButton.isChecked()): fig = Figure() ax1 = fig.add_subplot(1, 2, 1, title="Historgram of " + self.XcomboBox.currentText()) low, high, samples = bootstrap(Y, self.spinBox.value(), np.std, 0.05) points = np.std(samples, 1) ax1.hist(points, 50, histtype='step') if Nnan: ax1.annotate('NaN present', xy=(0.80, 0.95), xycoords='figure fraction') ax2 = fig.add_subplot( 1, 2, 2, title='Bootstrap 95% CI for standard deviation') ax2.scatter(0.1 * (random.random(len(points)) - 0.5), points) ax2.plot([0.19, 0.21], [low, low], 'r', linewidth=2) ax2.plot([0.19, 0.21], [high, high], 'r', linewidth=2) ax2.plot([0.2, 0.2], [low, high], 'r', linewidth=2) ax2.set_xlim([-0.2, 0.3]) elif (self.histogramradioButton.isChecked()): iqr = np.percentile(Y, [75, 25]) iqr = iqr[0] - iqr[1] n = Y.shape[0] dy = abs(float(Y.max()) - float(Y.min())) nbins = np.floor(dy / (2 * iqr) * n**(1 / 3)) + 1 nbins = 2 * nbins bins = np.linspace(Y.min(), Y.max(), nbins) ax.hist(Y, bins=bins, histtype='bar', color=color, alpha=0.5, orientation='vertical', label="X") if Nnan: ax.annotate('NaN present', xy=(0.80, 0.95), xycoords='axes fraction') elif (self.trendradioButton.isChecked()): nr = len(Y) ind = np.array(range(1, nr + 1)) ax.scatter(ind, Y, marker='o', color=color) if self.LcheckBox.isChecked(): ax.plot(ind, Y, color=color) if (nr > 30): itick = np.linspace(0, nr - 1, 20).astype(int) ltick = Lc[itick] else: itick = ind ltick = Lc ax.set_xlim([0, nr + 2]) ax.set_xticks(itick) ax.set_xticklabels(ltick, rotation='vertical') ax.set_ylabel(self.XcomboBox.currentText()) if Nnan: ax.annotate('NaN present', xy=(0.80, 0.95), xycoords='axes fraction') if self.TcheckBox.isChecked(): if self.TlineEdit.text(): ax.set_title(self.TlineEdit.text()) else: ax.set_title('') if self.XcheckBox.isChecked(): if self.XlineEdit.text(): ax.set_xlabel(self.XlineEdit.text()) else: ax.set_xlabel('') if self.YcheckBox.isChecked(): ax.set_ylabel(self.YlineEdit.text()) else: ax.set_ylabel('') if self.XGcheckBox.isChecked(): ax.xaxis.grid(True) else: ax.xaxis.grid(False) if self.YGcheckBox.isChecked(): ax.yaxis.grid(True) else: ax.yaxis.grid(False) if not self.XMcheckBox.isChecked(): ax.tick_params(axis='x', which='both', bottom='off', top='off', labelbottom='off') if not self.YMcheckBox.isChecked(): ax.tick_params(axis='y', which='both', left='off', right='off', labelleft='off') self.rmmpl() self.addmpl(fig) def reset(self): self.XcomboBox.setCurrentIndex(0) self.XGcheckBox.setChecked(False) self.YGcheckBox.setChecked(False) self.XMcheckBox.setChecked(False) self.YMcheckBox.setChecked(True) self.XcheckBox.setChecked(True) self.YcheckBox.setChecked(True) self.XlineEdit.setText('') self.YlineEdit.setText('') self.TlineEdit.setText('') self.update() def addmpl(self, fig): self.canvas = FigureCanvas(fig) self.mplvl.addWidget(self.canvas) self.canvas.draw() self.toolbar = NavigationToolbar(self.canvas, self.mplwindow, coordinates=True) self.mplvl.addWidget(self.toolbar) def rmmpl(self, ): self.mplvl.removeWidget(self.canvas) self.canvas.close() self.mplvl.removeWidget(self.toolbar) self.toolbar.close()
class FigureFrame(qw.QFrame): def __init__(self, parent=None): qw.QFrame.__init__(self, parent) # bgrgb = self.palette().color(qw.QPalette.Window).getRgb()[:3] fgcolor = plot.tango_colors['aluminium5'] dpi = 0.5*(self.logicalDpiX() + self.logicalDpiY()) font = qg.QFont() font.setBold(True) fontsize = font.pointSize() import matplotlib matplotlib.rcdefaults() if use_pyqt5: try: matplotlib.rcParams['backend'] = 'Qt5Agg' except ValueError: matplotlib.rcParams['backend'] = 'Qt4Agg' else: matplotlib.rcParams['backend'] = 'Qt4Agg' matplotlib.rc('xtick', direction='out', labelsize=fontsize) matplotlib.rc('ytick', direction='out', labelsize=fontsize) matplotlib.rc('xtick.major', size=8) matplotlib.rc('xtick.minor', size=4) matplotlib.rc('ytick.major', size=8) matplotlib.rc('ytick.minor', size=4) # matplotlib.rc( # 'figure', facecolor=tohex(bgrgb), edgecolor=tohex(fgcolor)) matplotlib.rc('figure', facecolor='white', edgecolor=tohex(fgcolor)) matplotlib.rc( 'font', family='sans-serif', weight='bold', size=fontsize, **{'sans-serif': [font.family()]}) matplotlib.rc('text', color=tohex(fgcolor)) matplotlib.rc('xtick', color=tohex(fgcolor)) matplotlib.rc('ytick', color=tohex(fgcolor)) matplotlib.rc('figure.subplot', bottom=0.15) matplotlib.rc('axes', linewidth=0.5, unicode_minus=False) matplotlib.rc( 'axes', facecolor='white', edgecolor=tohex(fgcolor), labelcolor=tohex(fgcolor)) try: from cycler import cycler matplotlib.rc( 'axes', prop_cycle=cycler( 'color', [to01(x) for x in plot.graph_colors])) except (ImportError, KeyError): try: matplotlib.rc('axes', color_cycle=[ to01(x) for x in plot.graph_colors]) except KeyError: pass try: matplotlib.rc('axes', labelsize=fontsize) except KeyError: pass try: matplotlib.rc('axes', labelweight='bold') except KeyError: pass from matplotlib.figure import Figure if use_pyqt5: from matplotlib.backends.backend_qt5agg import \ NavigationToolbar2QT as NavigationToolbar from matplotlib.backends.backend_qt5agg \ import FigureCanvasQTAgg as FigureCanvas else: try: from matplotlib.backends.backend_qt4agg import \ NavigationToolbar2QTAgg as NavigationToolbar except ImportError: from matplotlib.backends.backend_qt4agg import \ NavigationToolbar2QT as NavigationToolbar from matplotlib.backends.backend_qt4agg \ import FigureCanvasQTAgg as FigureCanvas layout = qw.QGridLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) self.setLayout(layout) self.figure = Figure(dpi=dpi) self.canvas = FigureCanvas(self.figure) self.canvas.setParent(self) self.toolbar = NavigationToolbar(self.canvas, self) layout.addWidget(self.toolbar, 0, 0) layout.addWidget(self.canvas, 1, 0) self.closed = False def gca(self): axes = self.figure.gca() beautify_axes(axes) return axes def gcf(self): return self.figure def draw(self): '''Draw with AGG, then queue for Qt update.''' self.canvas.draw() def closeEvent(self, ev): self.closed = True
class BackTestResult(QDialog): def __init__(self, ACid): super().__init__() f = FETCH() self.risk = f.fetch_risk(AC_id=ACid) self.account = f.fetch_account(AC_id=ACid) self.initUI() def initUI(self): self.resize(1000, 700) self.setWindowTitle("QUANT XH 金融终端") self.setWindowIcon(QIcon("static/icon.png")) self.figure = plt.figure(facecolor='#FFFFFF') self.canvas = FigureCanvas(self.figure) self.Draw() self.tb = QTextBrowser() self.tb.setFixedSize(300,500) self.tb.setFont(QFont("仿宋", 10)) for line in self.account["history"]: s = str(line[0]) if line[3] >= 0: s += " 买入" else: s += " 卖出" s += line[1] + "共" + str(abs(line[3])) + "股,单股价格是" + str(line[2]) + "\n" self.tb.append(s) self.hbox = QHBoxLayout() self.hbox.addWidget(self.canvas) self.hbox.addWidget(self.tb) self.grid = QGridLayout() label = QLabel() label.setText("回测收益:"+str(self.risk["profit"])) label.setFont(QFont("仿宋", 12)) self.grid.addWidget(label,0,0) label = QLabel() label.setText("年化回测收益:" + str(self.risk["annualize_return"])) label.setFont(QFont("仿宋", 12)) self.grid.addWidget(label, 0, 1) label = QLabel() label.setText("基准收益:" + str(self.risk["bm_profit"])) label.setFont(QFont("仿宋", 12)) self.grid.addWidget(label, 0, 2) label = QLabel() label.setText("年化基准收益:" + str(self.risk["bm_annualizereturn"])) label.setFont(QFont("仿宋", 12)) self.grid.addWidget(label, 0, 3) label = QLabel() label.setText("Alpha:" + str(self.risk["alpha"])) label.setFont(QFont("仿宋", 12)) self.grid.addWidget(label, 1, 0) label = QLabel() label.setText("Beta:" + str(self.risk["beta"])) label.setFont(QFont("仿宋", 12)) self.grid.addWidget(label, 1, 1) label = QLabel() label.setText("夏普率:" + str(self.risk["sharpe"])) label.setFont(QFont("仿宋", 12)) self.grid.addWidget(label, 1, 2) label = QLabel() label.setText("信息比率:" + str(self.risk["ir"])) label.setFont(QFont("仿宋", 12)) self.grid.addWidget(label, 1, 3) label = QLabel() label.setText("波动性:" + str(self.risk["volatility"])) label.setFont(QFont("仿宋", 12)) self.grid.addWidget(label, 2, 0) label = QLabel() label.setText("最大回撤:" + str(self.risk["max_dropback"])) label.setFont(QFont("仿宋", 12)) self.grid.addWidget(label, 2, 1) self.layout = QVBoxLayout() self.layout.addLayout(self.hbox) self.layout.addLayout(self.grid) self.setLayout(self.layout) def Draw(self): xs = [datetime.strptime(d, '%Y-%m-%d').date() for d in self.risk["totaltimeindex"]] plt.plot(xs,self.risk["assets"], color = 'red', linewidth = 2) plt.plot(xs,self.risk["benchmark_assets"], color="blue",linewidth=2) self.canvas.draw()
class FitMainGui(QtWidgets.QMainWindow): # define main GUI window of the simulator def __init__(self, parent=None): # initialize GUI super().__init__() # initialize fit parameter & fit status instance self.fit_par = FitParameter(1) self.fit_stat = FitStatus() # initialize input validity tracker self.fit_stat.input_valid = True # get log directory (local directory of the script) self.log_dir = os.getcwd() # get file directory (read last directory from .cfg file) self.current_dir = self.get_file_dir() # add aborted and successful file list self.list_aborted_file = [] self.list_success_file = [] # add menubar openAction = QtWidgets.QAction('Open', self) openAction.setShortcut('Ctrl+O') openAction.setStatusTip('Open Spectra') openAction.triggered.connect(self.open_file) self.menu = self.menuBar() self.menu.setNativeMenuBar(False) self.menu.addAction(openAction) # add status bar self.statusbar = self.statusBar() # set GUI layout self.set_main_grid() self.widget_main = QtWidgets.QWidget() self.widget_main.setLayout(self.layout_main) self.setCentralWidget(self.widget_main) # set program title self.setWindowTitle('Fit Spectra!') # show program window self.show() def set_main_grid(self): self.layout_main = QtWidgets.QGridLayout() self.layout_main.setSpacing(6) # add current_file label self.label_current_file = QtWidgets.QLabel() self.layout_main.addWidget(QtWidgets.QLabel('Current File:'), 0, 0) self.layout_main.addWidget(self.label_current_file, 0, 1, 1, 2) # add matplotlib canvas self.fig = plt.figure() self.canvas = FigureCanvas(self.fig) self.canvas.setFocus() self.mpl_toolbar = NavigationToolbar(self.canvas, self) self.click_counter = 0 # initialize click counter # connect the canvas to matplotlib standard key press events self.canvas.mpl_connect('key_press_event', self.mpl_key_press) # connect the canvas to mouse click events self.canvas.mpl_connect('button_press_event', self.mpl_click) self.layout_main.addWidget(self.mpl_toolbar, 1, 0, 1, 3) self.layout_main.addWidget(self.canvas, 2, 0, 1, 3) # add fit option layout self.layout_setting = QtWidgets.QGridLayout() # select lineshape self.combo_ftype = QtWidgets.QComboBox() self.combo_ftype.addItems(['Gaussian', 'Lorentzian']) # select number of derivatives self.combo_der = QtWidgets.QComboBox() self.combo_der.addItems(['0', '1', '2', '3', '4']) self.check_boxcar = QtWidgets.QCheckBox('Boxcar Smooth?') self.check_rescale = QtWidgets.QCheckBox('Rescale Intensity?') self.edit_boxcar = QtWidgets.QLineEdit('1') self.edit_rescale = QtWidgets.QLineEdit('1') self.edit_deg = QtWidgets.QLineEdit('0') self.edit_num_peak = QtWidgets.QLineEdit('1') self.layout_setting.addWidget(QtWidgets.QLabel('Lineshape Function'), 0, 0) self.layout_setting.addWidget(self.combo_ftype, 1, 0) self.layout_setting.addWidget(QtWidgets.QLabel('Derivative'), 0, 1) self.layout_setting.addWidget(self.combo_der, 1, 1) self.layout_setting.addWidget(self.check_boxcar, 2, 0) self.layout_setting.addWidget(self.edit_boxcar, 2, 1) self.layout_setting.addWidget(self.check_rescale, 3, 0) self.layout_setting.addWidget(self.edit_rescale, 3, 1) self.layout_setting.addWidget(QtWidgets.QLabel('PolyBaseline Degree'), 4, 0) self.layout_setting.addWidget(self.edit_deg, 4, 1) self.layout_setting.addWidget(QtWidgets.QLabel('Number of Peaks'), 5, 0) self.layout_setting.addWidget(self.edit_num_peak, 5, 1) self.layout_setting.addWidget(QtWidgets.QLabel('<<< Initial Guess >>>'), 6, 0, 2, 2) # connect signals # select combo box items self.combo_ftype.currentIndexChanged.connect(self.get_ftype) self.combo_der.currentIndexChanged.connect(self.get_der) # display/hide checked edit box self.edit_boxcar.hide() self.edit_rescale.hide() self.check_boxcar.stateChanged.connect(self.show_boxcar) self.check_rescale.stateChanged.connect(self.show_rescale) # check input validity self.edit_boxcar.textChanged.connect(self.check_int_validity) self.edit_rescale.textChanged.connect(self.check_double_validity) self.edit_deg.textChanged.connect(self.check_int_validity) self.edit_num_peak.textChanged.connect(self.set_par_layout) # add fit parameter layout for initial guess self.widget_par = QtWidgets.QWidget() self.layout_par = QtWidgets.QGridLayout() self.edit_par = [] self.set_par_layout() self.widget_par.setLayout(self.layout_par) self.scroll_par = QtWidgets.QScrollArea() self.scroll_par.setWidget(self.widget_par) self.scroll_par.setWidgetResizable(True) self.scroll_par.setMaximumHeight(600) self.layout_setting.addWidget(self.scroll_par, 8, 0, 1, 2) self.layout_main.addLayout(self.layout_setting, 2, 3) # add fit & Quit button btn_fit = QtWidgets.QPushButton('Fit Spectrum', self) btn_quit = QtWidgets.QPushButton('Quit', self) btn_quit.setShortcut('Ctrl+Q') self.layout_main.addWidget(btn_fit, 0, 3) self.layout_main.addWidget(btn_quit, 3, 3) btn_fit.clicked.connect(self.fit_routine) btn_quit.clicked.connect(self.close) def set_par_layout(self): text = self.edit_num_peak.text() try: self.fit_par.peak = abs(int(text)) green = '#00A352' self.edit_num_peak.setStyleSheet('border: 3px solid %s' % green) except ValueError: red = '#D63333' self.edit_num_peak.setStyleSheet('border: 3px solid %s' % red) self.fit_par.peak = 0 # set initial guess layout # clear previous parameters self.fit_par.par = np.zeros(self.fit_par.peak * self.fit_par.par_per_peak) self.edit_par = [] # clear previous widgets self.clear_item(self.layout_par) # clear layout self.click_counter = 0 # reset click counter # add widgets for i in range(self.fit_par.par_per_peak * self.fit_par.peak): peak_index = i // self.fit_par.par_per_peak + 1 par_index = i % self.fit_par.par_per_peak self.edit_par.append(QtWidgets.QLineEdit()) if par_index: # starting of a new peak self.layout_par.addWidget(QtWidgets.QLabel( '--- Peak {:d} ---'.format(peak_index)), 4*(peak_index-1), 0, 1, 2) self.layout_par.addWidget(QtWidgets.QLabel( self.fit_par.par_name[par_index]), i+peak_index, 0) self.layout_par.addWidget(self.edit_par[i], i+peak_index, 1) self.edit_par[i].setText('0.5') # set default value self.edit_par[i].textChanged.connect(self.check_double_validity) # --------- get all fitting options --------- def get_ftype(self, ftype): self.fit_par.ftype = ftype self.fit_par.par_name = self.fit_par.get_par_name(ftype) # refresh parameter layout self.set_par_layout() def get_der(self, der): self.fit_par.der = der def get_par(self): # if input is valid if self.fit_stat.input_valid == 2: for i in range(self.fit_par.par_per_peak * self.fit_par.peak): self.fit_par.par[i] = float(self.edit_par[i].text()) self.fit_par.boxwin = abs(int(self.edit_boxcar.text())) self.fit_par.rescale = abs(float(self.edit_rescale.text())) self.fit_par.deg = abs(int(self.edit_deg.text())) else: self.fit_stat.stat = 5 # --------- fit routine --------- def fit_routine(self): # if data loaded successfully if not self.fit_stat.stat: data_table, popt, uncertainty, ppoly = self.fit_try() # if fit failed, print information if self.fit_stat.stat: failure = QtWidgets.QMessageBox.information(self, 'Failure', self.fit_stat.print_stat(), QtWidgets.QMessageBox.Retry | QtWidgets.QMessageBox.Abort, QtWidgets.QMessageBox.Retry) # choose retry or ignore if failure == QtWidgets.QMessageBox.Retry: pass elif failure == QtWidgets.QMessageBox.Abort: self.pass_file() # if fit successful, ask user for save|retry option else: success = QtWidgets.QMessageBox.question(self, 'Save?', 'Save the fit if it looks good. \n ' + 'Otherwise retry a fit or abort this file ', QtWidgets.QMessageBox.Save | QtWidgets.QMessageBox.Retry | QtWidgets.QMessageBox.Abort, QtWidgets.QMessageBox.Save) if success == QtWidgets.QMessageBox.Save: # save file self.save_file(data_table, popt, uncertainty, ppoly) # go to next spectrum self.next_file() elif success == QtWidgets.QMessageBox.Retry: pass elif success == QtWidgets.QMessageBox.Abort: self.pass_file() def fit_try(self): # get fitting parameters self.get_par() if not self.fit_stat.stat: if self.fit_par.peak: # get fit function f = self.fit_par.get_function() # re-load data with boxcar win and rescale xdata, ydata = self.load_data() popt, uncertainty, noise, ppoly, self.fit_stat.stat = sflib.fit_spectrum(f, xdata, ydata, self.fit_par.par, self.fit_par.deg, self.fit_par.smooth_edge) else: # if no peak, fit baseline xdata, ydata = self.load_data() popt, uncertainty, noise, ppoly, self.fit_stat.stat = sflib.fit_baseline(xdata, ydata, self.fit_par.deg) # if fit successful, plot fit if not self.fit_stat.stat and self.fit_par.peak: # Make plot for successful fit fit = f.get_func()(xdata, *popt) baseline = np.polyval(ppoly, xdata - np.median(xdata)) residual = ydata - fit - baseline self.statusbar.showMessage('Noise {:.4f}'.format(noise)) self.plot_spect(xdata, ydata, fit, baseline) # concatenate data table data_table = np.column_stack((xdata, ydata, fit, baseline)) return data_table, popt, uncertainty, ppoly elif not self.fit_stat.stat: baseline = np.polyval(ppoly, xdata - np.median(xdata)) residual = ydata - baseline fit = np.zeros_like(ydata) self.statusbar.showMessage('Noise {:.4f}'.format(noise)) self.plot_spect(xdata, ydata, fit, baseline) data_table = np.column_stack((xdata, ydata, fit, baseline)) return data_table, popt, uncertainty, ppoly else: return None, None, None, None def load_data(self): # load data # check if there is a file name try: filename = '/'.join([self.current_dir, self.current_file]) except AttributeError: select_file = QtWidgets.QMessageBox.warning(self, 'No File!', 'No spectrum file has been selected. Do you want to select now?', QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.Yes) if select_file == QtWidgets.QMessageBox.Yes: self.open_file() else: self.fit_stat.stat = 2 # exception: file not found return None, None # try load data xdata, ydata, self.fit_stat.stat = sflib.read_file(filename, self.fit_par.boxwin, self.fit_par.rescale) # if file is readable, plot raw data and return xy data if not self.fit_stat.stat: self.plot_data(xdata, ydata) return xdata, ydata else: return None, None def plot_data(self, xdata, ydata): # plot raw data file before fit self.fig.clear() ax = self.fig.add_subplot(111) ax.hold(False) ax.plot(xdata, ydata, 'k-') ax.set_xlabel('Frequency (MHz)') ax.set_ylabel('Intensity (a.u.)') self.canvas.draw() def plot_spect(self, xdata, ydata, fit, baseline): # plot fitted spectra self.fig.clear() ax = self.fig.add_subplot(111) ax.plot(xdata, ydata, 'k-', xdata, fit+baseline, 'r-', xdata, baseline, 'b--') ax.set_xlabel('Frequency (MHz)') ax.set_ylabel('Intensity (a.u.)') self.canvas.draw() # --------- file handling --------- def open_file(self): # get all file names QFileHandle = QtWidgets.QFileDialog() QFileHandle.setDirectory(self.current_dir) filelist = QFileHandle.getOpenFileNames(self, 'Open Spectra')[0] # if list is not empty, proceed if filelist: # sort file name filelist.sort() # seperate directory name and file name self.list_dir, self.list_file = sflib.separate_dir(filelist) # get the first directory and file name self.current_dir = self.list_dir[0] self.current_file = self.list_file[0] self.fit_stat.file_idx = 0 # update label self.label_current_file.setText(self.current_file) # launch fit routine self.load_data() else: self.fit_stat.stat = 2 def pass_file(self): try: self.list_aborted_file.append('/'.join([self.current_dir, self.current_file])) except AttributeError: pass self.next_file() def save_file(self, data_table, popt, uncertainty, ppoly): default_fitname = sflib.out_name_gen(self.current_file) + '.csv' default_logname = sflib.out_name_gen(self.current_file) + '.log' fitname = QtWidgets.QFileDialog.getSaveFileName(self, 'Save Current Fit Spectrum', '/'.join([self.current_dir, default_fitname]))[0] if fitname: sflib.save_fit(fitname, data_table, popt, self.fit_par.ftype, self.fit_par.der, self.fit_par.peak) logname = QtWidgets.QFileDialog.getSaveFileName(self, 'Save Current Fit Log', '/'.join([self.current_dir, default_logname]))[0] if logname: sflib.save_log(logname, popt, uncertainty, ppoly, self.fit_par.ftype, self.fit_par.der, self.fit_par.peak, self.fit_par.par_name) self.list_success_file.append('/'.join([self.current_dir, self.current_file])) def next_file(self): # refresh current file index, fit status and click counter self.fit_stat.file_idx += 1 self.fit_stat.stat = 0 self.click_counter = 0 try: self.current_file = self.list_file[self.fit_stat.file_idx] self.current_dir = self.list_dir[self.fit_stat.file_idx] # update label text self.label_current_file.setText(self.current_file) # repeat fit routine self.load_data() except (IndexError, AttributeError): eof = QtWidgets.QMessageBox.information(self, 'End of File', 'No more files to fit. Do you want to select new files?', QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.Close, QtWidgets.QMessageBox.Yes) if eof == QtWidgets.QMessageBox.Yes: self.open_file() else: self.close() def get_file_dir(self): try: f = open('.prev_dir.log', 'r') last_dir = f.readline() f.close() return last_dir except FileNotFoundError: return self.log_dir def save_log(self): log = QtWidgets.QFileDialog() log.setNameFilter('Log files (*.log)') logname = log.getSaveFileName(self, 'Save Fit Log', '/'.join([self.current_dir, 'FitJob.log']))[0] # if name is not empty if logname: pass else: logname = '/'.join([self.log_dir, 'FitJob.log']) with open(logname, 'w') as a_log: for file_name in self.list_success_file: a_log.write('Successful --- {0:s}\n'.format(file_name)) for file_name in self.list_aborted_file: a_log.write('Aborted --- {0:s}\n'.format(file_name)) def save_last_dir(self): with open('.prev_dir.log', 'w') as a_file: a_file.write(self.current_dir) # --------- some useful little tools ----------- def show_boxcar(self, state): if state == QtCore.Qt.Checked: self.edit_boxcar.show() else: # make sure no boxcar (in case) self.edit_boxcar.setText('1') self.edit_boxcar.hide() def show_rescale(self, state): if state == QtCore.Qt.Checked: self.edit_rescale.show() else: # no rescale self.edit_rescale.setText('1') self.edit_rescale.hide() def check_double_validity(self, *args): sender = self.sender() validator = QtGui.QDoubleValidator() state = validator.validate(sender.text(), 0)[0] if state == QtGui.QValidator.Acceptable and sender.text(): color = '#00A352' # green self.fit_stat.input_valid = 2 # valid entry elif not sender.text(): color = '#FF9933' # yellow self.fit_stat.input_valid = 1 # empty entry else: color = '#D63333' # red self.fit_stat.input_valid = 0 # invalid entry sender.setStyleSheet('border: 3px solid %s' % color) def check_int_validity(self, *args): sender = self.sender() validator = QtGui.QIntValidator() state = validator.validate(sender.text(), 0)[0] if state == QtGui.QValidator.Acceptable and sender.text(): color = '#00A352' # green self.fit_stat.input_valid = 2 # valid entry elif not sender.text(): color = '#FF9933' # yellow self.fit_stat.input_valid = 1 # empty entry else: color = '#D63333' # red self.fit_stat.input_valid = 0 # invalid entry sender.setStyleSheet('border: 3px solid %s' % color) def clear_item(self, layout): # clears all elements in the layout if layout is not None: while layout.count(): item = layout.takeAt(0) w = item.widget() if w is not None: w.deleteLater() else: self.clear_item(item.layout()) def mpl_key_press(self, event): # matplotlib standard key press event key_press_handler(event, self.canvas, self.mpl_toolbar) def mpl_click(self, event): # if can still pick peak position if (self.click_counter < self.fit_par.peak) and (self.click_counter >= 0): # update counter self.click_counter += 1 # retrieve cooridate upon mouse click mu = event.xdata # peak center a = event.ydata*0.1 # peak intensity # locate parameter index in the parameter list mu_idx = self.fit_par.par_per_peak * (self.click_counter-1) a_idx = mu_idx + self.fit_par.par_per_peak - 1 self.edit_par[mu_idx].setText(str(mu)) self.edit_par[a_idx].setText(str(a)) elif self.click_counter >= self.fit_par.peak: # click number overloads. As user to reset reset = QtWidgets.QMessageBox.question(self, 'Reset?', 'Do you want to reset clicks to override peak selection?', QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No) if reset == QtWidgets.QMessageBox.Yes: self.click_counter = 0 elif reset == QtWidgets.QMessageBox.No: self.click_counter = -1 # no longer bother in this session else: event.ignore() def closeEvent(self, event): # exit warning quit_confirm = QtWidgets.QMessageBox.question(self, 'Quit?', 'Are you sure to quit?', QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.Yes) if quit_confirm == QtWidgets.QMessageBox.Yes: #try: # save fit job log file self.save_log() self.save_last_dir() #except: # pass event.accept() else: event.ignore() def keyPressEvent(self, event): # press ESC to exit if event.key() == QtCore.Qt.Key_Escape: self.close()
class plot_window(): def __init__(self): self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas, self) def plot(self, conc, data, samplename, blankstdev, sampleMW): self.figure.clear() ax = self.figure.add_subplot(111) ax.clear() logconc = [np.log10(x) for x in conc] # log(concentration) if samplename == '': samplename = "sample" data = [abs(d) for d in data] #absolute value of data ax.scatter(logconc, data, marker='s', label=samplename, c="k") ax.set(ylabel=r'$\Delta$ I / I$_0$', xlabel="log [concentration (g/mL) ]") ax.set_ylim(auto=True) ax.set_xlim(auto=True) ax.legend(loc='upper left') if len(data) > 1: # Trendline plot equation = self._trendline(logconc, data) # get data stats slope, intercept, r_value, Rsquare = self.get_stats(logconc, data) # get LOD LOD_for_mM, LOD_for_gmL = self.get_LOD(blankstdev, slope, intercept, sampleMW) # table in fig self.table(equation, samplename, intercept, slope, r_value, Rsquare, LOD_for_mM, LOD_for_gmL, sampleMW) self.canvas.draw() return logconc def _trendline(self, conc, data): z = np.polyfit(conc, data, 1) p = np.poly1d(z) y_hat = p(conc) plt.plot(conc, y_hat, "r", linewidth=.8) equation = "y = %.4fx + ( %.4f )" % (z[0], z[1]) return equation def get_stats(self, conc, data): slope, intercept, r_value, p_value, std_err = stats.linregress( conc, data) return slope, intercept, r_value, r_value**2 def get_LOD(self, blankstdev, slope, intercept, sampleMW): index = ((3 * blankstdev) - intercept) / slope LOD_for_M = (10**index) / sampleMW LOD_for_gmL = 10**index return LOD_for_M, LOD_for_gmL def table(self, equation, plot_sample, intercept, slope, Pearsons_r, r_square_value, LOD_for_M, LOD_for_gmL, sampleMW): # col_labels = [''] row_labels = [ 'Equation', 'Plot', 'Intercept', 'Slope', "Pearson's r", "R-square", "sample M.W.", "LOD(M)", "LOD(g/mL)" ] table_vals = [ [equation], [plot_sample], ["%.4f" % intercept], ["%.4f" % slope], ["%.4f" % Pearsons_r], ["%.4f" % r_square_value], ["%.2f Kda" % sampleMW], ["%.3E (M)" % LOD_for_M], ["%.3E (g/mL)" % LOD_for_gmL], ] fig_table = plt.table(cellText=table_vals, colWidths=[0.2] * 1, rowLabels=row_labels, colLabels=None, loc='lower right') fig_table.set_fontsize(15.0)