def initUI(self): layout = qt.QHBoxLayout() self.setFixedWidth(self.screenGeometry.width()) self.canvas = pyqtplt.FigureCanvas(fig.Figure()) axes = self.canvas.figure.subplots(2, 2, gridspec_kw={ "hspace": 0, "wspace": 0 }) layout.addWidget(self.canvas) (ax1, ax2), (ax3, ax4) = axes self.axes = [ax1, ax2, ax3, ax4] layout.addWidget(self.canvas) self.initAxes() self.setLayout(layout) self.timer = self.canvas.new_timer(150) self.timer.add_callback(self.animation) self.timer.start() self.initAxes() self.getLines()
def __init__(self, figure=None, *args, **kwargs): """ Initialize figure/canvas and connect the view. :param TwissFigure figure: the contained figure :param args: positional arguments for :class:`QWidget` :param kwargs: keyword arguments for :class:`QWidget` """ super().__init__(*args, **kwargs) self.figure = figure or Figure(tight_layout=True) self.canvas = canvas = mpl_backend.FigureCanvas(figure) self.toolbar = toolbar = Toolbar(canvas, self) self.setLayout(VBoxLayout([canvas, toolbar], tight=True)) # Needed on PyQt5 with tight_layout=True to prevent crash due to # singular matrix if size=0: canvas.setMinimumSize(QSize(100, 100)) # Prevent annoying busy cursor due to MPL redraws, see: # https://github.com/matplotlib/matplotlib/issues/9546 canvas.set_cursor = lambda cursor: None # Monkey-patch MPL's mouse-capture update logic into a Qt signal: self._updateCapture.connect(toolbar._update_buttons_checked) toolbar._update_buttons_checked = self._updateCapture.emit self._actions = []
def buildUI(self, doRebuild=False): if doRebuild: self.myHBoxLayout_statplot.removeWidget(self.static_canvas) self.defaultPlotLayout(buildingInterface=True) # sets matplotlib to dark theme #self.setStyleSheet(qdarkstyle.load_stylesheet(qt_api='pyqt5')) self.myHBoxLayout_statplot = QtWidgets.QHBoxLayout(self) # if I remove self here, plot does not show up self.plotToolbarWidget = myStatPlotToolbarWidget(self) self.myHBoxLayout_statplot.addWidget(self.plotToolbarWidget, stretch=2) # stretch=10, not sure on the units??? # works #static_canvas = backend_qt5agg.FigureCanvas(mpl.figure.Figure(figsize=(5, 3))) tmpFig = mpl.figure.Figure() #tmpFig.tight_layout(pad=0) self.static_canvas = backend_qt5agg.FigureCanvas(tmpFig) self._static_ax = self.static_canvas.figure.subplots() #self._static_ax.plot(xPlot, yPlot, ".") # pick_event assumes 'picker=5' in any .plot() self.cid = self.static_canvas.mpl_connect('pick_event', self.on_pick_event) ''' fig = mpl.figure.Figure() self._static_ax = fig.add_subplot(111) self.static_canvas = backend_qt5agg.FigureCanvas(fig) self._static_ax = self.static_canvas.figure.subplots() ''' self.lastSpikeNumber = None self.lastFileName = '' self.plotMeta_selection = None # selection of many spikes matching detection widget x-aixs # holds data of current x/y plot values (used to quickly select a range with xxx self.my_xPlot = None self.my_yPlot = None self.metaLine = None self.singleSpikeSelection = None self.replot() # x='peakSec' # works ''' self.myCanvas = MyDynamicMplCanvas(self.centralwidget) self.myHBoxLayout_statplot.addWidget(self.myCanvas, stretch=9) ''' # i want the mpl toolbar in the mpl canvas or sublot # this is adding mpl toolbar to main window -->> not what I want #self.addToolBar(backend_qt5agg.NavigationToolbar2QT(self.static_canvas, self)) # this kinda works as wanted, toolbar is inside mpl plot but it is F*****G UGLY !!!! # works but turning off toolbar for now #self.mplToolbar = backend_qt5agg.NavigationToolbar2QT(self.static_canvas, self.static_canvas) # params are (canvas, parent) #self.mplToolbar = backend_qt5agg.NavigationToolbar2QT(self.myCanvas, self.myCanvas) # params are (canvas, parent) self.myHBoxLayout_statplot.addWidget(self.static_canvas, stretch=6) # stretch=10, not sure on the units???
def initializeFigure(self): self.figure = Figure() self.axis, self.timelineAxis = self.figure.subplots(2,1, gridspec_kw={'height_ratios': [8, 1]}) self.figure.set_tight_layout(True) self.figureCanvas = pltQt5.FigureCanvas(self.figure) self.layout.addWidget(self.figureCanvas) self.plotToolBar = pltQt5.NavigationToolbar2QT(self.figureCanvas, self) self.figure.canvas.mpl_connect('button_press_event', self.onClick)
def buildUI(self): self.centralwidget = QtWidgets.QWidget(self) self.centralwidget.setObjectName("centralwidget") self.myQVBoxLayout = QtWidgets.QVBoxLayout(self.centralwidget) # # toolbar self.toolbarWidget = myToolbarWidget() self.addToolBar(QtCore.Qt.LeftToolBarArea, self.toolbarWidget) # # tree view of files self.myTableWidget = QtWidgets.QTreeWidget() # append to layout self.myQVBoxLayout.addWidget(self.myTableWidget) # # dv/dt plot self.myGraphicsView = myQGraphicsView( plotThis='dvdt') #myQGraphicsView(self.centralwidget) self.myQVBoxLayout.addWidget(self.myGraphicsView) # # vm plot self.myGraphicsView = myQGraphicsView( plotThis='vm') #myQGraphicsView(self.centralwidget) self.myQVBoxLayout.addWidget(self.myGraphicsView) # # stat plot static_canvas = backend_qt5agg.FigureCanvas( mpl.figure.Figure(figsize=(5, 3))) self.myQVBoxLayout.addWidget(static_canvas) # i want the mpl toolbar in the mpl canvas or sublot # this is adding mpl toolbar to main window -->> not what I want #self.addToolBar(backend_qt5agg.NavigationToolbar2QT(static_canvas, self)) # this kinda works as wanted, toolbar is inside mpl plot but it is F*****G UGLY !!!! self.mplToolbar = backend_qt5agg.NavigationToolbar2QT( static_canvas, static_canvas) self._static_ax = static_canvas.figure.subplots() t = np.linspace(0, 10, 501) self._static_ax.plot(t, np.tan(t), ".") # # leave here, critical self.setCentralWidget(self.centralwidget)
def __init__(self, parent=None): super().__init__(parent) # Matplotlib figure instance passed to FigureCanvas of matplotlib # Qt5Agg backend. This returns the matplotlib canvas Qt widget. self.canvas_qt = mpl_backend_qt.FigureCanvas( matplotlib.figure.Figure()) # Basic plot setup self.subplot1 = self.canvas_qt.figure.add_subplot(111) # Further QtWidget setup vertical_layout = QVBoxLayout() vertical_layout.addWidget(self.canvas_qt) self.setLayout(vertical_layout) # Setup callbacks self.canvas_qt.mpl_connect("motion_notify_event", self.onMouseMove) self.canvas_qt.mpl_connect("pick_event", self.itemPicked) self.cursors = [ Cursor(self.canvas_qt, self.subplot1, name="Hor. Cursor 1", is_vertical=False, linestyle="--"), Cursor(self.canvas_qt, self.subplot1, name="Hor. Cursor 2", is_vertical=False, linestyle="-."), Cursor(self.canvas_qt, self.subplot1, name="Vert. Cursor 1", is_vertical=True, linestyle="--"), Cursor(self.canvas_qt, self.subplot1, name="Vert. Cursor 2", is_vertical=True, linestyle="-."), ] self.canvas_qt.draw_idle()
def mplWindow2(self, numRow=1, numCol=1): plt.style.use('dark_background') # this is dangerous, collides with self.mplWindow() self.fig = mpl.figure.Figure() # not working #self.fig.canvas.mpl_connect('key_press_event', self.keyPressEvent) self.static_canvas = backend_qt5agg.FigureCanvas(self.fig) self.static_canvas.setFocusPolicy( QtCore.Qt.ClickFocus ) # this is really triccky and annoying self.static_canvas.setFocus() self.fig.canvas.mpl_connect('key_press_event', self.keyPressEvent) self.axs = [None] * numRow # empty list if numRow==1 and numCol==1: self._static_ax = self.static_canvas.figure.subplots() self.axs = self._static_ax else: for idx in range(numRow): plotNum = idx + 1 #print('mplWindow2()', idx) self.axs[idx] = self.static_canvas.figure.add_subplot(numRow,1,plotNum) self._mySetWindowTitle() # does not work #self.static_canvas.mpl_connect('key_press_event', self.keyPressEvent) # pick_event assumes 'picker=5' in any .plot() self.cid = self.static_canvas.mpl_connect('pick_event', self.spike_pick_event) # toolbar need to be added to layout #from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar self.mplToolbar = mpl.backends.backend_qt5agg.NavigationToolbar2QT(self.static_canvas, self.static_canvas) layout = QtWidgets.QVBoxLayout() layout.addWidget(self.static_canvas) layout.addWidget(self.mplToolbar) self.setLayout(layout)
def __init__(self): super().__init__() self.initUI() self.setMouseTracking(True) self.x = -1 self.y = -1 self.pos = None self.startPos = None self.isDrawing = False self.figure = Figure() self.canvas = backend_qt5agg.FigureCanvas(self.figure) self.axes = self.figure.add_axes([0, 0, 1, 1]) #remove white border self.axes.axis('off') #turn off axis labels # markerColor = 'red' markerSize = 5 self.oneRoi = self.axes.scatter([], [], marker='o', color=markerColor, s=markerSize)
def buildUI(self): minVal = 0 if self.bitDepth is None: print('FIX THIS ERROR IN BITDEPTH WTF self.bitDepth:', self.bitDepth) self.bitDepth = 16 #8 maxVal = 2**self.bitDepth #self.myQVBoxLayout = QtWidgets.QVBoxLayout(self) self.myGridLayout = QtWidgets.QGridLayout(self) # # upper/min #self.upperHBoxLayout = QtWidgets.QHBoxLayout() # don't use self spinBoxWidth = 64 self.minLabel = QtWidgets.QLabel("Min") self.minSpinBox = QtWidgets.QSpinBox() self.minSpinBox.setMaximumWidth(spinBoxWidth) self.minSpinBox.setMinimum( -1e6) # si user can specify whatever they want self.minSpinBox.setMaximum(1e6) self.minSpinBox.setValue(minVal) self.minSpinBox.valueChanged.connect(self.spinBoxValueChanged) # self.minContrastSlider = QtWidgets.QSlider(QtCore.Qt.Horizontal) self.minContrastSlider.setMinimum(minVal) self.minContrastSlider.setMaximum(maxVal) self.minContrastSlider.setValue(minVal) self.minContrastSlider.valueChanged.connect(self.sliderValueChanged) # inverse checkbox # color table # don't remove this code, need to implement min/max color ''' # min color self.minColorButton = myColorButton() # use *self so we can .getColor() self.minColorButton.setColor('black') ''' # # bit depth # don't include 32, it causes an over-run self._myBitDepths = [1, 2, 8, 9, 10, 11, 12, 13, 14, 15, 16] bitDepthIdx = self._myBitDepths.index( self.bitDepth) # will sometimes fail bitDepthLabel = QtWidgets.QLabel('Bit Depth') bitDepthComboBox = QtWidgets.QComboBox() #bitDepthComboBox.setMaximumWidth(spinBoxWidth) for depth in self._myBitDepths: bitDepthComboBox.addItem(str(depth)) bitDepthComboBox.setCurrentIndex(bitDepthIdx) bitDepthComboBox.currentIndexChanged.connect(self.bitDepth_Callback) histCheckbox = QtWidgets.QCheckBox('Histogram') histCheckbox.setChecked(True) histCheckbox.clicked.connect(self.checkbox_callback) row = 0 col = 0 self.myGridLayout.addWidget(self.minLabel, row, col) col += 1 self.myGridLayout.addWidget(self.minSpinBox, row, col) col += 1 self.myGridLayout.addWidget(self.minContrastSlider, row, col) col += 1 # don't remove this code, need to implement min/max color ''' self.myGridLayout.addWidget(self.minColorButton, row, col) col += 1 ''' self.myGridLayout.addWidget(bitDepthLabel, row, col) col += 1 self.myGridLayout.addWidget(bitDepthComboBox, row, col) col += 1 self.myGridLayout.addWidget(histCheckbox, row, col) # # lower/max #self.lowerHBoxLayout = QtWidgets.QHBoxLayout() # don't use self self.maxLabel = QtWidgets.QLabel("Max") self.maxSpinBox = QtWidgets.QSpinBox() self.maxSpinBox.setMaximumWidth(spinBoxWidth) self.maxSpinBox.setMinimum( -1e6) # si user can specify whatever they want self.maxSpinBox.setMaximum(1e6) self.maxSpinBox.setValue(maxVal) self.maxSpinBox.valueChanged.connect(self.spinBoxValueChanged) # self.maxContrastSlider = QtWidgets.QSlider(QtCore.Qt.Horizontal) self.maxContrastSlider.setMinimum(minVal) self.maxContrastSlider.setMaximum(maxVal) self.maxContrastSlider.setValue(maxVal) self.maxContrastSlider.valueChanged.connect(self.sliderValueChanged) # inverse checkbox # color table # don't remove this code, need to implement min/max color ''' # max color self.maxColorButton = myColorButton() # use *self so we can .getColor() self.maxColorButton.setColor('white') ''' # popup for color LUT for image self.myColor = 'gray' # todo: add some more colors #self._myColors = ['gray', 'red', 'green', 'blue', 'gray_r', 'red_r', 'green_r', 'blue_r', # 'gist_earth', 'gist_earth_r', 'gist_gray', 'gist_gray_r', 'gist_heat', 'gist_heat_r'] self._myColors = ['gray', 'red', 'green', 'blue', 'gray_r'] colorIdx = self._myColors.index(self.myColor) # will sometimes fail colorLabel = QtWidgets.QLabel('LUT') colorComboBox = QtWidgets.QComboBox() #colorComboBox.setMaximumWidth(spinBoxWidth) for color in self._myColors: colorComboBox.addItem(color) colorComboBox.setCurrentIndex(colorIdx) colorComboBox.currentIndexChanged.connect(self.color_Callback) #colorComboBox.setEnabled(False) # todo: not implemented, turn hist on/off self.logCheckbox = QtWidgets.QCheckBox('Log') self.logCheckbox.setChecked(self.plotLogHist) self.logCheckbox.clicked.connect(self.checkbox_callback) row += 1 col = 0 self.myGridLayout.addWidget(self.maxLabel, row, col) col += 1 self.myGridLayout.addWidget(self.maxSpinBox, row, col) col += 1 self.myGridLayout.addWidget(self.maxContrastSlider, row, col) col += 1 # don't remove this code, need to implement min/max color ''' self.myGridLayout.addWidget(self.maxColorButton, row, col) col += 1 ''' self.myGridLayout.addWidget(colorLabel, row, col) col += 1 self.myGridLayout.addWidget(colorComboBox, row, col) col += 1 self.myGridLayout.addWidget(self.logCheckbox, row, col) col += 1 ''' self.lowerHBoxLayout.addWidget(self.maxLabel) self.lowerHBoxLayout.addWidget(self.maxSpinBox) self.lowerHBoxLayout.addWidget(self.maxContrastSlider) self.lowerHBoxLayout.addWidget(self.maxColorButton) self.lowerHBoxLayout.addWidget(colorLabel) self.lowerHBoxLayout.addWidget(colorComboBox) self.myQVBoxLayout.addLayout(self.lowerHBoxLayout) # triggering non trace warning ''' # # histograph self.figure = Figure( ) # need size otherwise square image gets squished in y? self.canvasHist = backend_qt5agg.FigureCanvas(self.figure) #self.axes = self.figure.add_subplot(111) self.numChannels = 3 self.axes = [None] * self.numChannels for i in range(self.numChannels): self.axes[i] = self.figure.add_axes([0, 0, 1, 1]) #remove white border self.axes[i].patch.set_facecolor("black") self.figure.set_facecolor("black") #histHBoxLayout = QtWidgets.QHBoxLayout() # # second row row += 1 #col = 0 #self.myGridLayout.addWidget(self.logCheckbox, row, col) col = 0 specialCol = 2 self.myGridLayout.addWidget(self.canvasHist, row, specialCol) col += 1 ''' histHBoxLayout.addWidget(self.logCheckbox) histHBoxLayout.addWidget(self.canvasHist) ''' # #self.myQVBoxLayout.addLayout(histHBoxLayout) self.setSlice(0)
def _buildInterface(self): #self.pyqtWindow() # main layout vLayout = QtWidgets.QVBoxLayout() self.controlLayout = QtWidgets.QHBoxLayout() # #aLabel = QtWidgets.QLabel('fft') #self.controlLayout.addWidget(aLabel) ''' buttonName = 'Detect' aButton = QtWidgets.QPushButton(buttonName) aButton.clicked.connect(partial(self.on_button_click,buttonName)) self.controlLayout.addWidget(aButton) ''' ''' aLabel = QtWidgets.QLabel('mV Threshold') self.controlLayout.addWidget(aLabel) self.mvThresholdSpinBox = QtWidgets.QDoubleSpinBox() self.mvThresholdSpinBox.setRange(-1e9, 1e9) self.controlLayout.addWidget(self.mvThresholdSpinBox) ''' ''' checkboxName = 'PSD' aCheckBox = QtWidgets.QCheckBox(checkboxName) aCheckBox.setChecked(True) aCheckBox.stateChanged.connect(partial(self.on_checkbox_clicked, checkboxName)) self.controlLayout.addWidget(aCheckBox) ''' ''' checkboxName = 'Auto-Correlation' aCheckBox = QtWidgets.QCheckBox(checkboxName) aCheckBox.setChecked(True) aCheckBox.stateChanged.connect(partial(self.on_checkbox_clicked, checkboxName)) self.controlLayout.addWidget(aCheckBox) ''' buttonName = 'Replot' aButton = QtWidgets.QPushButton(buttonName) aButton.clicked.connect(partial(self.on_button_click,buttonName)) self.controlLayout.addWidget(aButton) self.resultsLabel = QtWidgets.QLabel('Results: Peak Hz=??? Ampplitude=???') self.controlLayout.addWidget(self.resultsLabel) checkboxName = 'Butter Filter' butterCheckBox = QtWidgets.QCheckBox(checkboxName) butterCheckBox.setChecked(self.doButterFilter) butterCheckBox.stateChanged.connect(partial(self.on_checkbox_clicked, checkboxName)) self.controlLayout.addWidget(butterCheckBox) aLabel = QtWidgets.QLabel('Order') self.controlLayout.addWidget(aLabel) self.butterOrderSpinBox = QtWidgets.QSpinBox() self.butterOrderSpinBox.setRange(0, 1e9) self.butterOrderSpinBox.setValue(self.butterOrder) self.butterOrderSpinBox.editingFinished.connect(partial(self.on_cutoff_spinbox, aLabel)) self.controlLayout.addWidget(self.butterOrderSpinBox) aLabel = QtWidgets.QLabel('Low (Hz)') self.controlLayout.addWidget(aLabel) self.lowCutoffSpinBox = QtWidgets.QDoubleSpinBox() self.lowCutoffSpinBox.setRange(0, 1e9) self.lowCutoffSpinBox.setValue(self.butterCutoff[0]) self.lowCutoffSpinBox.editingFinished.connect(partial(self.on_cutoff_spinbox, aLabel)) self.controlLayout.addWidget(self.lowCutoffSpinBox) aLabel = QtWidgets.QLabel('High') self.controlLayout.addWidget(aLabel) self.highCutoffSpinBox = QtWidgets.QDoubleSpinBox() self.highCutoffSpinBox.setRange(0, 1e9) self.highCutoffSpinBox.setValue(self.butterCutoff[1]) self.highCutoffSpinBox.editingFinished.connect(partial(self.on_cutoff_spinbox, aLabel)) self.controlLayout.addWidget(self.highCutoffSpinBox) psdWindowComboBox = QtWidgets.QComboBox() psdWindowComboBox.addItem('Hanning') psdWindowComboBox.addItem('Blackman') psdWindowComboBox.currentTextChanged.connect(self.on_psd_window_changed) self.controlLayout.addWidget(psdWindowComboBox) # vLayout.addLayout(self.controlLayout) # add mpl canvas self.controlLayout1_5 = QtWidgets.QHBoxLayout() self.fsLabel = QtWidgets.QLabel(f'fs={self.fs}') self.controlLayout1_5.addWidget(self.fsLabel) aLabel = QtWidgets.QLabel('NFFT') self.controlLayout1_5.addWidget(aLabel) self.nfftSpinBox = QtWidgets.QSpinBox() self.nfftSpinBox.setRange(0, 1e9) self.nfftSpinBox.setValue(self.nfft) self.nfftSpinBox.editingFinished.connect(partial(self.on_cutoff_spinbox, aLabel)) self.controlLayout1_5.addWidget(self.nfftSpinBox) #self.freqResLabel = QtWidgets.QLabel(f'Freq Resolution (Hz) {round(self.fs/self.nfft,3)}') self.freqResLabel = QtWidgets.QLabel(f'Freq Resolution (Hz) Unknown') self.controlLayout1_5.addWidget(self.freqResLabel) aLabel = QtWidgets.QLabel('Median Filter (Pnts)') self.controlLayout1_5.addWidget(aLabel) self.medianFilterPntsSpinBox = QtWidgets.QSpinBox() self.medianFilterPntsSpinBox.setRange(0, 1e9) self.medianFilterPntsSpinBox.setValue(self.medianFilterPnts) self.medianFilterPntsSpinBox.editingFinished.connect(partial(self.on_cutoff_spinbox, aLabel)) self.controlLayout1_5.addWidget(self.medianFilterPntsSpinBox) aLabel = QtWidgets.QLabel('Max Plot (Hz)') self.controlLayout1_5.addWidget(aLabel) self.maxPlotHzSpinBox = QtWidgets.QDoubleSpinBox() self.maxPlotHzSpinBox.setRange(0, 1e9) self.maxPlotHzSpinBox.setValue(self.maxPlotHz) self.maxPlotHzSpinBox.editingFinished.connect(partial(self.on_cutoff_spinbox, aLabel)) self.controlLayout1_5.addWidget(self.maxPlotHzSpinBox) ''' aLabel = QtWidgets.QLabel('Order') self.controlLayout1_5.addWidget(aLabel) self.orderSpinBox = QtWidgets.QDoubleSpinBox() self.orderSpinBox.setRange(-1e9, 1e9) self.orderSpinBox.setValue(self.order) self.orderSpinBox.editingFinished.connect(partial(self.on_cutoff_spinbox, aLabel)) self.controlLayout1_5.addWidget(self.orderSpinBox) ''' buttonName = 'Filter Response' aButton = QtWidgets.QPushButton(buttonName) aButton.clicked.connect(partial(self.on_button_click,buttonName)) self.controlLayout1_5.addWidget(aButton) ''' buttonName = 'Rebuild Auto-Corr' aButton = QtWidgets.QPushButton(buttonName) aButton.clicked.connect(partial(self.on_button_click,buttonName)) self.controlLayout1_5.addWidget(aButton) ''' # vLayout.addLayout(self.controlLayout1_5) # add mpl canvas # # second row of controls (for model) self.controlLayout_row2 = QtWidgets.QHBoxLayout() checkboxName = 'Model Data' self.modelDataCheckBox = QtWidgets.QCheckBox(checkboxName) self.modelDataCheckBox.setChecked(False) self.modelDataCheckBox.stateChanged.connect(partial(self.on_checkbox_clicked, checkboxName)) self.controlLayout_row2.addWidget(self.modelDataCheckBox) ''' buttonName = 'Detect' aButton = QtWidgets.QPushButton(buttonName) aButton.clicked.connect(partial(self.on_button_click,buttonName)) self.controlLayout_row2.addWidget(aButton) ''' ''' aLabel = QtWidgets.QLabel('mvThreshold') self.controlLayout_row2.addWidget(aLabel) self.mvThresholdSpinBox = QtWidgets.QDoubleSpinBox() self.mvThresholdSpinBox.setValue(-52) self.mvThresholdSpinBox.setRange(-1000, 1000) self.controlLayout_row2.addWidget(self.mvThresholdSpinBox) ''' # numSeconds, spikeFreq, amp, noise aLabel = QtWidgets.QLabel('Seconds') self.controlLayout_row2.addWidget(aLabel) self.modelSecondsSpinBox = QtWidgets.QDoubleSpinBox() self.modelSecondsSpinBox.setValue(20) self.modelSecondsSpinBox.setRange(0, 1000) self.controlLayout_row2.addWidget(self.modelSecondsSpinBox) # finalize row 2 vLayout.addLayout(self.controlLayout_row2) # add mpl canvas # 3rd row # second row of controls (for model) #self.controlLayout_row3 = QtWidgets.QHBoxLayout() aLabel = QtWidgets.QLabel('Spike Frequency') self.controlLayout_row2.addWidget(aLabel) self.modelFrequencySpinBox = QtWidgets.QDoubleSpinBox() self.modelFrequencySpinBox.setValue(1) self.modelFrequencySpinBox.setRange(0, 100) self.controlLayout_row2.addWidget(self.modelFrequencySpinBox) aLabel = QtWidgets.QLabel('Amplitude') self.controlLayout_row2.addWidget(aLabel) self.modelAmpSpinBox = QtWidgets.QDoubleSpinBox() self.modelAmpSpinBox.setValue(100) self.modelAmpSpinBox.setRange(-100, 100) self.controlLayout_row2.addWidget(self.modelAmpSpinBox) aLabel = QtWidgets.QLabel('Noise Amp') self.controlLayout_row2.addWidget(aLabel) self.modelNoiseAmpSpinBox = QtWidgets.QDoubleSpinBox() self.modelNoiseAmpSpinBox.setValue(50) self.modelNoiseAmpSpinBox.setRange(0, 1000) self.controlLayout_row2.addWidget(self.modelNoiseAmpSpinBox) # finalize row 3 #vLayout.addLayout(self.controlLayout_row3) # add mpl canvas vSplitter = QtWidgets.QSplitter(QtCore.Qt.Vertical) vLayout.addWidget(vSplitter) # don't use inherited, want 3x3 with rows: 1, 1, 3 subplits ''' self.mplWindow2(numRow=3) # makes self.axs[] and self.static_canvas #self.vmAxes = self.axs[0] self.rawAxes = self.axs[0] self.rawZoomAxes = self.axs[1] self.fftAxes = self.axs[2] #self.autoCorrAxes = self.axs[3] # uses spike detection ''' # mirror self.mplWindow2() from matplotlib.backends import backend_qt5agg self.fig = mpl.figure.Figure(constrained_layout=True) self.static_canvas = backend_qt5agg.FigureCanvas(self.fig) # this is really tricky and annoying self.static_canvas.setFocusPolicy( QtCore.Qt.ClickFocus ) self.static_canvas.setFocus() #self.fig.canvas.mpl_connect('key_press_event', self.keyPressEvent) self.mplToolbar = mpl.backends.backend_qt5agg.NavigationToolbar2QT(self.static_canvas, self.static_canvas) if self.plotRawAxis: numRow = 3 else: numRow = 2 gs = self.fig.add_gridspec(numRow, 3) #self.rawAxes = self.fig.addsubplot(gs[0,:]) if self.plotRawAxis: self.rawAxes = self.static_canvas.figure.add_subplot(gs[0,:]) self.rawZoomAxes = self.static_canvas.figure.add_subplot(gs[1,:]) # 3rd row has 3 subplots self.psdAxes = self.static_canvas.figure.add_subplot(gs[2,0]) self.spectrogramAxes = self.static_canvas.figure.add_subplot(gs[2,-2]) else: self.rawAxes = None self.rawZoomAxes = self.static_canvas.figure.add_subplot(gs[0,:]) # 3rd row has 3 subplots self.psdAxes = self.static_canvas.figure.add_subplot(gs[1,0]) self.spectrogramAxes = self.static_canvas.figure.add_subplot(gs[1,-2]) vSplitter.addWidget(self.static_canvas) # add mpl canvas vSplitter.addWidget(self.mplToolbar) # add mpl canvas # this works #self.mplToolbar.hide() # set the layout of the main window self.setLayout(vLayout)
def buildUI(self): # main layout vLayout = QtWidgets.QVBoxLayout() controlLayout = QtWidgets.QHBoxLayout() ''' aName = 'Make Stimulus' aButton = QtWidgets.QPushButton(aName) aButton.clicked.connect(partial(self.on_button_click,aName)) controlLayout.addWidget(aButton) ''' aName = 'Save As...' self.saveAsButton = QtWidgets.QPushButton(aName) self.saveAsButton.clicked.connect(partial(self.on_button_click, aName)) controlLayout.addWidget(self.saveAsButton) aName = 'Save Index' aLabel = QtWidgets.QLabel(aName) controlLayout.addWidget(aLabel) self.saveIndexSpinBox = QtWidgets.QSpinBox() self.saveIndexSpinBox.setKeyboardTracking(False) self.saveIndexSpinBox.setRange(0, 9999) self.saveIndexSpinBox.setValue(self.saveStimIndex) self.saveIndexSpinBox.valueChanged.connect( partial(self.on_spin_box, aName)) #self.saveIndexSpinBox.valueChanged.connect(partial(self.on_spin_box2, aName, self.saveIndexSpinBox)) controlLayout.addWidget(self.saveIndexSpinBox) aName = 'Stim Type' aLabel = QtWidgets.QLabel(aName) controlLayout.addWidget(aLabel) self.stimTypeDropdown = QtWidgets.QComboBox() for type in self.stimTypes: self.stimTypeDropdown.addItem(type) self.stimTypeDropdown.currentTextChanged.connect(self.on_stim_type) controlLayout.addWidget(self.stimTypeDropdown) aName = 'Sweep Duration(s)' aLabel = QtWidgets.QLabel(aName) controlLayout.addWidget(aLabel) self.sweepDurationSpinBox = QtWidgets.QDoubleSpinBox() self.sweepDurationSpinBox.setKeyboardTracking(False) self.sweepDurationSpinBox.setRange(0, 1e9) self.sweepDurationSpinBox.setValue(self.sweepDurSeconds) self.sweepDurationSpinBox.valueChanged.connect( partial(self.on_spin_box, aName)) controlLayout.addWidget(self.sweepDurationSpinBox) aName = 'Number Of Sweeps' aLabel = QtWidgets.QLabel(aName) controlLayout.addWidget(aLabel) self.numSweepsSpinBox = QtWidgets.QSpinBox() self.numSweepsSpinBox.setKeyboardTracking(False) self.numSweepsSpinBox.setRange(1, 100) self.numSweepsSpinBox.setValue(self.numSweeps) self.numSweepsSpinBox.valueChanged.connect( partial(self.on_spin_box, aName)) controlLayout.addWidget(self.numSweepsSpinBox) vLayout.addLayout(controlLayout) # add mpl canvas # row 1.5 controlLayout_row1_5 = QtWidgets.QHBoxLayout() aName = 'Stim Start(s)' aLabel = QtWidgets.QLabel(aName) controlLayout_row1_5.addWidget(aLabel) self.stimStartSpinBox = QtWidgets.QDoubleSpinBox() self.stimStartSpinBox.setKeyboardTracking(False) self.stimStartSpinBox.setRange(0, 1e9) self.stimStartSpinBox.setValue(self.stimStartSeconds) self.stimStartSpinBox.valueChanged.connect( partial(self.on_spin_box, aName)) controlLayout_row1_5.addWidget(self.stimStartSpinBox) aName = 'Stim Duration(s)' aLabel = QtWidgets.QLabel(aName) controlLayout_row1_5.addWidget(aLabel) self.durationSpinBox = QtWidgets.QDoubleSpinBox() self.durationSpinBox.setKeyboardTracking(False) self.durationSpinBox.setRange(0, 1e9) self.durationSpinBox.setValue(self.durSeconds) self.durationSpinBox.valueChanged.connect( partial(self.on_spin_box, aName)) controlLayout_row1_5.addWidget(self.durationSpinBox) aName = 'Stim Offset(y)' aLabel = QtWidgets.QLabel(aName) controlLayout_row1_5.addWidget(aLabel) self.yStimOffsetSpinBox = QtWidgets.QDoubleSpinBox() self.yStimOffsetSpinBox.setKeyboardTracking(False) self.yStimOffsetSpinBox.setRange(-1e9, 1e9) self.yStimOffsetSpinBox.setValue(self.yStimOffset) self.yStimOffsetSpinBox.valueChanged.connect( partial(self.on_spin_box, aName)) controlLayout_row1_5.addWidget(self.yStimOffsetSpinBox) vLayout.addLayout(controlLayout_row1_5) # add mpl canvas # 2nd row controlLayout_row2 = QtWidgets.QGridLayout() rowSpan = 1 colSpan = 1 row = 0 col = 0 aName = 'Amplitude' aLabel = QtWidgets.QLabel(aName) controlLayout_row2.addWidget(aLabel, row, col, rowSpan, colSpan) self.amplitudeSpinBox = QtWidgets.QDoubleSpinBox() self.amplitudeSpinBox.setKeyboardTracking(False) self.amplitudeSpinBox.setRange(0, 1e9) self.amplitudeSpinBox.setDecimals(5) self.amplitudeSpinBox.setValue(self.amplitude) self.amplitudeSpinBox.valueChanged.connect( partial(self.on_spin_box, aName)) controlLayout_row2.addWidget(self.amplitudeSpinBox, 0, 1, rowSpan, colSpan) # rms of sin (amp and freq) ''' rmsMult = 1/np.sqrt(2) sinRms = self.amplitude * rmsMult sinRms = round(sinRms,2) aName = f'RMS:{sinRms}' self.sinRms = QtWidgets.QLabel(aName) controlLayout_row2.addWidget(self.sinRms, 0, 2, rowSpan, colSpan) ''' aName = 'Frequency (Hz)' aLabel = QtWidgets.QLabel(aName) controlLayout_row2.addWidget(aLabel, 0, 3, rowSpan, colSpan) self.frequencySpinBox = QtWidgets.QDoubleSpinBox() self.frequencySpinBox.setKeyboardTracking(False) self.frequencySpinBox.setRange(0, 1e9) self.frequencySpinBox.setValue(self.frequency) self.frequencySpinBox.valueChanged.connect( partial(self.on_spin_box, aName)) controlLayout_row2.addWidget(self.frequencySpinBox, 0, 4, rowSpan, colSpan) aName = 'Noise Amplitude' aLabel = QtWidgets.QLabel(aName) controlLayout_row2.addWidget(aLabel, 0, 5, rowSpan, colSpan) self.noiseAmpSpinBox = QtWidgets.QDoubleSpinBox() self.noiseAmpSpinBox.setKeyboardTracking(False) self.noiseAmpSpinBox.setDecimals(5) self.noiseAmpSpinBox.setSingleStep(0.01) self.noiseAmpSpinBox.setRange(0, 1e9) self.noiseAmpSpinBox.setValue(self.noiseAmplitude) self.noiseAmpSpinBox.valueChanged.connect( partial(self.on_spin_box, aName)) controlLayout_row2.addWidget(self.noiseAmpSpinBox, 0, 6, rowSpan, colSpan) # # row 2 #controlLayout_row2 = QtWidgets.QHBoxLayout() aName = 'Amplitude Step' aLabel = QtWidgets.QLabel(aName) controlLayout_row2.addWidget(aLabel, 1, 0, rowSpan, colSpan) self.amplitudeStepSpinBox = QtWidgets.QDoubleSpinBox() self.amplitudeStepSpinBox.setKeyboardTracking(False) self.amplitudeStepSpinBox.setDecimals(5) self.amplitudeStepSpinBox.setSingleStep(0.01) self.amplitudeStepSpinBox.setRange(0, 1e9) self.amplitudeStepSpinBox.setValue(self.amplitudeStep) self.amplitudeStepSpinBox.valueChanged.connect( partial(self.on_spin_box, aName)) controlLayout_row2.addWidget(self.amplitudeStepSpinBox, 1, 1, rowSpan, colSpan) aName = 'Frequency Step' aLabel = QtWidgets.QLabel(aName) controlLayout_row2.addWidget(aLabel, 1, 3, rowSpan, colSpan) self.frequencyStepSpinBox = QtWidgets.QDoubleSpinBox() self.frequencyStepSpinBox.setKeyboardTracking(False) self.frequencyStepSpinBox.setSingleStep(0.1) self.frequencyStepSpinBox.setRange(0, 1e9) self.frequencyStepSpinBox.setValue(self.frequencyStep) self.frequencyStepSpinBox.valueChanged.connect( partial(self.on_spin_box, aName)) controlLayout_row2.addWidget(self.frequencyStepSpinBox, 1, 4, rowSpan, colSpan) # first row in grid has freq rms aName = 'Noise Step' aLabel = QtWidgets.QLabel(aName) controlLayout_row2.addWidget(aLabel, 1, 5, rowSpan, colSpan) self.noiseStepSpinBox = QtWidgets.QDoubleSpinBox() self.noiseStepSpinBox.setKeyboardTracking(False) self.noiseStepSpinBox.setDecimals(5) self.noiseStepSpinBox.setSingleStep(0.01) self.noiseStepSpinBox.setRange(0, 1e9) self.noiseStepSpinBox.setValue(self.frequencyStep) self.noiseStepSpinBox.valueChanged.connect( partial(self.on_spin_box, aName)) controlLayout_row2.addWidget(self.noiseStepSpinBox, 1, 6, rowSpan, colSpan) # vLayout.addLayout(controlLayout_row2) # add mpl canvas controlLayout_row3 = QtWidgets.QHBoxLayout() checkboxName = 'Rectify' self.rectifyCheckBox = QtWidgets.QCheckBox(checkboxName) self.rectifyCheckBox.setChecked(self.doRectify) self.rectifyCheckBox.stateChanged.connect( partial(self.on_checkbox_clicked, checkboxName)) controlLayout_row3.addWidget(self.rectifyCheckBox) aName = 'Samples Per Second' aLabel = QtWidgets.QLabel(aName) controlLayout_row3.addWidget(aLabel) self.fsSpinBox = QtWidgets.QSpinBox() self.fsSpinBox.setKeyboardTracking(False) self.fsSpinBox.setRange(1, 100000) # TODO: Fix hard coding of 100000 self.fsSpinBox.setValue(self._fs) self.fsSpinBox.valueChanged.connect(partial(self.on_spin_box, aName)) controlLayout_row3.addWidget(self.fsSpinBox) aName = 'Scale' aLabel = QtWidgets.QLabel(aName) controlLayout_row3.addWidget(aLabel) self.scaleDropdown = QtWidgets.QComboBox() scales = [0.001, 0.01, 0.1, 1, 10, 100, 1000] for scale in scales: scaleStr = str(scale) self.scaleDropdown.addItem(scaleStr) startIndex = 3 self.scaleDropdown.setCurrentIndex(startIndex) self.scaleDropdown.currentTextChanged.connect(self.on_scale) controlLayout_row3.addWidget(self.scaleDropdown) # vLayout.addLayout(controlLayout_row3) # add mpl canvas vSplitter = QtWidgets.QSplitter(QtCore.Qt.Vertical) vLayout.addWidget(vSplitter) plt.style.use('dark_background') self.fig = mpl.figure.Figure(constrained_layout=True) self.static_canvas = backend_qt5agg.FigureCanvas(self.fig) self.static_canvas.setFocusPolicy(QtCore.Qt.ClickFocus) self.static_canvas.setFocus() #can do self.mplToolbar.hide() self.mplToolbar = mpl.backends.backend_qt5agg.NavigationToolbar2QT( self.static_canvas, self.static_canvas) self._updateNumSweeps(self.numSweeps) #self.rawAxes = self.static_canvas.figure.add_subplot(self.numSweeps,1,1) #self.plotLine, = self.rawAxes[0].plot([], [], '-w', linewidth=1) vSplitter.addWidget(self.static_canvas) # add mpl canvas vSplitter.addWidget(self.mplToolbar) # add mpl canvas # # finalize #self.mainWidget = QtWidgets.QWidget() if qdarkstyle is not None: self.setStyleSheet(qdarkstyle.load_stylesheet(qt_api='pyqt5')) else: self.setStyleSheet("") # set the layout of the main window self.setLayout(vLayout)
def __init__(self, mainWindow=None): super(bLineProfileWidget, self).__init__() self.mainWindow = mainWindow # usually bStackWidget self.updateDict = None self.currSlabIdx = None # so we can commit self.currentSlice = None # so we can commit # grab local copies, do not change options self.lineRadius = self.mainWindow.getOptions()['LineProfile']['lineRadius'] #12 # pixels self.lineWidth = self.mainWindow.getOptions()['LineProfile']['lineWidth'] #5 self.medianFilter = self.mainWindow.getOptions()['LineProfile']['medianFilter'] #5 self.halfHeight = self.mainWindow.getOptions()['LineProfile']['halfHeight'] #0.5 self.plusMinusSlidingZ = self.mainWindow.getOptions()['LineProfile']['plusMinusSlidingZ'] #0.5 self.doUpdate = True # set to false to not update on signal/slot self.setMaximumHeight(220) # if adding rows, make this bigger self.myHBoxLayout = QtWidgets.QHBoxLayout(self) # # to hold control panel self.leftGridLayout = QtWidgets.QGridLayout() # abb aics, removed (self) myRow = 0 ''' # nudge up button nudgeUpButton = QtWidgets.QPushButton('Nudge Up') nudgeUpButton.clicked.connect(self.nudgeUp_Callback) self.leftGridLayout.addWidget(nudgeUpButton, myRow, 0) # nudge down button nudgeUpButton = QtWidgets.QPushButton('Nudge Down') nudgeUpButton.clicked.connect(self.nudgeDown_Callback) self.leftGridLayout.addWidget(nudgeUpButton, myRow, 1) myRow += 1 ''' # line radius for intensity profile myLabel = QtWidgets.QLabel('Line Radius (pixels)') lineRadiusSpinBox = QtWidgets.QSpinBox() lineRadiusSpinBox.setMinimum(1) lineRadiusSpinBox.setValue(self.lineRadius) lineRadiusSpinBox.valueChanged.connect(self.lineRadius_Callback) self.leftGridLayout.addWidget(myLabel, myRow, 0) self.leftGridLayout.addWidget(lineRadiusSpinBox, myRow, 1) myRow += 1 # line width for intensity profile myLabel = QtWidgets.QLabel('Line Width (pixels)') lineWidthSpinBox = QtWidgets.QSpinBox() lineWidthSpinBox.setMinimum(1) lineWidthSpinBox.setValue(self.lineWidth) lineWidthSpinBox.valueChanged.connect(self.lineWidth_Callback) self.leftGridLayout.addWidget(myLabel, myRow, 0) self.leftGridLayout.addWidget(lineWidthSpinBox, myRow, 1) myRow += 1 # median filter size (pixels) myLabel = QtWidgets.QLabel('Median Filter (pixels)') medianFilterSpinbox = QtWidgets.QSpinBox() medianFilterSpinbox.setMinimum(0) medianFilterSpinbox.setValue(self.medianFilter) medianFilterSpinbox.valueChanged.connect(self.medianFilter_Callback) self.leftGridLayout.addWidget(myLabel, myRow, 0) self.leftGridLayout.addWidget(medianFilterSpinbox, myRow, 1) myRow += 1 # half height b/w 0.0 and 1.0 myLabel = QtWidgets.QLabel('Half Height') halfHeightSpinbox = QtWidgets.QDoubleSpinBox() halfHeightSpinbox.setMinimum(0.0) halfHeightSpinbox.setMaximum(1.0) halfHeightSpinbox.setSingleStep(0.05) halfHeightSpinbox.setValue(self.halfHeight) halfHeightSpinbox.valueChanged.connect(self.halfHeight_Callback) self.leftGridLayout.addWidget(myLabel, myRow, 0) self.leftGridLayout.addWidget(halfHeightSpinbox, myRow, 1) myRow += 1 # +/- for sliding z myLabel = QtWidgets.QLabel('+/- Sliding Z') slidingZ_Spinbox = QtWidgets.QSpinBox() slidingZ_Spinbox.setMinimum(0) #slidingZ_Spinbox.setMaximum(1.0) slidingZ_Spinbox.setSingleStep(1) slidingZ_Spinbox.setValue(self.plusMinusSlidingZ) slidingZ_Spinbox.valueChanged.connect(self.slidingZ_Callback) self.leftGridLayout.addWidget(myLabel, myRow, 0) self.leftGridLayout.addWidget(slidingZ_Spinbox, myRow, 1) myRow += 1 # # report results self.myMin = QtWidgets.QLabel('Min: None') self.myMax = QtWidgets.QLabel('Max: None') self.mySNR = QtWidgets.QLabel('SNR: None') self.myDiameter = QtWidgets.QLabel('Diam(pixels): None') self.leftGridLayout.addWidget(self.myMin, myRow, 0) self.leftGridLayout.addWidget(self.myMax, myRow, 1) myRow += 1 self.leftGridLayout.addWidget(self.mySNR, myRow, 0) self.leftGridLayout.addWidget(self.myDiameter, myRow, 1) myRow += 1 myCommitButton = QtWidgets.QPushButton('Commit') myCommitButton.setToolTip('Commit z and diameter (for ROIs)') self.myDiameter_um = QtWidgets.QLabel('Diam(um): None') self.leftGridLayout.addWidget(myCommitButton, myRow, 0) self.leftGridLayout.addWidget(self.myDiameter_um, myRow, 1) # add self.myHBoxLayout.addLayout(self.leftGridLayout, stretch=2) # # to hold plot self.figure = Figure(constrained_layout=True) # need size otherwise square image gets squished in y? self.canvas = backend_qt5agg.FigureCanvas(self.figure) #self.axes = self.figure.add_axes([0, 0, 1, 1]) #remove white border self.axes = self.figure.add_subplot(111) self.axes.patch.set_facecolor("black") self.figure.set_facecolor("black") self.myHBoxLayout.addWidget(self.canvas, stretch=8)
def buildUI(self): self.centralwidget = QtWidgets.QWidget(self) self.centralwidget.setObjectName("centralwidget") self.myQVBoxLayout = QtWidgets.QVBoxLayout(self.centralwidget) # # toolbar ''' print('buildUI() building toobar') self.toolbarWidget = myToolbarWidget() self.addToolBar(QtCore.Qt.LeftToolBarArea, self.toolbarWidget) ''' # # tree view of files print('buildUI() building file tree') #self.myTableWidget = QtWidgets.QTreeWidget() self.myTableWidget = QtWidgets.QTableWidget() self.myTableWidget.setRowCount(10) self.myTableWidget.setColumnCount(10) self.myTableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) self.myTableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.myTableWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) self.myTableWidget.cellClicked.connect(self.on_table_click) headerLabels = ['a ' + str(x) for x in range(10)] self.myTableWidget.setHorizontalHeaderLabels(headerLabels) for i in range(10): for j in range(10): item = QtWidgets.QTableWidgetItem('aaaaaaaaaaaaaaaaa ' + str(i*j)) self.myTableWidget.setItem(i,j, item) # append to layout self.myQVBoxLayout.addWidget(self.myTableWidget) # # # detect/plot widget # # self.myDetectionWidget = bDetectionWidget(ba) # add the detection widget to the main vertical layout self.myQVBoxLayout.addWidget(self.myDetectionWidget) # # # stat plot # # #self.myHBoxLayout_statplot = QtWidgets.QHBoxLayout(self.centralwidget) self.myHBoxLayout_statplot = QtWidgets.QHBoxLayout() plotToolbarWidget = myStatPlotToolbarWidget() self.myHBoxLayout_statplot.addWidget(plotToolbarWidget)#, stretch=2) # stretch=10, not sure on the units??? print('buildUI() building matplotlib x/y plot') #static_canvas = backend_qt5agg.FigureCanvas(mpl.figure.Figure(figsize=(5, 3))) static_canvas = backend_qt5agg.FigureCanvas(mpl.figure.Figure()) self._static_ax = static_canvas.figure.subplots() xPlot, yPlot = ba.getStat('peakSec', 'peakVal') self._static_ax.plot(xPlot, yPlot, ".") # i want the mpl toolbar in the mpl canvas or sublot # this is adding mpl toolbar to main window -->> not what I want #self.addToolBar(backend_qt5agg.NavigationToolbar2QT(static_canvas, self)) # this kinda works as wanted, toolbar is inside mpl plot but it is F*****G UGLY !!!! self.mplToolbar = backend_qt5agg.NavigationToolbar2QT(static_canvas, static_canvas) # params are (canvas, parent) self.myHBoxLayout_statplot.addWidget(static_canvas) #, stretch=8) # stretch=10, not sure on the units??? #self.myQVBoxLayout.addWidget(static_canvas) self.myQVBoxLayout.addLayout(self.myHBoxLayout_statplot) # # leave here, critical self.setCentralWidget(self.centralwidget) print('buildUI() done')
def _buildGui(self): vLayout = QtWidgets.QVBoxLayout() # # detect layout controlLayout = QtWidgets.QHBoxLayout() # detect button aName = 'Detect (mV)' self.detectButton = QtWidgets.QPushButton(aName) self.detectButton.setStyleSheet("background-color : Blue") self.detectButton.clicked.connect(partial(self.on_detect_button, aName)) controlLayout.addWidget(self.detectButton) # detection threshold self.thresholdSpinbox = QtWidgets.QDoubleSpinBox() self.thresholdSpinbox.setKeyboardTracking(False) #spinBox.setObjectName(statName) # correspond to stat to set in callback self.thresholdSpinbox.setRange(-1e9, 1e9) self.thresholdSpinbox.setDecimals(3) self.thresholdSpinbox.setValue(-20) #self.thresholdSpinbox.valueChanged.connect(self.setThreshold) controlLayout.addWidget(self.thresholdSpinbox) # vLayout.addLayout(controlLayout) # add mpl canvas # # plot type plotTypeLayout = QtWidgets.QHBoxLayout() b1 = QtWidgets.QRadioButton('Raw') b1.setChecked(True) b1.toggled.connect(self.btnstate) plotTypeLayout.addWidget(b1) b1 = QtWidgets.QRadioButton('ISI Histogram') b1.setChecked(False) b1.toggled.connect(self.btnstate) plotTypeLayout.addWidget(b1) b1 = QtWidgets.QRadioButton("Phase Histogram") b1.setChecked(False) b1.toggled.connect(self.btnstate) plotTypeLayout.addWidget(b1) # vLayout.addLayout(plotTypeLayout) # add mpl canvas # turn raw plot detection and dac on/off rawPlotOptionsLayout = QtWidgets.QHBoxLayout() showDetectionCheckbox = QtWidgets.QCheckBox('Show Detection') showDetectionCheckbox.setCheckState(2) # annoying showDetectionCheckbox.stateChanged.connect(self.on_check_boxState) rawPlotOptionsLayout.addWidget(showDetectionCheckbox) showDacCheckbox = QtWidgets.QCheckBox('Show DAC') showDacCheckbox.setCheckState(2) # annoying showDacCheckbox.stateChanged.connect(self.on_check_boxState) rawPlotOptionsLayout.addWidget(showDacCheckbox) vLayout.addLayout(rawPlotOptionsLayout) # add mpl canvas # # matplotlib vPlotLayout = QtWidgets.QVBoxLayout() #plt.style.use('dark_background') self.fig = mpl.figure.Figure(constrained_layout=True) self.static_canvas = backend_qt5agg.FigureCanvas(self.fig) self.static_canvas.setFocusPolicy(QtCore.Qt.ClickFocus) self.static_canvas.setFocus() #self.static_canvas.get_default_filename = lambda: 'new_default_name.png' #can do self.mplToolbar.hide() self.mplToolbar = mpl.backends.backend_qt5agg.NavigationToolbar2QT( self.static_canvas, self.static_canvas) vPlotLayout.addWidget(self.static_canvas) # add mpl canvas vPlotLayout.addWidget(self.mplToolbar) # add mpl canvas vLayout.addLayout(vPlotLayout) # add mpl canvas # self.setLayout(vLayout)
def __init__(self, **kwargs): """ Args: ba (bAnalysis): Not required """ super().__init__(**kwargs) self.plotChasePlot = False # i vs i-1 self.plotColorTime = False #self.plotColorType = True # Plot userType1, userType2, userType3 #self.plotIsBad= True self.plotHistograms = True # keep track of what we are plotting, use this in replot() self.xStatName = None self.yStatName = None self.xStatHumanName = None self.yStatHumanName = None self.xData = [] self.yData = [] self.xAxisSpikeNumber = [] # We need to keep track of this for 'Chase Plot' #self.selectedSpike = None #self.selectedSpikeList = [] # Always a list, if empy then None #self.pyqtWindow() # makes self.mainWidget and calls show() # main layout hLayout = QtWidgets.QHBoxLayout() hSplitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal) hLayout.addWidget(hSplitter) # coontrols and 2x stat list vLayout = QtWidgets.QVBoxLayout() # # controls controlWidget = QtWidgets.QWidget() hLayout2 = QtWidgets.QHBoxLayout() # self.b2 = QtWidgets.QCheckBox("Chase Plot") self.b2.setChecked(self.plotChasePlot) self.b2.stateChanged.connect(lambda:self.btnstate(self.b2)) hLayout2.addWidget(self.b2) # self.colorTime = QtWidgets.QCheckBox("Color Time") self.colorTime.setChecked(self.plotColorTime) self.colorTime.stateChanged.connect(lambda:self.btnstate(self.colorTime)) hLayout2.addWidget(self.colorTime) # ''' self.colorType = QtWidgets.QCheckBox("Color Type") self.colorType.setChecked(self.plotColorType) self.colorType.stateChanged.connect(lambda:self.btnstate(self.colorType)) hLayout2.addWidget(self.colorType) ''' # ''' self.showBad = QtWidgets.QCheckBox("Show Bad") self.showBad.setChecked(self.plotIsBad) self.showBad.stateChanged.connect(lambda:self.btnstate(self.showBad)) hLayout2.addWidget(self.showBad) ''' # self.histogramCheckbox = QtWidgets.QCheckBox("Histograms") self.histogramCheckbox.setChecked(self.plotHistograms) self.histogramCheckbox.stateChanged.connect(lambda:self.btnstate(self.histogramCheckbox)) hLayout2.addWidget(self.histogramCheckbox) vLayout.addLayout(hLayout2) # second row of controls hLayout2_2 = QtWidgets.QHBoxLayout() aName = 'Spike: None' self.spikeNumberLabel = QtWidgets.QLabel(aName) hLayout2_2.addWidget(self.spikeNumberLabel) vLayout.addLayout(hLayout2_2) # x and y stat lists hLayout3 = QtWidgets.QHBoxLayout() self.xPlotWidget = myStatListWidget(self, headerStr='X Stat') self.xPlotWidget.myTableWidget.selectRow(0) self.yPlotWidget = myStatListWidget(self, headerStr='Y Stat') self.yPlotWidget.myTableWidget.selectRow(7) hLayout3.addWidget(self.xPlotWidget) hLayout3.addWidget(self.yPlotWidget) vLayout.addLayout(hLayout3) controlWidget.setLayout(vLayout) # # create a mpl plot (self._static_ax, self.static_canvas) #self.mplWindow2() plt.style.use('dark_background') # this is dangerous, collides with self.mplWindow() self.fig = mpl.figure.Figure() self.static_canvas = backend_qt5agg.FigureCanvas(self.fig) self.static_canvas.setFocusPolicy( QtCore.Qt.ClickFocus ) # this is really triccky and annoying self.static_canvas.setFocus() # self.axs[idx] = self.static_canvas.figure.add_subplot(numRow,1,plotNum) self._switchScatter() ''' # gridspec for scatter + hist self.gs = self.fig.add_gridspec(2, 2, width_ratios=(7, 2), height_ratios=(2, 7), left=0.1, right=0.9, bottom=0.1, top=0.9, wspace=0.05, hspace=0.05) self.axScatter = self.static_canvas.figure.add_subplot(self.gs[1, 0]) self.axHistX = self.static_canvas.figure.add_subplot(self.gs[0, 0], sharex=self.axScatter) self.axHistY = self.static_canvas.figure.add_subplot(self.gs[1, 1], sharey=self.axScatter) # make initial empty scatter plot #self.lines, = self._static_ax.plot([], [], 'ow', picker=5) self.cmap = mpl.pyplot.cm.coolwarm self.cmap.set_under("white") # only works for dark theme #self.lines = self._static_ax.scatter([], [], c=[], cmap=self.cmap, picker=5) self.lines = self.axScatter.scatter([], [], c=[], cmap=self.cmap, picker=5) # make initial empty spike selection plot #self.spikeSel, = self._static_ax.plot([], [], 'oy') self.spikeSel, = self.axScatter.plot([], [], 'oy') # despine top/right self.axScatter.spines['right'].set_visible(False) self.axScatter.spines['top'].set_visible(False) self.axHistX.spines['right'].set_visible(False) self.axHistX.spines['top'].set_visible(False) self.axHistY.spines['right'].set_visible(False) self.axHistY.spines['top'].set_visible(False) ''' #can do self.mplToolbar.hide() # matplotlib.backends.backend_qt5.NavigationToolbar2QT self.mplToolbar = mpl.backends.backend_qt5agg.NavigationToolbar2QT(self.static_canvas, self.static_canvas) # put toolbar and static_canvas in a V layout plotWidget = QtWidgets.QWidget() vLayoutPlot = QtWidgets.QVBoxLayout() vLayoutPlot.addWidget(self.static_canvas) vLayoutPlot.addWidget(self.mplToolbar) plotWidget.setLayout(vLayoutPlot) # # finalize #hLayout.addLayout(vLayout) hSplitter.addWidget(controlWidget) #hSplitter.addWidget(self.static_canvas) # add mpl canvas hSplitter.addWidget(plotWidget) # set the layout of the main window # playing with dock #self.mainWidget.setLayout(hLayout) self.setLayout(hLayout) #self.mainWidget.setGeometry(100, 100, 1200, 600) self.replot()
def buildUI(self): # main layout vLayout = QtWidgets.QVBoxLayout() controlLayout = QtWidgets.QHBoxLayout() aName = 'Save As...' self.saveAsButton = QtWidgets.QPushButton(aName) self.saveAsButton.clicked.connect(partial(self.on_button_click, aName)) controlLayout.addWidget(self.saveAsButton) ''' statStr = 'saveStimIndex' self.saveIndexSpinBox = mySpinBox( label='Save Index', stat=statStr, value=self.getParam(statStr), callback=self.on_spin_box2) controlLayout.addLayout(self.saveIndexSpinBox) ''' aName = 'Save Index' aLabel = QtWidgets.QLabel(aName) controlLayout.addWidget(aLabel) self.saveIndexSpinBox = QtWidgets.QSpinBox() self.saveIndexSpinBox.setKeyboardTracking(False) self.saveIndexSpinBox.setObjectName(aName) self.saveIndexSpinBox.setRange(0, 9999) self.saveIndexSpinBox.setValue(self.saveStimIndex) self.saveIndexSpinBox.valueChanged.connect( partial(self.on_spin_box, aName)) #self.saveIndexSpinBox.valueChanged.connect(self.on_spin_box2) controlLayout.addWidget(self.saveIndexSpinBox) aName = 'Stim Type' aLabel = QtWidgets.QLabel(aName) controlLayout.addWidget(aLabel) self.stimTypeDropdown = QtWidgets.QComboBox() for type in self.stimTypes: self.stimTypeDropdown.addItem(type) self.stimTypeDropdown.currentTextChanged.connect(self.on_stim_type) controlLayout.addWidget(self.stimTypeDropdown) statStr = 'sweepDur_sec' aSpinBox = mySpinBox(label='Sweep Duration(s)', stat=statStr, value=self.getParam(statStr), callback=self.on_spin_box2) controlLayout.addLayout(aSpinBox) vLayout.addLayout(controlLayout) # add mpl canvas # row 1.25 controlLayout_row1_2 = QtWidgets.QHBoxLayout() statStr = 'preSweeps' aSpinBox = mySpinBox(label='Pre Sweeps', stat=statStr, value=self.getParam(statStr), callback=self.on_spin_box2) controlLayout_row1_2.addLayout(aSpinBox) statStr = 'numSweeps' aSpinBox = mySpinBox(label='Stim Sweeps', stat=statStr, value=self.getParam(statStr), callback=self.on_spin_box2) controlLayout_row1_2.addLayout(aSpinBox) statStr = 'postSweeps' aSpinBox = mySpinBox(label='Post Sweeps', stat=statStr, value=self.getParam(statStr), callback=self.on_spin_box2) controlLayout_row1_2.addLayout(aSpinBox) vLayout.addLayout(controlLayout_row1_2) # add mpl canvas # row 1.5 controlLayout_row1_5 = QtWidgets.QHBoxLayout() statStr = 'stimStart_sec' aSpinBox = mySpinBox(label='Stim Start(s)', stat=statStr, value=self.getParam(statStr), callback=self.on_spin_box2) controlLayout_row1_5.addLayout(aSpinBox) statStr = 'stimDur_sec' aSpinBox = mySpinBox(label='Stim Dur(s)', stat=statStr, value=self.getParam(statStr), callback=self.on_spin_box2) controlLayout_row1_5.addLayout(aSpinBox) statStr = 'yOffset' aSpinBox = mySpinBox(label='Stim Offset(y)', stat=statStr, value=self.getParam(statStr), callback=self.on_spin_box2) controlLayout_row1_5.addLayout(aSpinBox) vLayout.addLayout(controlLayout_row1_5) # add mpl canvas # 2nd row controlLayout_row2 = QtWidgets.QHBoxLayout() ''' controlLayout_row2 = QtWidgets.QGridLayout() rowSpan = 1 colSpan = 1 row = 0 col = 0 ''' statStr = 'stimAmp' aSpinBox = mySpinBox(label='Amplitude', stat=statStr, value=self.getParam(statStr), callback=self.on_spin_box2) controlLayout_row2.addLayout(aSpinBox) # rms of sin (amp and freq) ''' rmsMult = 1/np.sqrt(2) sinRms = self.amplitude * rmsMult sinRms = round(sinRms,2) aName = f'RMS:{sinRms}' self.sinRms = QtWidgets.QLabel(aName) controlLayout_row2.addWidget(self.sinRms, 0, 2, rowSpan, colSpan) ''' statStr = 'stimFreq' aSpinBox = mySpinBox(label='Frequency (Hz)', stat=statStr, value=self.getParam(statStr), callback=self.on_spin_box2) controlLayout_row2.addLayout(aSpinBox) statStr = 'stimNoiseAmp' aSpinBox = mySpinBox(label='Noise Amplitude', stat=statStr, value=self.getParam(statStr), callback=self.on_spin_box2) controlLayout_row2.addLayout(aSpinBox) vLayout.addLayout(controlLayout_row2) # add mpl canvas # # row 2 #controlLayout_row2 = QtWidgets.QHBoxLayout() controlLayout_row3 = QtWidgets.QHBoxLayout() statStr = 'stimAmpStep' aSpinBox = mySpinBox(label='Amplitude Step', stat=statStr, value=self.getParam(statStr), callback=self.on_spin_box2) controlLayout_row3.addLayout(aSpinBox) statStr = 'stimFreqStep' aSpinBox = mySpinBox(label='Frequency Step', stat=statStr, value=self.getParam(statStr), callback=self.on_spin_box2) controlLayout_row3.addLayout(aSpinBox) statStr = 'stimNoiseStep' aSpinBox = mySpinBox(label='Noise Step', stat=statStr, value=self.getParam(statStr), callback=self.on_spin_box2) controlLayout_row3.addLayout(aSpinBox) # vLayout.addLayout(controlLayout_row3) # add mpl canvas controlLayout_row4 = QtWidgets.QHBoxLayout() aValue = self.getParam('rectify') checkboxName = 'Rectify' self.rectifyCheckBox = QtWidgets.QCheckBox(checkboxName) self.rectifyCheckBox.setChecked(aValue) self.rectifyCheckBox.stateChanged.connect( partial(self.on_checkbox_clicked, checkboxName)) controlLayout_row4.addWidget(self.rectifyCheckBox) statStr = 'fs' aSpinBox = mySpinBox(label='Samples Per Second', stat=statStr, value=self.getParam(statStr), callback=self.on_spin_box2) controlLayout_row4.addLayout(aSpinBox) ''' aValue = self.getParam('fs') aName = 'Samples Per Second' aLabel = QtWidgets.QLabel(aName) controlLayout_row4.addWidget(aLabel) self.fsSpinBox = QtWidgets.QSpinBox() self.fsSpinBox.setKeyboardTracking(False) self.fsSpinBox.setObjectName(aName) self.fsSpinBox.setRange(1, 100000) # TODO: Fix hard coding of 100000 self.fsSpinBox.setValue(aValue) self.fsSpinBox.valueChanged.connect(partial(self.on_spin_box, aName)) self.fsSpinBox.valueChanged.connect(self.on_spin_box2) controlLayout_row4.addWidget(self.fsSpinBox) ''' #aValue = self.getParam('scale') aName = 'Scale' aLabel = QtWidgets.QLabel(aName) controlLayout_row4.addWidget(aLabel) self.scaleDropdown = QtWidgets.QComboBox() scales = [0.001, 0.01, 0.1, 1, 10, 100, 1000] for scale in scales: scaleStr = str(scale) self.scaleDropdown.addItem(scaleStr) startIndex = 3 self.scaleDropdown.setCurrentIndex(startIndex) self.scaleDropdown.currentTextChanged.connect(self.on_scale) controlLayout_row4.addWidget(self.scaleDropdown) # vLayout.addLayout(controlLayout_row4) # add mpl canvas vSplitter = QtWidgets.QSplitter(QtCore.Qt.Vertical) vLayout.addWidget(vSplitter) plt.style.use('dark_background') self.fig = mpl.figure.Figure(constrained_layout=True) self.static_canvas = backend_qt5agg.FigureCanvas(self.fig) self.static_canvas.setFocusPolicy(QtCore.Qt.ClickFocus) self.static_canvas.setFocus() #can do self.mplToolbar.hide() self.mplToolbar = mpl.backends.backend_qt5agg.NavigationToolbar2QT( self.static_canvas, self.static_canvas) self._updateNumSweeps() #self.rawAxes = self.static_canvas.figure.add_subplot(self.numSweeps,1,1) #self.plotLine, = self.rawAxes[0].plot([], [], '-w', linewidth=1) vSplitter.addWidget(self.static_canvas) # add mpl canvas vSplitter.addWidget(self.mplToolbar) # add mpl canvas # # finalize #self.mainWidget = QtWidgets.QWidget() if qdarkstyle is not None: self.setStyleSheet(qdarkstyle.load_stylesheet(qt_api='pyqt5')) else: self.setStyleSheet("") # set the layout of the main window self.setLayout(vLayout)