def display(w, b, raw, parent=None): reg = re.compile(r'-?[0-9\.]+') i = 0 list_dt = [] Mbefore = 0 Mafter = 0 dG = [] dt = 0 while i < len(raw): # find the STDP tag stdp_tag = str(raw[i][3]) if "before" in stdp_tag: # register resistances before and after Mbefore = raw[i][0] Mafter = raw[i + 1][0] # append delta Ts and delta Gs dt = float(re.findall(reg, stdp_tag)[0]) list_dt.append(dt) dG.append((1 / Mafter - 1 / Mbefore) / (1 / Mbefore)) i += 2 else: i += 1 resultWindow = QtWidgets.QWidget() resultWindow.setGeometry(100, 100, 500, 500) resultWindow.setWindowTitle("STDP: W=" + str(w) + " | B=" + str(b)) resultWindow.setWindowIcon(Graphics.getIcon('appicon')) resultWindow.show() view = pg.GraphicsLayoutWidget() label_style = {'color': '#000000', 'font-size': '10pt'} plot_stdp = view.addPlot() curve_stdp = plot_stdp.plot(pen=None, symbolPen=None, \ symbolBrush=(0,0,255), symbol='s', symbolSize=5, pxMode=True) plot_stdp.getAxis('left').setLabel('dG/G0', **label_style) plot_stdp.getAxis('bottom').setLabel('deltaT', units='s', **label_style) plot_stdp.getAxis('left').setGrid(50) plot_stdp.getAxis('bottom').setGrid(50) curve_stdp.setData(np.asarray(list_dt), np.asarray(dG)) layout = QtWidgets.QHBoxLayout() layout.addWidget(view) layout.setContentsMargins(0, 0, 0, 0) resultWindow.setLayout(layout) return resultWindow
def display(w, b, data, parent=None): timePoints = [] m = [] for point in data: tag = str(point[3]) tagCut = tag[4:] try: timePoint = float(tagCut) timePoints.append(timePoint) m.append(point[0]) except ValueError: pass # subtract the first point from all timepoints firstPoint = timePoints[0] for i in range(len(timePoints)): timePoints[i] = timePoints[i] - firstPoint view = pg.GraphicsLayoutWidget() label_style = {'color': '#000000', 'font-size': '10pt'} retentionPlot = view.addPlot() retentionCurve = retentionPlot.plot(symbolPen=None, symbolBrush=(0, 0, 255), symbol='s', symbolSize=5, pxMode=True) retentionPlot.getAxis('left').setLabel('Resistance', units='Ohms', **label_style) retentionPlot.getAxis('bottom').setLabel('Time', units='s', **label_style) retentionPlot.getAxis('left').setGrid(50) retentionPlot.getAxis('bottom').setGrid(50) resLayout = QtWidgets.QHBoxLayout() resLayout.addWidget(view) resLayout.setContentsMargins(0, 0, 0, 0) resultWindow = QtWidgets.QWidget() resultWindow.setGeometry(100, 100, 1000 * APP.scalingFactor, 400) resultWindow.setWindowTitle("Retention: W=" + str(w) + " | B=" + str(b)) resultWindow.setWindowIcon(Graphics.getIcon('appicon')) resultWindow.show() resultWindow.setLayout(resLayout) retentionPlot.setYRange(min(m) / 1.5, max(m) * 1.5) retentionCurve.setData(np.asarray(timePoints), np.asarray(m)) resultWindow.update() return resultWindow
def display(w, b, raw, parent=None): # Initialisations pulseNr = 0 deltaR = [] initR = [] ampl = [] Rs = [] # Holds under and overshoot voltages over = [] under = [] offshoots = [] # holds both in order # holds maximum normalised resistance offset during a train of reads max_dR = 0 # Find the pulse amplitudes and the resistance (averaged over the read # sequence) after each pulse train index = 0 while index < len(raw): # if this is the first read pulse of a read sequence: if index < len(raw) and raw[index][2] == 0: # record the start index start_index = index # initialise average resistance during a read run accumulator readAvgRun = 0 # counts nr of reads idx = 0 # If the line contains 0 amplitude and 0 width, then we're # entering a read run while index < len(raw) and raw[index][2] == 0: # increment the counter idx += 1 # add to accumulator readAvgRun += raw[index][0] # increment the global index as we're advancing through the # pulse run index += 1 # if the index exceeded the lenght of the run, exit if index > len(raw) - 1: break # When we exit the while loop we are at the end of the reading # run readAvgRun = readAvgRun / idx # append with this resistance Rs.append(readAvgRun) # find the maximum deviation from the average read during a # read sequence (helps future plotting of the confidence bar) for i in range(idx): # maybe not the best way to do this but still if abs(raw[start_index + i][0] - readAvgRun) / readAvgRun > max_dR: max_dR = abs(raw[start_index + i][0] - readAvgRun) / readAvgRun # if both amplitude and pw are non-zero, we are in a pulsing run # if this is the first pulse of a write sequence: if index < len(raw) and raw[index][1] != 0 and raw[index][2] != 0: while index < len( raw) and raw[index][1] != 0 and raw[index][2] != 0: # increment the index index += 1 # if the index exceeded the length of the run, exit if index == len(raw) - 1: break # record the pulse voltage at the end ampl.append(raw[index - 1][1]) # Record initial resistances and delta R. for i in range(len(ampl)): initR.append(Rs[i]) deltaR.append((Rs[i + 1] - Rs[i]) / Rs[i]) confX = [0, 0] confY = [-max_dR, max_dR] # setup display resultWindow = QtWidgets.QWidget() resultWindow.setGeometry(100, 100, 1000 * APP.scalingFactor, 500) resultWindow.setWindowTitle("SwitchSeeker: W=" + str(w) + " | B=" + str(b)) resultWindow.setWindowIcon(Graphics.getIcon('appicon')) resultWindow.show() view = pg.GraphicsLayoutWidget() labelStyle = {'color': '#000000', 'font-size': '10pt'} japanPlot = view.addPlot() japanCurve = japanPlot.plot(pen=None, symbolPen=None, symbolBrush=(0, 0, 255), symbol='s', symbolSize=5, pxMode=True) japanPlot.getAxis('left').setLabel('dM/M0', **labelStyle) japanPlot.getAxis('bottom').setLabel('Voltage', units='V', **labelStyle) japanPlot.getAxis('left').setGrid(50) japanPlot.getAxis('bottom').setGrid(50) resLayout = QtWidgets.QHBoxLayout() resLayout.addWidget(view) resLayout.setContentsMargins(0, 0, 0, 0) resultWindow.setLayout(resLayout) japanCurve.setData(np.asarray(ampl), np.asarray(deltaR)) resultWindow.update() return resultWindow
def initUI(self): vbox1 = QtWidgets.QVBoxLayout() self.view = pg.GraphicsLayoutWidget() label_style = {'color': '#000000', 'font-size': '10pt'} self.plot_IV = self.view.addPlot() self.plot_IV.getAxis('left').setLabel('Current', units='A', **label_style) self.plot_IV.getAxis('bottom').setLabel('Voltage', units='V', **label_style) self.plot_IV.getAxis('left').setGrid(50) self.plot_IV.getAxis('bottom').setGrid(50) vbox1.addWidget(self.view) titleLabel = QtWidgets.QLabel('CurveTracer') titleLabel.setFont(fonts.font1) descriptionLabel = QtWidgets.QLabel( 'Standard IV measurement module with current cut-off.') descriptionLabel.setFont(fonts.font3) descriptionLabel.setWordWrap(True) isInt = QtGui.QIntValidator() isFloat = QtGui.QDoubleValidator() leftLabels=['Positive voltage max (V)', \ 'Negative voltage max (V)', \ 'Voltage step (V)', \ 'Start Voltage (V)', \ 'Step width (ms)'] self.leftEdits = [] rightLabels=['Cycles', \ 'Interpulse (ms)',\ 'Positive current cut-off (uA)',\ 'Negative current cut-off (uA)'] self.rightEdits = [] leftInit= ['1', \ '1', \ '0.05', \ '0.05', \ '2'] rightInit= ['1', \ '10',\ '0',\ '0'] # min, max, step, value spinbox_params=[[0.1,12,0.1,1],\ [0.1,12,0.1,1],\ [0.05,1,0.05,0.05], [0.05,1,0.05,0.05], [2,100,0.5,2]] spinbox_cutoff_params = [0, 1000, 10, 0] # Setup the two combo boxes IVtypes = ['Staircase', 'Pulsed'] IVoptions = [ 'Start towards V+', 'Start towards V-', 'Only V+', 'Only V-' ] self.combo_IVtype = QtWidgets.QComboBox() self.combo_IVoption = QtWidgets.QComboBox() self.combo_IVtype.insertItems(1, IVtypes) self.combo_IVoption.insertItems(1, IVoptions) # Setup the two combo boxes gridLayout = QtWidgets.QGridLayout() gridLayout.setColumnStretch(0, 3) gridLayout.setColumnStretch(1, 1) gridLayout.setColumnStretch(2, 1) gridLayout.setColumnStretch(3, 1) gridLayout.setColumnStretch(4, 3) if self.short == False: gridLayout.setColumnStretch(5, 1) gridLayout.setColumnStretch(6, 1) gridLayout.setColumnStretch(7, 2) lineLeft = QtWidgets.QFrame() lineLeft.setFrameShape(QtWidgets.QFrame.VLine) lineLeft.setFrameShadow(QtWidgets.QFrame.Raised) lineLeft.setLineWidth(1) lineRight = QtWidgets.QFrame() lineRight.setFrameShape(QtWidgets.QFrame.VLine) lineRight.setFrameShadow(QtWidgets.QFrame.Raised) lineRight.setLineWidth(1) gridLayout.addWidget(lineLeft, 0, 2, 7, 1) gridLayout.addWidget(lineRight, 0, 6, 7, 1) for i in range(len(leftLabels)): lineLabel = QtWidgets.QLabel() #lineLabel.setFixedHeight(50) lineLabel.setText(leftLabels[i]) gridLayout.addWidget(lineLabel, i, 0) spinEdit = QtWidgets.QDoubleSpinBox() spinEdit.setMinimum(spinbox_params[i][0]) spinEdit.setMaximum(spinbox_params[i][1]) spinEdit.setSingleStep(spinbox_params[i][2]) spinEdit.setValue(spinbox_params[i][3]) gridLayout.addWidget(spinEdit, i, 1) self.leftEdits.append(spinEdit) gridLayout.addWidget(QtWidgets.QLabel("Buffer size:"), 6, 0) edit_buffSize = QtWidgets.QDoubleSpinBox() edit_buffSize.setMinimum(10) edit_buffSize.setMaximum(100) edit_buffSize.setSingleStep(10) edit_buffSize.setValue(50) edit_buffSize.setDecimals(0) edit_buffSize.valueChanged.connect(self.update_bufSize) gridLayout.addWidget(edit_buffSize, 6, 1) for i in range(len(rightLabels)): lineLabel = QtWidgets.QLabel() lineLabel.setText(rightLabels[i]) #lineLabel.setFixedHeight(50) gridLayout.addWidget(lineLabel, i, 4) if i < 2: lineEdit = QtWidgets.QLineEdit() lineEdit.setText(rightInit[i]) lineEdit.setValidator(isFloat) self.rightEdits.append(lineEdit) gridLayout.addWidget(lineEdit, i, 5) else: spinEdit = QtWidgets.QDoubleSpinBox() spinEdit.setMinimum(spinbox_cutoff_params[0]) spinEdit.setMaximum(spinbox_cutoff_params[1]) spinEdit.setSingleStep(spinbox_cutoff_params[2]) spinEdit.setValue(spinbox_cutoff_params[3]) spinEdit.setDecimals(0) gridLayout.addWidget(spinEdit, i, 5) self.rightEdits.append(spinEdit) self.leftEdits[0].valueChanged.connect(self.update_v_pmax) self.leftEdits[1].valueChanged.connect(self.update_v_nmax) self.leftEdits[2].valueChanged.connect(self.update_v_step) self.leftEdits[3].valueChanged.connect(self.update_v_start) self.leftEdits[4].valueChanged.connect(self.update_pw) self.rightEdits[0].textChanged.connect(self.update_cycles) self.rightEdits[1].textChanged.connect(self.update_interpulse) self.rightEdits[2].valueChanged.connect(self.update_c_p) self.rightEdits[3].valueChanged.connect(self.update_c_n) returnCheckBox = QtWidgets.QCheckBox("Halt and return.") returnCheckBox.stateChanged.connect(self.toggleReturn) self.returnCheck = 0 gridLayout.addWidget(returnCheckBox, 4, 5) lineLabel = QtWidgets.QLabel() lineLabel.setText('Bias type:') gridLayout.addWidget(lineLabel, 5, 4) lineLabel = QtWidgets.QLabel() lineLabel.setText('IV span:') gridLayout.addWidget(lineLabel, 6, 4) gridLayout.addWidget(self.combo_IVtype, 5, 5) gridLayout.addWidget(self.combo_IVoption, 6, 5) vbox1.addWidget(titleLabel) vbox1.addWidget(descriptionLabel) self.vW = QtWidgets.QWidget() self.vW.setLayout(gridLayout) self.vW.setContentsMargins(0, 0, 0, 0) self.scrlArea = QtWidgets.QScrollArea() self.scrlArea.setWidget(self.vW) self.scrlArea.setContentsMargins(0, 0, 0, 0) self.scrlArea.setWidgetResizable(False) self.scrlArea.setHorizontalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff) self.scrlArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn) self.scrlArea.installEventFilter(self) self.scrlArea.setMaximumHeight(200) vbox1.addWidget(self.scrlArea) if self.short == False: self.hboxProg = QtWidgets.QHBoxLayout() push_single = QtWidgets.QPushButton('Apply to One') push_range = QtWidgets.QPushButton('Apply to Range') push_all = QtWidgets.QPushButton('Apply to All') push_single.setStyleSheet(styles.btnStyle) push_range.setStyleSheet(styles.btnStyle) push_all.setStyleSheet(styles.btnStyle) push_single.clicked.connect(self.programOne) push_range.clicked.connect(self.programRange) push_all.clicked.connect(self.programAll) self.hboxProg.addWidget(push_single) self.hboxProg.addWidget(push_range) self.hboxProg.addWidget(push_all) vbox1.addLayout(self.hboxProg) push_live = QtWidgets.QPushButton("LIVE") push_live.setStyleSheet("background-color: red") push_live.clicked.connect(self.goLive) gridLayout.addWidget(push_live, len(self.leftEdits), 0) self.setLayout(vbox1) self.vW.setFixedWidth(self.size().width()) self.gridLayout = gridLayout btn_widget = QtWidgets.QWidget() hbox = QtWidgets.QHBoxLayout(self) self.push_live = QtWidgets.QPushButton("GO LIVE!") self.push_live.clicked.connect(self.live) self.push_live.setStyleSheet(styles.btnStyle) self.push_one = QtWidgets.QPushButton("Apply to One") self.push_one.clicked.connect(self.start_programOne) self.push_one.setStyleSheet(styles.btnStyle) self.push_save = QtWidgets.QPushButton("Save Data") self.push_save.clicked.connect(self.saveQueue) self.push_save.setStyleSheet(styles.btnStyle2) hbox.addWidget(self.push_save) hbox.addWidget(self.push_live) hbox.addWidget(self.push_one) btn_widget.setLayout(hbox) vbox1.addWidget(btn_widget) self.setWindowTitle("CurveTracer: LIVE!") self.setWindowIcon(Graphics.getIcon('appicon'))
def __init__(self, w, b, raw_data, parent=None): Ui_FitDialogParent.__init__(self) QtWidgets.QDialog.__init__(self, parent=parent) self.setupUi(self) self.setWindowTitle("Parameter fit for W=%d | B=%d" % (w, b)) self.setWindowIcon(Graphics.getIcon('appicon')) self.numPulsesEdit.setValidator(QtGui.QIntValidator()) self.fitButton.clicked.connect(self.fitClicked) self.exportModelDataButton.clicked.connect(self.exportClicked) self.exportVerilogButton.clicked.connect(self.exportVerilogClicked) self.fitMechanismModelButton.clicked.connect(self.fitMechanismClicked) self.mechanismModelCombo.currentIndexChanged.connect(self.mechanismModelComboIndexChanged) self.resistances[:] = [] self.voltages[:] = [] self.pulses[:] = [] self.modelData[:] = [] self.modelParams = {} self.IVs = [] unique_pos_voltages = set() unique_neg_voltages = set() in_ff = True currentIV = { "R0": -1.0, "data": [[],[]] } for line in raw_data: if str(line[3]).split("_")[1] == 'FF': in_ff = True self.resistances.append(line[0]) self.voltages.append(line[1]) if line[1] >= 0: unique_pos_voltages.add(line[1]) else: unique_neg_voltages.add(line[1]) self.pulses.append(line[2]) else: if in_ff: if len(currentIV["data"][0]) > 0 and len(currentIV["data"][1]) > 0: self.IVs.append(currentIV) currentIV = { "R0": self.resistances[-1], "data": [[],[]] } in_ff = False voltage = float(line[5]) current = float(line[5])/float(line[0]) currentIV["data"][0].append(voltage) currentIV["data"][1].append(current) self.resistancePlot = self.responsePlotWidget.plot(self.resistances, clear=True, pen=pyqtgraph.mkPen({'color': 'F00', 'width': 1})) self.fitPlot = None self.responsePlotWidget.setLabel('left', 'Resistance', units=u"Ω") self.responsePlotWidget.setLabel('bottom', 'Pulse') self.mechanismPlotWidget.setLabel('left', 'Current', units="A") self.mechanismPlotWidget.setLabel('bottom', 'Voltage', units="V") self.curveSelectionSpinBox.setMinimum(1) self.curveSelectionSpinBox.setMaximum(len(self.IVs)) self.curveSelectionSpinBox.valueChanged.connect(self.IVSpinBoxValueChanged) self.IVSpinBoxValueChanged(1) for v in sorted(unique_pos_voltages): self.refPosCombo.addItem(str(v), v) for v in sorted(unique_neg_voltages, reverse=True): self.refNegCombo.addItem(str(v), v) self.modelWidgets = {} self.modelWidgets["sinh"] = ModelWidget(["a","b"], lambda p, x: p[0]*np.sinh(p[1]*x), "y = a*sinh(b*x)") self.modelWidgets["linear"] = ModelWidget(["a"], lambda p, x: p[0]*x, "y=a*x") for (k, v) in self.modelWidgets.items(): self.modelStackedWidget.addWidget(v) self.mechanismModelCombo.addItem(k, v) if len(self.IVs) < 1: mechanismTab = self.tabWidget.findChild(QtGui.QWidget, \ "mechanismTab") idx = self.tabWidget.indexOf(mechanismTab) if idx > 0: self.tabWidget.setTabEnabled(idx, False)
def display(w, b, data, parent=None): dialog = QtWidgets.QDialog(parent) dialog.setWindowFlag(QtCore.Qt.WindowContextHelpButtonHint, False) containerLayout = QtWidgets.QHBoxLayout() dialog.setLayout(containerLayout) tabs = QtWidgets.QTabWidget(dialog) containerLayout.addWidget(tabs) saveButton = QtWidgets.QPushButton("Export data") resStates = [] tab1 = QtWidgets.QWidget() topLayout = QtWidgets.QVBoxLayout() bottomLayout = QtWidgets.QHBoxLayout() bottomLayout.addItem( QtWidgets.QSpacerItem(40, 10, QtWidgets.QSizePolicy.Expanding)) bottomLayout.addWidget(saveButton) topLayout.addWidget( QtWidgets.QLabel("Calculated resistive states for device %d x %d" % (w, b))) resultTable = QtWidgets.QTableWidget() resultTable.setColumnCount(3) resultTable.setHorizontalHeaderLabels( ["Resistance", "Lower bound", "Upper bound"]) resultTable.verticalHeader().setVisible(False) resultTable.horizontalHeader().setResizeMode( QtWidgets.QHeaderView.Stretch) resultTable.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) resultTable.setSelectionMode(QtWidgets.QTableWidget.NoSelection) topLayout.addWidget(resultTable) topLayout.addItem(bottomLayout) dialog.setGeometry(100, 100, 600, 400) dialog.setWindowTitle("Multistate report for W=%d | B=%d" % (w, b)) dialog.setWindowIcon(Graphics.getIcon('appicon')) tab1.setLayout(topLayout) tabs.addTab(tab1, "Data") for line in data: tag = line[3] if str(tag).startswith("MSS3_STATE"): elements = tag.split("_") resStates.append([ float(elements[2]), float(elements[3]), float(elements[4]) ]) position = resultTable.rowCount() resultTable.insertRow(position) resultTable.setItem(position, 0, QtWidgets.QTableWidgetItem(elements[2])) resultTable.setItem(position, 1, QtWidgets.QTableWidgetItem(elements[3])) resultTable.setItem(position, 2, QtWidgets.QTableWidgetItem(elements[4])) resultTable.resizeColumnsToContents() resultTable.resizeRowsToContents() saveCb = partial(functions.writeDelimitedData, resStates) saveButton.clicked.connect( partial(functions.saveFuncToFilename, saveCb, "Save data to...", parent)) plot = pyqtgraph.PlotWidget() plot.getAxis('bottom').setLabel("State #") plot.getAxis('left').setLabel("Resistance", units=u"Ω") tab2 = QtWidgets.QWidget() plotLayout = QtWidgets.QVBoxLayout() plotLayout.addWidget(plot) tab2.setLayout(plotLayout) tabs.addTab(tab2, "Plot") indices = numpy.arange(1, len(resStates) + 1) mainCurve = plot.plot(indices, [x[0] for x in resStates], pen=pyqtgraph.mkPen({ 'color': '000', 'width': 2 }), symbolBrush=pyqtgraph.mkBrush('000'), symbol='o', symbolSize=6, pxMode=True) lowBoundCurve = plot.plot(indices, [x[1] for x in resStates], pen=pyqtgraph.mkPen({ 'color': '00F', 'width': 1 }), symbolPen=pyqtgraph.mkPen({ 'color': '00F', 'width': 1 }), symbolBrush=pyqtgraph.mkBrush('00F'), symbol='+', symbolSize=6, pxMode=True) upperBoundCurve = plot.plot(indices, [x[2] for x in resStates], pen=pyqtgraph.mkPen({ 'color': 'F00', 'width': 1 }), symbolPen=pyqtgraph.mkPen({ 'color': 'F00', 'width': 1 }), symbolBrush=pyqtgraph.mkBrush('F00'), symbol='+', symbolSize=6, pxMode=True) filler = pyqtgraph.FillBetweenItem(lowBoundCurve, upperBoundCurve, brush=pyqtgraph.mkBrush('BBB')) plot.addItem(filler) return dialog
def display(w, b, raw, parent=None): resistance = [] voltage = [] current = [] abs_current = [] # Find nr of cycles lineNr = 1 totalCycles = 0 resistance.append([]) voltage.append([]) current.append([]) abs_current.append([]) resistance[totalCycles].append(raw[0][0]) voltage[totalCycles].append(raw[0][1]) current[totalCycles].append(raw[0][1] / raw[lineNr][0]) abs_current[totalCycles].append(abs(current[totalCycles][-1])) # take all data lines without the first and last one (which are _s and # _e) while lineNr < len(raw) - 1: currentRunTag = raw[lineNr][3] while (currentRunTag == raw[lineNr][3]): resistance[totalCycles].append(raw[lineNr][0]) voltage[totalCycles].append(raw[lineNr][1]) current[totalCycles].append(raw[lineNr][1] / raw[lineNr][0]) abs_current[totalCycles].append(abs(current[totalCycles][-1])) lineNr += 1 if lineNr == len(raw): break totalCycles += 1 resistance.append([]) voltage.append([]) current.append([]) abs_current.append([]) resistance[totalCycles - 1].append(raw[-1][0]) voltage[totalCycles - 1].append(raw[-1][1]) current[totalCycles - 1].append(raw[-1][1] / raw[-1][0]) abs_current[totalCycles - 1].append(abs(current[totalCycles - 1][-1])) # setup display resultWindow = QtWidgets.QWidget() resultWindow.setGeometry(100, 100, 1000 * APP.scalingFactor, 400) resultWindow.setWindowTitle("Curve Tracer: W=" + str(w) + " | B=" + str(b)) resultWindow.setWindowIcon(Graphics.getIcon('appicon')) resultWindow.show() view = pg.GraphicsLayoutWidget() label_style = {'color': '#000000', 'font-size': '10pt'} plot_abs = view.addPlot() plot_abs.getAxis('left').setLabel('Current', units='A', **label_style) plot_abs.getAxis('bottom').setLabel('Voltage', units='V', **label_style) plot_abs.setLogMode(False, True) plot_abs.getAxis('left').setGrid(50) plot_abs.getAxis('bottom').setGrid(50) # go to next row and add the next plot view.nextColumn() plot_IV = view.addPlot() plot_IV.addLegend() plot_IV.getAxis('left').setLabel('Current', units='A', **label_style) plot_IV.getAxis('bottom').setLabel('Voltage', units='V', **label_style) plot_IV.getAxis('left').setGrid(50) plot_IV.getAxis('bottom').setGrid(50) # go to next row and add the next plot view.nextColumn() plot_R = view.addPlot() plot_R.getAxis('left').setLabel('Resistance', units='Ohms', **label_style) plot_R.getAxis('bottom').setLabel('Voltage', units='V', **label_style) plot_R.setLogMode(False, True) plot_R.getAxis('left').setGrid(50) plot_R.getAxis('bottom').setGrid(50) resLayout = QtWidgets.QVBoxLayout() resLayout.addWidget(view) resLayout.setContentsMargins(0, 0, 0, 0) resultWindow.setLayout(resLayout) # setup range for resistance plot maxRes_arr = [] minRes_arr = [] for cycle in range(1, totalCycles + 1): maxRes_arr.append(max(resistance[cycle - 1])) minRes_arr.append(min(resistance[cycle - 1])) maxRes = max(maxRes_arr) minRes = max(minRes_arr) for cycle in range(1, totalCycles + 1): aux1 = plot_abs.plot(pen=(cycle, totalCycles), symbolPen=None, symbolBrush=(cycle, totalCycles), symbol='s', symbolSize=5, pxMode=True, name='Cycle ' + str(cycle)) aux1.setData(np.asarray(voltage[cycle - 1]), np.asarray(abs_current[cycle - 1])) aux2 = plot_IV.plot(pen=(cycle, totalCycles), symbolPen=None, symbolBrush=(cycle, totalCycles), symbol='s', symbolSize=5, pxMode=True, name='Cycle ' + str(cycle)) aux2.setData(np.asarray(voltage[cycle - 1]), np.asarray(current[cycle - 1])) aux3 = plot_R.plot(pen=(cycle, totalCycles), symbolPen=None, symbolBrush=(cycle, totalCycles), symbol='s', symbolSize=5, pxMode=True, name='Cycle ' + str(cycle)) aux3.setData(np.asarray(voltage[cycle - 1]), np.asarray(resistance[cycle - 1])) plot_R.setYRange(np.log10(_min_without_inf(resistance, np.inf)), np.log10(_max_without_inf(resistance, np.inf))) plot_abs.setYRange(np.log10(_min_without_inf(abs_current, 0.0)), np.log10(_max_without_inf(abs_current, 0.0))) resultWindow.update() return resultWindow