def attach_to_plot_item(axis: pg.AxisItem, plot_item: pg.PlotWidget): """Функция прикрепляет ось AxisItem к графику PlotWidget""" axis.setParentItem(plot_item) view_box = plot_item.getViewBox() axis.linkToView(view_box) axis._oldAxis = plot_item.axes[axis.orientation]['item'] axis._oldAxis.hide() plot_item.axes[axis.orientation]['item'] = axis pos = plot_item.axes[axis.orientation]['pos'] plot_item.layout.addItem(axis, *pos) axis.setZValue(-1000)
def __init__(self, directory='.', **kwargs): super(astraPlotWidget, self).__init__(**kwargs) self.beam = raf.beam() self.twiss = rtf.twiss() self.directory = directory ''' twissPlotWidget ''' self.twissPlotView = GraphicsView(useOpenGL=True) self.twissPlotWidget = GraphicsLayout() self.twissPlotView.setCentralItem(self.twissPlotWidget) self.latticePlotData = imageio.imread( os.path.dirname(os.path.abspath(__file__)) + '/lattice_plot.png') self.latticePlots = {} self.twissPlots = {} i = -1 for entry in self.twissplotLayout: if entry == 'next_row': self.twissPlotWidget.nextRow() else: i += 1 p = self.twissPlotWidget.addPlot(title=entry['name']) p.showGrid(x=True, y=True) vb = p.vb vb.setYRange(*entry['range']) latticePlot = ImageItem(self.latticePlotData) latticePlot.setOpts(axisOrder='row-major') vb.addItem(latticePlot) latticePlot.setZValue(-1) # make sure this image is on top # latticePlot.setOpacity(0.5) self.twissPlots[entry['name']] = p.plot( pen=mkPen('b', width=3)) self.latticePlots[p.vb] = latticePlot p.vb.sigRangeChanged.connect(self.scaleLattice) ''' beamPlotWidget ''' self.beamPlotWidget = QWidget() self.beamPlotLayout = QVBoxLayout() self.beamPlotWidget.setLayout(self.beamPlotLayout) # # self.beamPlotChoice = # self.beamPlotAxisWidget = QWidget() self.beamPlotAxisWidget.setMaximumHeight(100) Form = self.beamPlotAxisWidget self.beamPlotXAxisDict = OrderedDict() self.beamPlotXAxisDict['x'] = {'scale': 1e3, 'axis': 'x [mm]'} self.beamPlotXAxisDict['y'] = {'scale': 1e3, 'axis': 'y [mm]'} self.beamPlotXAxisDict['z'] = { 'scale': 1e6, 'axis': 'z [micron]', 'norm': True } self.beamPlotXAxisDict['t'] = { 'scale': 1e12, 'axis': 't [ps]', 'norm': True } self.beamPlotXAxisDict['cpx'] = {'scale': 1e3, 'axis': 'cpx [keV]'} self.beamPlotXAxisDict['cpy'] = {'scale': 1e3, 'axis': 'cpy [keV]'} self.beamPlotXAxisDict['BetaGamma'] = { 'scale': 0.511, 'axis': 'cp [MeV]' } # Form.setObjectName(("Form")) # Form.resize(874, 212) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(Form.sizePolicy().hasHeightForWidth()) Form.setSizePolicy(sizePolicy) self.horizontalLayout = QHBoxLayout(Form) self.horizontalLayout.setObjectName("horizontalLayout") self.beamPlotXAxisCombo = QComboBox(Form) self.beamPlotXAxisCombo.addItems(list(self.beamPlotXAxisDict.keys())) self.beamPlotXAxisCombo.setCurrentIndex(2) self.horizontalLayout.addWidget(self.beamPlotXAxisCombo) self.beamPlotYAxisCombo = QComboBox(Form) self.beamPlotYAxisCombo.addItems(list(self.beamPlotXAxisDict.keys())) self.beamPlotYAxisCombo.setCurrentIndex(6) self.horizontalLayout.addWidget(self.beamPlotYAxisCombo) self.groupBox = QGroupBox(Form) self.groupBox.setObjectName("groupBox") self.formLayout = QFormLayout(self.groupBox) self.formLayout.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow) self.formLayout.setObjectName("formLayout") self.chooseSliceWidth = QRadioButton(self.groupBox) self.chooseSliceWidth.setObjectName(("chooseSliceWidth")) self.formLayout.setWidget(0, QFormLayout.LabelRole, self.chooseSliceWidth) self.sliceWidth = QDoubleSpinBox(self.groupBox) self.sliceWidth.setDecimals(6) self.sliceWidth.setObjectName("sliceWidth") self.formLayout.setWidget(0, QFormLayout.FieldRole, self.sliceWidth) self.chooseSliceNumber = QRadioButton(self.groupBox) self.chooseSliceNumber.setChecked(True) self.chooseSliceNumber.setObjectName("chooseSliceNumber") self.formLayout.setWidget(1, QFormLayout.LabelRole, self.chooseSliceNumber) self.sliceNumber = QSpinBox(self.groupBox) self.sliceNumber.setObjectName(("sliceNumber")) self.formLayout.setWidget(1, QFormLayout.FieldRole, self.sliceNumber) self.horizontalLayout.addWidget(self.groupBox) self.chooseSliceWidth.setText(_translate("Form", "Slice Width", None)) self.chooseSliceNumber.setText( _translate("Form", "Number of Slices", None)) self.sliceWidth.setRange(1e-6, 1) self.sliceWidth.setSingleStep(0.00001) self.histogramWidth = 0.0005 self.sliceWidth.setValue(self.histogramWidth) # self.sliceNumber = QSpinBox() self.sliceNumber.setRange(10, 10000) self.sliceNumber.setSingleStep(10) self.histogramBins = 100 self.sliceNumber.setValue(self.histogramBins) # self.beamPlotXAxisCombo = QComboBox() # self.beamPlotAxisLayout = QHBoxLayout() # self.beamPlotAxisWidget.setLayout(self.beamPlotAxisLayout) # self.beamPlotAxisLayout.addWidget(self.beamPlotXAxisCombo) # self.beamPlotAxisLayout.addWidget(self.beamPlotYAxisCombo) # self.beamPlotAxisLayout.addWidget(self.beamPlotNumberBins) self.beamPlotXAxisCombo.currentIndexChanged.connect(self.plotDataBeam) self.beamPlotYAxisCombo.currentIndexChanged.connect(self.plotDataBeam) self.chooseSliceNumber.toggled.connect(self.plotDataBeam) self.sliceNumber.valueChanged.connect(self.plotDataBeam) self.sliceWidth.valueChanged.connect(self.plotDataBeam) # self.beamPlotXAxisCombo.setCurrentIndex(2) # self.beamPlotYAxisCombo.setCurrentIndex(5) self.canvasWidget = QWidget() l = QVBoxLayout(self.canvasWidget) self.sc = MyStaticMplCanvas(self.canvasWidget, width=1, height=1, dpi=150) l.addWidget(self.sc) self.beamPlotLayout.addWidget(self.beamPlotAxisWidget) self.beamPlotLayout.addWidget(self.canvasWidget) ''' slicePlotWidget ''' self.sliceParams = [ { 'name': 'slice_normalized_horizontal_emittance', 'units': 'm-rad', 'text': 'enx' }, { 'name': 'slice_normalized_vertical_emittance', 'units': 'm-rad', 'text': 'eny' }, { 'name': 'slice_peak_current', 'units': 'A', 'text': 'PeakI' }, { 'name': 'slice_relative_momentum_spread', 'units': '%', 'text': 'sigma-p' }, { 'name': 'slice_beta_x', 'units': 'm', 'text': 'beta_x' }, { 'name': 'slice_beta_y', 'units': 'm', 'text': 'beta_y' }, ] self.slicePlotWidget = QWidget() self.slicePlotLayout = QVBoxLayout() self.slicePlotWidget.setLayout(self.slicePlotLayout) # self.slicePlotView = GraphicsView(useOpenGL=True) self.slicePlotWidgetGraphicsLayout = GraphicsLayoutWidget() # self.slicePlots = {} self.slicePlotCheckbox = {} self.curve = {} self.sliceaxis = {} self.slicePlotCheckboxWidget = QWidget() self.slicePlotCheckboxLayout = QVBoxLayout() self.slicePlotCheckboxWidget.setLayout(self.slicePlotCheckboxLayout) self.slicePlot = self.slicePlotWidgetGraphicsLayout.addPlot( title='Slice', row=0, col=50) self.slicePlot.showAxis('left', False) self.slicePlot.showGrid(x=True, y=True) i = -1 colors = ['b', 'r', 'g', 'k', 'y', 'm', 'c'] for param in self.sliceParams: i += 1 axis = AxisItem("left") labelStyle = {'color': '#' + colorStr(mkColor(colors[i]))[0:-2]} axis.setLabel(text=param['text'], units=param['units'], **labelStyle) viewbox = ViewBox() axis.linkToView(viewbox) viewbox.setXLink(self.slicePlot.vb) self.sliceaxis[param['name']] = [axis, viewbox] self.curve[param['name']] = PlotDataItem(pen=colors[i], symbol='+') viewbox.addItem(self.curve[param['name']]) col = self.findFirstEmptyColumnInGraphicsLayout() self.slicePlotWidgetGraphicsLayout.ci.addItem(axis, row=0, col=col, rowspan=1, colspan=1) self.slicePlotWidgetGraphicsLayout.ci.addItem(viewbox, row=0, col=50) p.showGrid(x=True, y=True) # self.slicePlots[param] = self.slicePlot.plot(pen=colors[i], symbol='+') self.slicePlotCheckbox[param['name']] = QCheckBox(param['text']) self.slicePlotCheckboxLayout.addWidget( self.slicePlotCheckbox[param['name']]) self.slicePlotCheckbox[param['name']].stateChanged.connect( self.plotDataSlice) # self.slicePlotView.setCentralItem(self.slicePlotWidgetGraphicsLayout) self.slicePlotSliceWidthWidget = QSpinBox() self.slicePlotSliceWidthWidget.setMaximum(500) self.slicePlotSliceWidthWidget.setValue(100) self.slicePlotSliceWidthWidget.setSingleStep(10) self.slicePlotSliceWidthWidget.setSuffix(" slices") self.slicePlotSliceWidthWidget.setSpecialValueText('Automatic') self.slicePlotAxisWidget = QWidget() self.slicePlotAxisLayout = QHBoxLayout() self.slicePlotAxisWidget.setLayout(self.slicePlotAxisLayout) self.slicePlotAxisLayout.addWidget(self.slicePlotCheckboxWidget) self.slicePlotAxisLayout.addWidget(self.slicePlotSliceWidthWidget) # self.slicePlotXAxisCombo.currentIndexChanged.connect(self.plotDataSlice) self.slicePlotSliceWidthWidget.valueChanged.connect( self.changeSliceLength) # self.beamPlotXAxisCombo.setCurrentIndex(2) # self.beamPlotYAxisCombo.setCurrentIndex(5) self.slicePlotLayout.addWidget(self.slicePlotAxisWidget) self.slicePlotLayout.addWidget(self.slicePlotWidgetGraphicsLayout) self.layout = QVBoxLayout() self.setLayout(self.layout) self.tabWidget = QTabWidget() self.folderButton = QPushButton('Select Directory') self.folderLineEdit = QLineEdit() self.folderLineEdit.setReadOnly(True) self.folderLineEdit.setText(self.directory) self.reloadButton = QPushButton() self.reloadButton.setIcon(qApp.style().standardIcon( QStyle.SP_BrowserReload)) self.folderWidget = QGroupBox() self.folderLayout = QHBoxLayout() self.folderLayout.addWidget(self.folderButton) self.folderLayout.addWidget(self.folderLineEdit) self.folderLayout.addWidget(self.reloadButton) self.folderWidget.setLayout(self.folderLayout) self.folderWidget.setMaximumWidth(800) self.reloadButton.clicked.connect( lambda: self.changeDirectory(self.directory)) self.folderButton.clicked.connect(self.changeDirectory) self.fileSelector = QComboBox() self.fileSelector.currentIndexChanged.connect(self.updateScreenCombo) self.screenSelector = QComboBox() self.screenSelector.currentIndexChanged.connect(self.changeScreen) self.beamWidget = QGroupBox() self.beamLayout = QHBoxLayout() self.beamLayout.addWidget(self.fileSelector) self.beamLayout.addWidget(self.screenSelector) self.beamWidget.setLayout(self.beamLayout) self.beamWidget.setMaximumWidth(800) self.beamWidget.setVisible(False) self.folderBeamWidget = QWidget() self.folderBeamLayout = QHBoxLayout() self.folderBeamLayout.setAlignment(Qt.AlignLeft) self.folderBeamWidget.setLayout(self.folderBeamLayout) self.folderBeamLayout.addWidget(self.folderWidget) self.folderBeamLayout.addWidget(self.beamWidget) self.tabWidget.addTab(self.twissPlotView, 'Twiss Plots') self.tabWidget.addTab(self.beamPlotWidget, 'Beam Plots') self.tabWidget.addTab(self.slicePlotWidget, 'Slice Beam Plots') # self.log = lw.loggerWidget() # self.log.addLogger(logger) # sys.stdout = lw.redirectLogger(self.log, 'stdout') # self.tabWidget.addTab(self.log,'Log') self.tabWidget.currentChanged.connect(self.changeTab) self.layout.addWidget(self.folderBeamWidget) self.layout.addWidget(self.tabWidget) self.plotType = 'Twiss' self.changeDirectory(self.directory)
def __init__(self, directory='.', **kwargs): super(astraPlotWidget, self).__init__(**kwargs) self.beam = raf.beam() self.twiss = rtf.twiss() self.directory = directory ''' twissPlotWidget ''' self.twissPlotView = GraphicsView(useOpenGL=True) self.twissPlotWidget = GraphicsLayout() self.twissPlotView.setCentralItem(self.twissPlotWidget) self.latticePlotData = imageio.imread('lattice_plot.png') self.latticePlots = {} self.twissPlots = {} i = -1 for entry in self.twissplotLayout: if entry == 'next_row': self.twissPlotWidget.nextRow() else: i += 1 p = self.twissPlotWidget.addPlot(title=entry['name']) p.showGrid(x=True, y=True) vb = p.vb vb.setYRange(*entry['range']) latticePlot = ImageItem(self.latticePlotData) latticePlot.setOpts(axisOrder='row-major') vb.addItem(latticePlot) latticePlot.setZValue(-1) # make sure this image is on top # latticePlot.setOpacity(0.5) self.twissPlots[entry['name']] = p.plot( pen=mkPen('b', width=3)) self.latticePlots[p.vb] = latticePlot p.vb.sigRangeChanged.connect(self.scaleLattice) ''' beamPlotWidget ''' self.beamPlotWidget = QWidget() self.beamPlotLayout = QVBoxLayout() self.item = ImageItem() self.beamPlotWidget.setLayout(self.beamPlotLayout) self.beamPlotView = ImageView(imageItem=self.item) self.rainbow = rainbow() self.item.setLookupTable(self.rainbow) self.item.setLevels([0, 1]) # self.beamPlotWidgetGraphicsLayout = GraphicsLayout() # p = self.beamPlotWidgetGraphicsLayout.addPlot(title='beam') # p.showGrid(x=True, y=True) # self.beamPlot = p.plot(pen=None, symbol='+') # self.beamPlotView.setCentralItem(self.beamPlotWidgetGraphicsLayout) self.beamPlotXAxisCombo = QComboBox() self.beamPlotXAxisCombo.addItems( ['x', 'y', 'zn', 'cpx', 'cpy', 'BetaGamma']) self.beamPlotYAxisCombo = QComboBox() self.beamPlotYAxisCombo.addItems( ['x', 'y', 'zn', 'cpx', 'cpy', 'BetaGamma']) self.beamPlotNumberBins = QSpinBox() self.beamPlotNumberBins.setRange(10, 500) self.beamPlotNumberBins.setSingleStep(10) self.histogramBins = 100 self.beamPlotNumberBins.setValue(self.histogramBins) self.beamPlotAxisWidget = QWidget() self.beamPlotAxisLayout = QHBoxLayout() self.beamPlotAxisWidget.setLayout(self.beamPlotAxisLayout) self.beamPlotAxisLayout.addWidget(self.beamPlotXAxisCombo) self.beamPlotAxisLayout.addWidget(self.beamPlotYAxisCombo) self.beamPlotAxisLayout.addWidget(self.beamPlotNumberBins) self.beamPlotXAxisCombo.currentIndexChanged.connect(self.plotDataBeam) self.beamPlotYAxisCombo.currentIndexChanged.connect(self.plotDataBeam) self.beamPlotNumberBins.valueChanged.connect(self.plotDataBeam) # self.beamPlotXAxisCombo.setCurrentIndex(2) # self.beamPlotYAxisCombo.setCurrentIndex(5) self.beamPlotLayout.addWidget(self.beamPlotAxisWidget) self.beamPlotLayout.addWidget(self.beamPlotView) ''' slicePlotWidget ''' self.sliceParams = [ { 'name': 'slice_normalized_horizontal_emittance', 'units': 'm-rad', 'text': 'enx' }, { 'name': 'slice_normalized_vertical_emittance', 'units': 'm-rad', 'text': 'eny' }, { 'name': 'slice_peak_current', 'units': 'A', 'text': 'PeakI' }, { 'name': 'slice_relative_momentum_spread', 'units': '%', 'text': 'sigma-p' }, ] self.slicePlotWidget = QWidget() self.slicePlotLayout = QVBoxLayout() self.slicePlotWidget.setLayout(self.slicePlotLayout) # self.slicePlotView = GraphicsView(useOpenGL=True) self.slicePlotWidgetGraphicsLayout = GraphicsLayoutWidget() # self.slicePlots = {} self.slicePlotCheckbox = {} self.curve = {} self.sliceaxis = {} self.slicePlotCheckboxWidget = QWidget() self.slicePlotCheckboxLayout = QVBoxLayout() self.slicePlotCheckboxWidget.setLayout(self.slicePlotCheckboxLayout) self.slicePlot = self.slicePlotWidgetGraphicsLayout.addPlot( title='Slice', row=0, col=50) self.slicePlot.showAxis('left', False) self.slicePlot.showGrid(x=True, y=True) i = -1 colors = ['b', 'r', 'g', 'k'] for param in self.sliceParams: i += 1 axis = AxisItem("left") labelStyle = {'color': '#' + colorStr(mkColor(colors[i]))[0:-2]} axis.setLabel(text=param['text'], units=param['units'], **labelStyle) viewbox = ViewBox() axis.linkToView(viewbox) viewbox.setXLink(self.slicePlot.vb) self.sliceaxis[param['name']] = [axis, viewbox] self.curve[param['name']] = PlotDataItem(pen=colors[i], symbol='+') viewbox.addItem(self.curve[param['name']]) col = self.findFirstEmptyColumnInGraphicsLayout() self.slicePlotWidgetGraphicsLayout.ci.addItem(axis, row=0, col=col, rowspan=1, colspan=1) self.slicePlotWidgetGraphicsLayout.ci.addItem(viewbox, row=0, col=50) p.showGrid(x=True, y=True) # self.slicePlots[param] = self.slicePlot.plot(pen=colors[i], symbol='+') self.slicePlotCheckbox[param['name']] = QCheckBox(param['text']) self.slicePlotCheckboxLayout.addWidget( self.slicePlotCheckbox[param['name']]) self.slicePlotCheckbox[param['name']].stateChanged.connect( self.plotDataSlice) # self.slicePlotView.setCentralItem(self.slicePlotWidgetGraphicsLayout) self.slicePlotSliceWidthWidget = QSpinBox() self.slicePlotSliceWidthWidget.setMaximum(1000) self.slicePlotSliceWidthWidget.setValue(100) self.slicePlotSliceWidthWidget.setSingleStep(10) self.slicePlotSliceWidthWidget.setSuffix("fs") self.slicePlotSliceWidthWidget.setSpecialValueText('Automatic') self.slicePlotAxisWidget = QWidget() self.slicePlotAxisLayout = QHBoxLayout() self.slicePlotAxisWidget.setLayout(self.slicePlotAxisLayout) self.slicePlotAxisLayout.addWidget(self.slicePlotCheckboxWidget) self.slicePlotAxisLayout.addWidget(self.slicePlotSliceWidthWidget) # self.slicePlotXAxisCombo.currentIndexChanged.connect(self.plotDataSlice) self.slicePlotSliceWidthWidget.valueChanged.connect( self.changeSliceLength) # self.beamPlotXAxisCombo.setCurrentIndex(2) # self.beamPlotYAxisCombo.setCurrentIndex(5) self.slicePlotLayout.addWidget(self.slicePlotAxisWidget) self.slicePlotLayout.addWidget(self.slicePlotWidgetGraphicsLayout) self.layout = QVBoxLayout() self.setLayout(self.layout) self.tabWidget = QTabWidget() self.folderButton = QPushButton('Select Directory') self.folderLineEdit = QLineEdit() self.folderLineEdit.setReadOnly(True) self.folderLineEdit.setText(self.directory) self.reloadButton = QPushButton() self.reloadButton.setIcon(qApp.style().standardIcon( QStyle.SP_BrowserReload)) self.folderWidget = QGroupBox() self.folderLayout = QHBoxLayout() self.folderLayout.addWidget(self.folderButton) self.folderLayout.addWidget(self.folderLineEdit) self.folderLayout.addWidget(self.reloadButton) self.folderWidget.setLayout(self.folderLayout) self.folderWidget.setMaximumWidth(800) self.reloadButton.clicked.connect( lambda: self.changeDirectory(self.directory)) self.folderButton.clicked.connect(self.changeDirectory) self.fileSelector = QComboBox() self.fileSelector.currentIndexChanged.connect(self.updateScreenCombo) self.screenSelector = QComboBox() self.screenSelector.currentIndexChanged.connect(self.changeScreen) self.beamWidget = QGroupBox() self.beamLayout = QHBoxLayout() self.beamLayout.addWidget(self.fileSelector) self.beamLayout.addWidget(self.screenSelector) self.beamWidget.setLayout(self.beamLayout) self.beamWidget.setMaximumWidth(800) self.beamWidget.setVisible(False) self.folderBeamWidget = QWidget() self.folderBeamLayout = QHBoxLayout() self.folderBeamLayout.setAlignment(Qt.AlignLeft) self.folderBeamWidget.setLayout(self.folderBeamLayout) self.folderBeamLayout.addWidget(self.folderWidget) self.folderBeamLayout.addWidget(self.beamWidget) self.tabWidget.addTab(self.twissPlotView, 'Twiss Plots') self.tabWidget.addTab(self.beamPlotWidget, 'Beam Plots') self.tabWidget.addTab(self.slicePlotWidget, 'Slice Beam Plots') self.tabWidget.currentChanged.connect(self.changeTab) self.layout.addWidget(self.folderBeamWidget) self.layout.addWidget(self.tabWidget) self.plotType = 'Twiss' self.changeDirectory(self.directory)
class DataWidget(QWidget): def __init__(self, parent, shared_data): super(DataWidget, self).__init__(parent) self.__shared_data = shared_data self.__shared_data.update_sync.emit() # Add the file selection controls self.__dir_picker_button = QPushButton() self.__dir_picker_button.setEnabled(True) self.__dir_picker_button.setText("Load data") self.__dir_picker_button.setIcon(self.style().standardIcon(QStyle.SP_DirIcon)) self.__dir_picker_button.setToolTip('Select the directory using the file explorer') self.__dir_picker_button.clicked.connect(self.__open_dir_picker) # Add the sync controls self.__sync_time_label = QLabel() self.__sync_time_label.setText('Enter the timecode (HH:mm:ss:zzz) : ') self.__sync_time_edit = QTimeEdit() self.__sync_time_edit.setDisplayFormat('HH:mm:ss:zzz') self.__sync_time_edit.setEnabled(False) self.__sync_time_button = QPushButton() self.__sync_time_button.setText('Sync data') self.__sync_time_button.setEnabled(False) self.__sync_time_button.clicked.connect(self.__sync_data) # Create the layout for the file controls dir_layout = QHBoxLayout() dir_layout.setContentsMargins(0, 0, 0, 0) dir_layout.addWidget(self.__dir_picker_button) dir_layout.addStretch(1) dir_layout.addWidget(self.__sync_time_label) dir_layout.addWidget(self.__sync_time_edit) dir_layout.addWidget(self.__sync_time_button) # Create the axis and their viewbox self.__x_axis_item = AxisItem('left') self.__y_axis_item = AxisItem('left') self.__z_axis_item = AxisItem('left') self.__x_axis_viewbox = ViewBox() self.__y_axis_viewbox = ViewBox() self.__z_axis_viewbox = ViewBox() # Create the widget which will display the data self.__graphic_view = GraphicsView(background="#ecf0f1") self.__graphic_layout = GraphicsLayout() self.__graphic_view.setCentralWidget(self.__graphic_layout) # Add the axis to the widget self.__graphic_layout.addItem(self.__x_axis_item, row=2, col=3, rowspan=1, colspan=1) self.__graphic_layout.addItem(self.__y_axis_item, row=2, col=2, rowspan=1, colspan=1) self.__graphic_layout.addItem(self.__z_axis_item, row=2, col=1, rowspan=1, colspan=1) self.__plot_item = PlotItem() self.__plot_item_viewbox = self.__plot_item.vb self.__graphic_layout.addItem(self.__plot_item, row=2, col=4, rowspan=1, colspan=1) self.__graphic_layout.scene().addItem(self.__x_axis_viewbox) self.__graphic_layout.scene().addItem(self.__y_axis_viewbox) self.__graphic_layout.scene().addItem(self.__z_axis_viewbox) self.__x_axis_item.linkToView(self.__x_axis_viewbox) self.__y_axis_item.linkToView(self.__y_axis_viewbox) self.__z_axis_item.linkToView(self.__z_axis_viewbox) self.__x_axis_viewbox.setXLink(self.__plot_item_viewbox) self.__y_axis_viewbox.setXLink(self.__plot_item_viewbox) self.__z_axis_viewbox.setXLink(self.__plot_item_viewbox) self.__plot_item_viewbox.sigResized.connect(self.__update_views) self.__x_axis_viewbox.enableAutoRange(axis=ViewBox.XAxis, enable=True) self.__y_axis_viewbox.enableAutoRange(axis=ViewBox.XAxis, enable=True) self.__z_axis_viewbox.enableAutoRange(axis=ViewBox.XAxis, enable=True) # Create the final layout self.__v_box = QVBoxLayout() self.__v_box.addLayout(dir_layout) self.__v_box.addWidget(self.__graphic_view) self.setLayout(self.__v_box) self.__restore_state() def __open_dir_picker(self): self.__shared_data.data_file_path = QFileDialog.getOpenFileUrl(self, 'Open the Hexoskin data directory', QDir.homePath())[0] if self.__shared_data.data_file_path is not None: try: self.__load_data() self.__add_selector_acc_gyr() self.__show_data('ACC_X', 'ACC_Y', 'ACC_Z') except FileNotFoundError: pass except UnicodeDecodeError: pass def __load_data(self): if self.__shared_data.data_file_path is not None: self.__shared_data.import_parameter() def __show_data(self, field1, field2, field3): if self.__shared_data.parameter is not None: # Generate the timecodes if needed if len(self.__shared_data.parameter['TIMECODE']) == 0: if self.__shared_data.sampling_rate is None: result = False while not result and result == 0: result = self.__show_sampling_rate_picker() self.__shared_data.add_timecode() self.__x_axis_viewbox.clear() self.__y_axis_viewbox.clear() self.__z_axis_viewbox.clear() # Show the 3 selected fields self.__x_axis_viewbox.addItem(PlotCurveItem(list(map(int, self.__shared_data.parameter.get(field1))), pen='#34495e')) self.__y_axis_viewbox.addItem(PlotCurveItem(list(map(int, self.__shared_data.parameter.get(field2))), pen='#9b59b6')) self.__z_axis_viewbox.addItem(PlotCurveItem(list(map(int, self.__shared_data.parameter.get(field3))), pen='#3498db')) self.__x_axis_item.setLabel(field1, color="#34495e") self.__y_axis_item.setLabel(field2, color="#9b59b6") self.__z_axis_item.setLabel(field3, color="#3498db") # Add the middle line and the bottom timecodes timecodes = self.__shared_data.parameter['TIMECODE'] middle = [0] * len(timecodes) self.__plot_item_viewbox.addItem(PlotCurveItem(middle, pen='#000000')) self.__plot_item.getAxis('bottom').setTicks( self.__generate_time_ticks(timecodes, self.__shared_data.sampling_rate)) # Enable the controls self.__sync_time_edit.setEnabled(True) self.__sync_time_button.setEnabled(True) self.__dir_picker_button.setEnabled(False) self.__update_views() def __update_views(self): self.__x_axis_viewbox.setGeometry(self.__plot_item_viewbox.sceneBoundingRect()) self.__y_axis_viewbox.setGeometry(self.__plot_item_viewbox.sceneBoundingRect()) self.__z_axis_viewbox.setGeometry(self.__plot_item_viewbox.sceneBoundingRect()) def __generate_time_ticks(self, timecodes, rate): ticks = list() steps = [rate * 30, rate * 15, rate * 5, rate] for step in steps: temp = list() i = step while i in range(len(timecodes)): temp.append((i, timecodes[i].strftime('%H:%M:%S:') + str(int(timecodes[i].microsecond / 1000)))) i += step ticks.append(temp) return ticks def __sync_data(self): self.__shared_data.data_sync = self.__sync_time_edit.text() self.__shared_data.update_sync.emit() def __show_sampling_rate_picker(self) -> bool: self.__shared_data.sampling_rate, result = QInputDialog.getInt(self, 'Set sampling rate value', 'Sampling rate') return result def __add_selector_acc_gyr(self): if 'GYR_X' in self.__shared_data.parameter.keys() or 'GYR_Y' in self.__shared_data.parameter.keys() \ or 'GYR_Z' in self.__shared_data.parameter.keys(): show_acc = QPushButton() show_acc.setText('Show Accelerometer Axis') show_acc.clicked.connect(self.__show_acc) show_gyr = QPushButton() show_gyr.setText('Show Gyroscope Axis') show_gyr.clicked.connect(self.__show_gyr) layout = QHBoxLayout() layout.addWidget(show_acc) layout.addWidget(show_gyr) layout.addStretch(1) self.__v_box.addLayout(layout) def __show_acc(self): self.__show_data('ACC_X', 'ACC_Y', 'ACC_Z') def __show_gyr(self): self.__show_data('GYR_X', 'GYR_Y', 'GYR_Z') def __restore_state(self): if self.__shared_data.parameter is not None: self.__add_selector_acc_gyr() self.__show_data('ACC_X', 'ACC_Y', 'ACC_Z') print('trigger reimport') if self.__shared_data.data_sync is not None: text_time = self.__shared_data.data_sync.split(':') time = QTime() time.setHMS(int(text_time[0]), int(text_time[1]), int(text_time[2]), int(text_time[3])) self.__sync_time_edit.setTime(time)