def __init__(self, parent=None): """Initialize the class. Parameters ---------- parent : None, optional Top-level widget. """ super().__init__(parent) self.setupUi(self) p1 = self.scatterPlot.addPlot() self.scatterPlotItem = ScatterPlotItem() p1.addItem(self.scatterPlotItem) p1.setLabel('left', 'Y', units='pixel') p1.setLabel('bottom', 'X', units='pixel') self.yHistogramItem = None self.xHistogramItem = None self.numBins = 40 self.dataSize = None self.xData = None self.yData = None self.rollArray = False self.dataCounter = 0 self.brushes = None self.brushColor = (159, 159, 159) self.penColor = (255, 255, 255) self.maxAlpha = 255 self.minAlpha = 127 self.histogramFillBrush = mkBrush(*self.brushColor, 200) self.pointBrush = mkBrush(*self.brushColor, self.maxAlpha) self.pointPen = mkPen(*self.penColor) self.scatterPlotItem.setBrush(self.pointBrush)
def __init__(self, *args, **kwargs): self.centerplot = ScatterPlotItem(brush="r") self.centerplot.setZValue(100) super(CenterMarker, self).__init__(*args, **kwargs) self.addItem(self.centerplot) self.drawCenter()
def plotCurveAndFit(self, xData, yData): # noinspection PyTypeChecker self.plotAttributes["curve"] = ScatterPlotItem(xData, yData, pen=1, symbol='x', size=5) self.plot.addItem(self.plotAttributes["curve"]) self.plotFit(xData, yData, self.devices["B"] + ' vs. ' + self.devices["A"])
def scatter(self, x: np.ndarray, y: np.ndarray, label: Optional[str] = None, symbol: Optional[list] = None, **kwargs) -> None: kwargs = Axes._add_label_to_kwargs(label, kwargs) item = ScatterPlotItem(**kwargs) item.setData(x=x, y=y) self._raw.addItem(item)
def initPlotView(self): self.plot = PlotWidget(enableAutoRange=True) self.plot.setXRange(self.lower - self.range * 0.05, self.upper + self.range * 0.05) self.plotLegand = self.plot.addLegend() self.graphicsView.addWidget(self.plot) self.plotRegion = LinearRegionItem() self.plotRegion.setZValue(10) self.peakPoint = ScatterPlotItem(size=8, pen=mkPen(color='0000FF', width=2), symbol="+", brush=mkBrush(255, 255, 255, 240)) self.plot.addItem(self.plotRegion, ignoreBounds=True) self.plot.addItem(self.peakPoint) self.setGraphViewStyle()
def __init__(self, name): Node.__init__(self, name, terminals={ 'x': { 'io': 'in' }, 'y': { 'io': 'in' }, 'color': { 'io': 'in' }, 'plotItem': { 'io': 'out' } }) self.ScatterPlotItem = ScatterPlotItem(pen=None, symbol='o', size=2, brush=(255, 255, 255, 160)) self.sigUpdatePlot.connect(self.updatePlot)
def __init__( self, date_format="%Y-%m-%d %H:%M:%S", y_format="%0.4f", trigger_point_size=10, ): super(DataInspectorLine, self).__init__(angle=90, movable=True) self._labels = [] self._plot_item = None self.y_format = y_format self.trigger_point_size = trigger_point_size self.date_format = date_format self._label_style = "background-color: #35393C;" self.sigPositionChanged.connect(self._inspect) self._highlights = ScatterPlotItem( pos=(), symbol="s", brush="35393C88", pxMode=True, size=trigger_point_size, ) # hack to make the CurvesPropertiesTool ignore the highlight points self._highlights._UImodifiable = False
def initUI(self): self.win = QWidget() L_master = QGridLayout(self.win) # Left window, for image win_left = QWidget(self.win) L_left = QGridLayout(win_left) L_master.addWidget(win_left, 0, 0, 1, 2) # Right window, for widgets win_right = QWidget(self.win) L_right = QGridLayout(win_right) L_master.addWidget(win_right, 0, 2, 1, 1) ## IMAGE / TRAJECTORY OVERLAY # ImageView, for showing image self.imageView = ImageView(parent=win_left) L_left.addWidget(self.imageView, 0, 0) self.imageView.setImage(self.image) # GraphItems, for overlaying trajectories in various # colors self.graphItems = [GraphItem() for j in range(self.n_graphs)] for j in range(self.n_graphs): self.graphItems[j].setParentItem(self.imageView.imageItem) self.graphItems[j].scatter.setPen(color=self.graph_colors[j], width=4.0) # ScatterPlotItem, for occasional overlay of search radii self.scatterPlotItem = ScatterPlotItem() self.scatterPlotItem.setParentItem(self.imageView.imageItem) ## WIDGETS widget_align = Qt.AlignTop # Frame slider self.frame_slider = IntSlider(minimum=self.start_frame, interval=1, maximum=self.stop_frame, init_value=self.start_frame, name='Frame', parent=win_right) self.frame_slider.assign_callback(self.frame_slider_callback) L_right.addWidget(self.frame_slider, 0, 0, alignment=widget_align) # Button to toggle trajectory overlay self.B_overlay_state = True self.B_overlay = QPushButton("Overlay trajectories", parent=win_right) self.B_overlay.clicked.connect(self.B_overlay_callback) L_right.addWidget(self.B_overlay, 7, 0, alignment=widget_align) # Menu to select the tracking option methods = keys_to_str(TRACK_SLIDER_CONFIG.keys()) self.M_method = LabeledQComboBox(methods, "Method", init_value="diffusion", parent=win_right) L_right.addWidget(self.M_method, 1, 0, alignment=widget_align) self.M_method.assign_callback(self.M_method_callback) # Five semantically-flexible FloatSliders to set tracking # method parameters self.floatSliders = [] self.n_sliders = 5 for j in range(self.n_sliders): slider = FloatSlider(parent=win_right, min_width=100) L_right.addWidget(slider, 2+j, 0, alignment=widget_align) slider.assign_callback(getattr(self, "slider_%d_callback" % j)) self.floatSliders.append(slider) # Button to change ROI self.B_change_roi = QPushButton("Change ROI", parent=win_right) L_right.addWidget(self.B_change_roi, 8, 0, alignment=widget_align) self.B_change_roi.clicked.connect(self.B_change_roi_callback) # Button to change frame limits self.B_frame_limits = QPushButton("Change frame limits", parent=win_right) L_right.addWidget(self.B_frame_limits, 9, 0, alignment=widget_align) self.B_frame_limits.clicked.connect(self.B_frame_limits_callback) # Button to toggle search radius overlay self.B_search_radius_state = False self.B_search_radius = QPushButton("Show search radii", parent=win_right) L_right.addWidget(self.B_search_radius, 9, 1, alignment=widget_align) self.B_search_radius.clicked.connect(self.B_search_radius_callback) ## KEYBOARD SHORTCUTS # Tab right/left through frames self.left_shortcut = QShortcut(QKeySequence(QtGui_Qt.Key_Left), self.win) self.right_shortcut = QShortcut(QKeySequence(QtGui_Qt.Key_Right), self.win) self.left_shortcut.activated.connect(self.tab_prev_frame) self.right_shortcut.activated.connect(self.tab_next_frame) ## INITIALIZATION # overlay the first set of localizations self.change_track_method(self.M_method.currentText()) self.retrack() self.hash_tracks() self.update_tracks() # Resize and show GUI self.win.resize(self.gui_size*2, self.gui_size) self.win.show()
def initUI(self): """ Initialize the user interface. """ # Main layout L_master = QGridLayout(self) # An ImageView on the left to contain the subject of masking self.imageView = ImageView(parent=self) L_master.addWidget(self.imageView, 0, 0, 15, 2) self.imageView.setImage(self.image) # Override the default ImageView.imageItem.mouseClickEvent self.imageView.imageItem.mouseClickEvent = self._imageView_mouseClickEvent # Override the default ImageView.imageItem.mouseDoubleClickEvent self.imageView.imageItem.mouseDoubleClickEvent = \ self._imageView_mouseDoubleClickEvent # All currently clicked points self.points = [] # All current PolyLineROI objects self.polyLineROIs = [] # ScatterPlotItem, to show current accumulated clicks self.scatterPlotItem = ScatterPlotItem() self.scatterPlotItem.setParentItem(self.imageView.imageItem) ## WIDGETS widget_align = Qt.AlignTop # Frame slider self.frame_slider = IntSlider(minimum=0, maximum=self.imageReader.n_frames - 1, interval=1, init_value=0, name='Frame', parent=self) L_master.addWidget(self.frame_slider, 0, 2, 1, 1, alignment=widget_align) self.frame_slider.assign_callback(self.frame_slider_callback) # Button: create new ROI self.create_roi_mode = False self.B_create_ROI = QPushButton("Draw ROI", parent=self) self.B_create_ROI.clicked.connect(self.B_create_ROI_callback) L_master.addWidget(self.B_create_ROI, 10, 2, 1, 1, alignment=widget_align) # Button: freestyle drawing to make ROI self.freestyle_mode = False self.B_freestyle = QPushButton("Freestyle", parent=self) self.B_freestyle.clicked.connect(self.B_freestyle_callback) L_master.addWidget(self.B_freestyle, 11, 2, 1, 1, alignment=widget_align) # Pure dialog mode: no options to save or load masks, only # define and accept if self.dialog_mode: # Button: accept the current set of masks. This is only meaningful # when this class is being used as a dialog by other classes. self.B_accept = QPushButton("Accept masks", parent=self) self.B_accept.clicked.connect(self.B_accept_callback) L_master.addWidget(self.B_accept, 12, 2, 1, 1, alignment=widget_align) # Non-dialog mode: full range of options else: # Button: apply these masks to the localizations in a file self.B_apply = QPushButton("Apply masks", parent=self) self.B_apply.clicked.connect(self.B_apply_callback) L_master.addWidget(self.B_apply, 12, 2, 1, 1, alignment=widget_align) # Button: save masks to a file self.B_save = QPushButton("Save masks", parent=self) self.B_save.clicked.connect(self.B_save_callback) L_master.addWidget(self.B_save, 13, 2, 1, 1, alignment=widget_align) # Button: load preexisting masks from a file self.B_load = QPushButton("Load masks", parent=self) self.B_load.clicked.connect(self.B_load_callback) L_master.addWidget(self.B_load, 14, 2, 1, 1, alignment=widget_align) # Resize and launch self.resize(800, 600) self.show()
def __init__(self, settings, server): super().__init__() self.server = server self.timer = QTimer() self.timer.timeout.connect(self.time_tick) self.settings = settings self.current_class = None self.current_students = [] self.stack = QStackedLayout() self.setLayout(self.stack) # First page: connection instructions connect_widget = QWidget() connect_layout = QVBoxLayout(connect_widget) connect_layout.addStretch() connect_label = QLabel( "Open a world in Minecraft, open a terminal (press t), and type:", self) connect_layout.addWidget(connect_label) self.connect_command = f'/connect {server.get_ip()}:{PORT}' connect_command_box = QLineEdit(self.connect_command, self) connect_command_box.setReadOnly(True) connect_layout.addWidget(connect_command_box) connect_copy_button = QPushButton("Copy to Clipboard", self) connect_copy_button.clicked.connect( lambda: QApplication.clipboard().setText(self.connect_command)) connect_layout.addWidget(connect_copy_button) connection_problems_button = QPushButton("Connection Problems?", self) connection_problems_button.clicked.connect(self.show_connection_help) connect_layout.addWidget(connection_problems_button) connect_layout.addStretch() self.stack.addWidget(connect_widget) # Main page main_col_widget = QWidget() columns = QHBoxLayout(main_col_widget) col_left = QVBoxLayout() col_mid = QVBoxLayout() col_right = QVBoxLayout() columns.addLayout(col_left) columns.addSpacing(10) columns.addLayout(col_mid) columns.addSpacing(10) columns.addLayout(col_right) self.stack.addWidget(main_col_widget) self.pause_button = self.setup_toggle_button(col_left, self.server.pause_game, 'Un-pause', self.server.unpause_game, 'Pause') button_size = self.pause_button.size() self.disable_chat_button = self.setup_toggle_button( col_left, self.server.disable_chat, 'Enable Chat', self.server.enable_chat, 'Disable Chat', button_size) self.allow_mobs_button = self.setup_toggle_button( col_left, self.server.disallow_mobs, 'Allow Mobs', self.server.allow_mobs, 'Disable Mobs', button_size) self.allow_destructiveobjects_button = self.setup_toggle_button( col_left, self.server.disallow_destructiveobjects, 'Enable Destructive Items', self.server.allow_destructiveobjects, 'Disable Destructive Items', button_size) self.allow_player_damage_button = self.setup_toggle_button( col_left, self.server.disallow_player_damage, 'Enable Player Damage', self.server.allow_player_damage, 'Disable Player Damage', button_size) self.allow_pvp_button = self.setup_toggle_button( col_left, self.server.disallow_pvp, 'Allow Player Fighting', self.server.allow_pvp, 'Disable Player Fighting', button_size) self.immutable_button = self.setup_toggle_button( col_left, self.server.immutable_world, 'Enable World Modifications', self.server.mutable_world, 'Disable World Modifications', button_size) self.weather_button = self.setup_toggle_button( col_left, self.server.perfect_weather, 'Disable Perfect Weather', self.server.imperfect_weather, 'Enable Perfect Weather', button_size) self.disable_potions_button = self.setup_toggle_button( col_left, self.server.disable_potions, 'Enable Potions', self.server.enable_potions, 'Disable Potions', button_size) # self.clear_potions_button = QPushButton('Clear All Potion Effects', self) # self.clear_potions_button.resize(button_size) # self.clear_potions_button.clicked.connect(lambda: self.server.clear_effects("@a")) # col_left.addWidget(self.clear_potions_button) self.teleport_button = QPushButton('Teleport Everyone to You', self) self.teleport_button.resize(button_size) self.teleport_button.clicked.connect( lambda: self.server.teleport_all_to("@s")) col_left.addWidget(self.teleport_button) self.disconnect_button = QPushButton('Disconnect', self) self.disconnect_button.resize(button_size) self.disconnect_button.clicked.connect(self.server.socket_disconnected) col_left.addWidget(self.disconnect_button) col_left.addStretch() self.version_label = QLabel(f'Version {VERSION}', self) self.version_label.setAlignment(Qt.AlignCenter) col_left.addWidget(self.version_label) self.feedback_button = QPushButton('Feedback/Bug report', self) self.feedback_button.resize(button_size) self.feedback_button.clicked.connect( lambda: QDesktopServices.openUrl(FEEDBACK_URL)) col_left.addWidget(self.feedback_button) # Middle Column: Roll/Register self.classes_combo = QComboBox(self) class_names = self.settings.value("class_names", []) self.classes_combo.addItem("Select class") self.classes_combo.addItem("Add a class") self.classes_combo.addItem("Delete a class") self.classes_combo.addItems(class_names) self.classes_combo.currentTextChanged.connect(self.class_changed) col_mid.addWidget(self.classes_combo) self.users_table = QTableWidget(0, 2) self.users_table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.users_table.setSizePolicy( QSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding)) self.users_table.setFixedWidth(140) self.users_table.verticalHeader().hide() header = self.users_table.horizontalHeader() header.setSectionResizeMode(0, QHeaderView.Stretch) header.setSectionResizeMode(1, QHeaderView.ResizeToContents) header.hide() col_mid.addWidget(self.users_table) self.class_edit_button = QPushButton("Edit Class", self) col_mid.addWidget(self.class_edit_button) self.class_edit_button.clicked.connect(self.edit_class) self.chat_box = QPlainTextEdit( f'Minecraft Education Chat Logs {datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}', self) self.chat_box.setReadOnly(True) col_right.addWidget(self.chat_box) self.chat_input = QLineEdit(self) self.chat_input.setPlaceholderText("Type chat here; enter to send") self.chat_input.returnPressed.connect(self.chat_enter) col_right.addWidget(self.chat_input) self.chat_save = QPushButton("Save Chat Logs", self) self.chat_save.clicked.connect(self.save_chat) col_right.addWidget(self.chat_save) self.user_map = PlotWidget() self.map_item = ScatterPlotItem(size=10) self.user_map.addItem(self.map_item) self.user_map.getPlotItem().hideAxis('left') self.user_map.getPlotItem().hideAxis('bottom') self.map_item.scene().sigMouseMoved.connect(self.map_hover) map_viewbox = self.map_item.getViewBox() map_viewbox.menu = None col_right.addWidget(self.user_map) self.user_map_info = QLineEdit("Hover over a user", self) self.user_map_info.setReadOnly(True) col_right.addWidget(self.user_map_info) self.setGeometry(300, 300, 800, 600) self.setWindowTitle('MineClass') self.stack.setCurrentIndex(0) self.activate_buttons(False) self.show() if is_newer_version_available(): QMessageBox.about( self, "Newer Version Available", f'A newer version of this program is available <a href="{GITHUB_DOWNLOAD_URL}">here</a>.' ) if not self.settings.value("HasRunFirstTime", False): self.show_connection_help() self.settings.setValue("HasRunFirstTime", True)
def __init__(self, imodel, iview, geom, parent=None): QObject.__init__(self, parent) self.imodel = imodel self.dmodel = imodel.model self.iview = iview self.iview.ui.menuBtn.hide() self.iview.ui.roiBtn.hide() # Thanks CXIVIEW, Anton & Valerio pos = np.array([0.0, 0.5, 1.0]) color = np.array( [[255, 255, 255, 255], [128, 128, 128, 255], [0, 0, 0, 255]], dtype=np.ubyte) new_color_map = ColorMap(pos, color) self.iview.ui.histogram.gradient.setColorMap(new_color_map) self.lastrow = -1 self.curFileName = None self.curFile = None self.canDraw = self.dmodel.canSaveLst() self.checkEvent = "event" in self.dmodel.cols self.yxmap = None self.slab_shape = None self.img_shape = None self.geom_coffset = 0 self.geom_pixsize = None self.im_out = None self.resolutionLambda = None self.pixRadiusToRes = None self.hkl = None self.hklLookup = None self.imodel.dataChanged.connect(self.draw) self.iview.view.menu.addSeparator() openGeomAct = self.iview.view.menu.addAction("Load CrystFEL Geometry") openGeomAct.triggered.connect(self.openGeom) peakmenu = self.iview.view.menu.addMenu("Peaks") self.peakActionGroup = QActionGroup(self) self.peakActionGroup.setExclusive(True) self.peakActionGroup.triggered.connect(self.drawPeaks) peakNone = peakmenu.addAction("None") peakNone.setCheckable(True) peakNone.setChecked(True) peakNone.setData(0) self.peakActionGroup.addAction(peakNone) peakCXI = peakmenu.addAction("CXI") peakCXI.setCheckable(True) peakCXI.setEnabled(self.dmodel.canSaveLst()) peakCXI.setData(1) self.peakActionGroup.addAction(peakCXI) peakStream = peakmenu.addAction("Stream") peakStream.setCheckable(True) peakStream.setEnabled(self.dmodel.hasStreamPeaks()) peakStream.setData(2) self.peakActionGroup.addAction(peakStream) self.peakCanvas = ScatterPlotItem() self.iview.getView().addItem(self.peakCanvas) reflectionmenu = self.iview.view.menu.addMenu("Reflections") self.reflectionActionGroup = QActionGroup(self) self.reflectionActionGroup.setExclusive(True) self.reflectionActionGroup.triggered.connect(self.drawReflections) refNone = reflectionmenu.addAction("None") refNone.setCheckable(True) refNone.setChecked(True) refNone.setData(0) self.reflectionActionGroup.addAction(refNone) refStream = reflectionmenu.addAction("Stream") refStream.setCheckable(True) refStream.setEnabled(self.dmodel.hasStreamReflections()) refStream.setData(1) self.reflectionActionGroup.addAction(refStream) self.reflectionCanvas = ScatterPlotItem() self.iview.getView().addItem(self.reflectionCanvas) self.drawResRingsAct = self.iview.view.menu.addAction( "Resolution Rings") self.drawResRingsAct.setCheckable(True) self.drawResRingsAct.setChecked(False) self.drawResRingsAct.triggered.connect(self.drawResRings) self.drawResRingsAct.setEnabled(self.yxmap is not None) self.resolutionRingsCanvas = ScatterPlotItem() self.iview.getView().addItem(self.resolutionRingsCanvas) self.resRingsTextItems = [] for x in self.dmodel.cfg.viewerResolutionRingsAngstroms: self.resRingsTextItems.append(TextItem('', anchor=(0.5, 0.8))) self.iview.getView().addItem(self.resRingsTextItems[-1]) self.drawResolutionLimitAct = self.iview.view.menu.addAction( "Resolution Limit Ring") self.drawResolutionLimitAct.setCheckable(True) self.drawResolutionLimitAct.setChecked(False) self.drawResolutionLimitAct.triggered.connect(self.drawResLimitRing) self.drawResolutionLimitAct.setEnabled( self.yxmap is not None and 'reslim' in self.dmodel.cols) self.resolutionLimitCanvas = ScatterPlotItem() self.iview.getView().addItem(self.resolutionLimitCanvas) if geom is not None: self.loadGeom(geom) self.toolTipsAct = self.iview.view.menu.addAction( "Show Position in Tool Tip") self.toolTipsAct.setCheckable(True) self.toolTipsAct.setChecked(True) self.iview.scene.sigMouseMoved.connect(self.mouseMove) self.draw()
def initUI(self): """ Initialize the user interface. """ # Main window self.win = QWidget() L = QGridLayout(self.win) self.win.resize(self.gui_size * 1.8, self.gui_size) # Two subwindows: one on the left for the scatter plot # and one on the right for widgets self.win_left = QWidget(self.win) self.win_right = QWidget(self.win) L.addWidget(self.win_left, 0, 0, 1, 3) L.addWidget(self.win_right, 0, 3, 1, 1) L_left = QGridLayout(self.win_left) L_right = QGridLayout(self.win_right) # GraphicsLayoutWidget, to organize scatter plot and # associated items self.graphicsLayoutWidget = GraphicsLayoutWidget(parent=self.win_left) # PlotItem, to contain the ScatterPlotItem self.plotItem = self.graphicsLayoutWidget.addPlot() L_left.addWidget(self.graphicsLayoutWidget, 0, 0) # ScatterPlotItem, core data display self.scatterPlotItem = ScatterPlotItem(symbol='o', brush=None, pxMode=True, pen={ 'color': '#FFFFFF', 'width': 4.0 }, size=4.0) self.plotItem.addItem(self.scatterPlotItem) ## WIDGETS widget_align = Qt.AlignTop # Select parameter to map to the x-axis self.M_par_0 = LabeledQComboBox(self.parameters, "x-parameter", init_value="x", parent=self.win_right) L_right.addWidget(self.M_par_0, 0, 0, alignment=widget_align) self.M_par_0.assign_callback(self.M_par_callback) # Select parameter to map to the y-axis self.M_par_1 = LabeledQComboBox(self.parameters, "y-parameter", init_value="y", parent=self.win_right) L_right.addWidget(self.M_par_1, 1, 0, alignment=widget_align) self.M_par_1.assign_callback(self.M_par_callback) # Select which attribute to color the localizations by options = self.parameters + ["density"] self.M_color_by = LabeledQComboBox(options, "Color by", init_value="density", parent=self.win_right) L_right.addWidget(self.M_color_by, 0, 1, alignment=widget_align) self.M_color_by.assign_callback(self.M_color_by_callback) # Select the size of the window to use when computing # localization density window_size_options = [ str(j) for j in [3, 5, 7, 9, 11, 13, 15, 19, 23, 31, 41, 61, 81, 101] ] self.M_density_window = LabeledQComboBox(window_size_options, "Density window", init_value="7", parent=self.win_right) L_right.addWidget(self.M_density_window, 1, 1, alignment=widget_align) self.M_density_window.assign_callback(self.M_density_window_callback) # Button to induce a simpler representation that can handle # more spots self.simple_mode = False self.B_simple = QPushButton("Simple scatter", parent=self.win_right) L_right.addWidget(self.B_simple, 2, 0, alignment=widget_align) self.B_simple.clicked.connect(self.B_simple_callback) # Button to toggle log color scaling self.log_scale_mode = True self.B_log = QPushButton("Log color scale", parent=self.win_right) self.B_log.clicked.connect(self.B_log_callback) L_right.addWidget(self.B_log, 2, 1, alignment=widget_align) # Empty widgets to manipulate the layout n_rows = 15 for j in range(3, n_rows): q = QWidget(self.win_right) L_right.addWidget(q, j, 0) # Show the main window self.update_scatter() self.win.show()
def initUI(self): """ Initialize the user interface. """ # Main window self.win = QWidget() # Figure out the GUI size self.AR = float(self.imageReader.width) / self.imageReader.height self.win.resize(self.gui_size*1.5, self.gui_size) L_main = QGridLayout(self.win) # A subwindow on the left for widgets, and a subwindow # on the right for the image self.win_right = QWidget(self.win) self.win_left = QWidget(self.win) L_right = QGridLayout(self.win_right) L_left = QGridLayout(self.win_left) L_main.addWidget(self.win_right, 0, 1, 1, 3) L_main.addWidget(self.win_left, 0, 0, 1, 1) ## IMAGES / OVERLAYS # ImageView, for rendering image self.imageView = ImageView(parent=self.win_right) L_right.addWidget(self.imageView, 0, 0) # ScatterPlotItem, for overlaying localizations self.scatterPlotItem = ScatterPlotItem() self.scatterPlotItem.setParentItem(self.imageView.imageItem) # GraphItem, for overlaying trajectory histories when # desired self.graphItem = GraphItem() self.graphItem.setParentItem(self.imageView.imageItem) # # Make spots clickable self.lastClicked = [] self.scatterPlotItem.sigClicked.connect(self.spot_clicked) ## WIDGETS widget_align = Qt.AlignTop # Frame slider self.frame_slider = IntSlider(minimum=0, interval=1, maximum=self.imageReader.n_frames-1, init_value=self.start_frame, name='Frame', parent=self.win_left) L_left.addWidget(self.frame_slider, 0, 0, rowSpan=2, alignment=widget_align) self.frame_slider.assign_callback(self.frame_slider_callback) # Button to toggle spot overlays self.B_overlay_state = True self.B_overlay = QPushButton("Overlay spots", parent=self.win_left) self.B_overlay.clicked.connect(self.B_overlay_callback) L_left.addWidget(self.B_overlay, 1, 0, alignment=widget_align) # Button to toggle trajectory trails self.B_overlay_trails_state = False self.B_overlay_trails = QPushButton("Overlay histories", parent=self.win_left) self.B_overlay_trails.clicked.connect(self.B_overlay_trails_callback) L_left.addWidget(self.B_overlay_trails, 1, 1, alignment=widget_align) self.B_overlay_trails.stackUnder(self.B_overlay) # Menu to select current overlay symbol symbol_options = keys_to_str(symbol_sizes.keys()) self.M_symbol = LabeledQComboBox(symbol_options, "Overlay symbol", init_value="o", parent=self.win_left) self.M_symbol.assign_callback(self.M_symbol_callback) L_left.addWidget(self.M_symbol, 2, 0, alignment=widget_align) # Menu to select how the spots are colored color_by_options = ["None", "Trajectory", "Quantitative attribute", "Boolean attribute"] self.M_color_by = LabeledQComboBox(color_by_options, "Color spots by", init_value="None", parent=self.win_left) self.M_color_by.assign_callback(self.M_color_by_callback) L_left.addWidget(self.M_color_by, 3, 0, alignment=widget_align) # Create a new binary spot condition self.B_create_condition = QPushButton("Create Boolean attribute", parent=self.win_left) self.B_create_condition.clicked.connect(self.B_create_condition_callback) L_left.addWidget(self.B_create_condition, 4, 0, alignment=widget_align) # Select the binary column that determines color when "condition" # is selected as the color-by attribute condition_options = [c for c in self.locs.columns if self.locs[c].dtype == 'bool'] self.M_condition = LabeledQComboBox(condition_options, "Boolean attribute", init_value="None", parent=self.win_left) L_left.addWidget(self.M_condition, 3, 1, alignment=widget_align) self.M_condition.assign_callback(self.M_condition_callback) # Compare spots in a separate window that shows a grid of spots self.B_compare_spots = QPushButton("Compare spots", parent=self) L_left.addWidget(self.B_compare_spots, 2, 1, alignment=widget_align) self.B_compare_spots.clicked.connect(self.B_compare_spot_callback) # Some placeholder widgets, for better formatting for j in range(6, 18): q = QLabel(parent=self.win_left) L_left.addWidget(q, j, 0, alignment=widget_align) ## KEYBOARD SHORTCUTS - tab right/left through frames self.left_shortcut = QShortcut(QKeySequence(QtGui_Qt.Key_Left), self.win) self.right_shortcut = QShortcut(QKeySequence(QtGui_Qt.Key_Right), self.win) self.left_shortcut.activated.connect(self.tab_prev_frame) self.right_shortcut.activated.connect(self.tab_next_frame) ## DISPLAY self.update_image(autoRange=True, autoLevels=True, autoHistogramRange=True) self.overlay_spots() if "trajectory" in self.locs.columns: self.M_color_by.setCurrentText("Trajectory") self.M_color_by_callback() self.win.show()
def handlePlotClearButton(self): self.plot = ScatterPlotItem() self.plot_widget.clear() self.plot_widget.addItem(self.plot) self.plot_widget.update()
def render(self, intent): if not self.canvas_widget: bases_names = getattr(intent, 'mixins', tuple()) or tuple() bases = map( lambda name: plugin_manager.type_mapping['PlotMixinPlugin'][ name], bases_names) self.canvas_widget = type('PlotViewBlend', (*bases, PlotIntentCanvasBlend), {})() self.layout().addWidget(self.canvas_widget) self.canvas_widget.plotItem.addLegend() items = [] if isinstance(intent, (PlotIntent, ErrorBarIntent, ScatterIntent)): x = intent.x if intent.x is not None: x = np.asarray(intent.x).squeeze() ys = np.asarray(intent.y).squeeze() if ys.ndim == 1: ys = [ys] multicurves = False else: multicurves = True symbol = intent.kwargs.get("symbol", None) for i in range(len(ys)): name = intent.name if multicurves: name += f' {i + 1}' if isinstance(intent, ScatterIntent): item = ScatterPlotItem(x=x, y=ys[i], name=name, symbol=symbol) self.canvas_widget.plotItem.addItem(item) elif isinstance(intent, (PlotIntent, ErrorBarIntent)): item = self.canvas_widget.plot(x=x, y=ys[i], name=name, symbol=symbol) items.append(item) # Use most recent intent's log mode for the canvas's log mode x_log_mode = intent.kwargs.get( "xLogMode", self.canvas_widget.plotItem.getAxis("bottom").logMode) y_log_mode = intent.kwargs.get( "yLogMode", self.canvas_widget.plotItem.getAxis("left").logMode) self.canvas_widget.plotItem.setLogMode(x=x_log_mode, y=y_log_mode) self.canvas_widget.setLabels(**intent.labels) if isinstance(intent, ErrorBarIntent): kwargs = intent.kwargs.copy() for key, value in kwargs.items(): if isinstance(value, DataArray): kwargs[key] = np.asanyarray(value).squeeze() erroritem = ErrorBarItem(x=np.asarray(intent.x).squeeze(), y=np.asarray(intent.y).squeeze(), **kwargs) self.canvas_widget.plotItem.addItem(erroritem) items.append(erroritem) elif isinstance(intent, BarIntent): kwargs = intent.kwargs.copy() for key, value in kwargs.items(): if isinstance(value, DataArray): kwargs[key] = np.asanyarray(value).squeeze() if intent.x is not None: kwargs['x'] = intent.x baritem = pg.BarGraphItem(**kwargs) self.canvas_widget.plotItem.addItem(baritem) items.append(baritem) self.intent_to_items[intent] = items self.colorize() return items
def initUI(self): # Master layout self.win = QWidget() L_master = QGridLayout(self.win) # Left subwindow, for widgets win_left = QWidget(self.win) L_left = QGridLayout(win_left) L_master.addWidget(win_left, 0, 0, 1, 3) # Right subwindow, for images win_right = QWidget(self.win) L_right = QGridLayout(win_right) L_master.addWidget(win_right, 0, 3, 1, 1) # Add four LabeledImageViews to this window liv_labels = ['(1) Raw', '(2) Filtered', '(3) Convolved', '(4) Binary'] self.LIVs = [LabeledImageView(parent=win_left, label=liv_labels[j]) \ for j in range(4)] for j in range(4): L_left.addWidget(self.LIVs[j], j % 2, j // 2) self.LIVs[j].setImage(self.images[j]) # Link the views between the ImageViews for j in range(1, 4): self.LIVs[j].ImageView.view.setXLink(self.LIVs[0].ImageView.view) self.LIVs[j].ImageView.view.setYLink(self.LIVs[0].ImageView.view) # Set up three ScatterPlotItems for each of the first three ImageViews, # for overlaying detections as symbols self.SPIs = [ScatterPlotItem() for j in range(3)] for i in range(3): self.SPIs[i].setParentItem(self.LIVs[i].ImageView.imageItem) ## WIDGETS widget_align = Qt.AlignTop slider_min_width = 125 # Frame slider self.frame_slider = IntSlider(minimum=self.start_frame, maximum=self.stop_frame, interval=1, name='Frame', init_value=0, min_width=slider_min_width, parent=win_right) L_right.addWidget(self.frame_slider, 0, 0, alignment=widget_align) self.frame_slider.assign_callback(self.frame_slider_callback) # Select filtering method filter_methods = keys_to_str(FILTER_SLIDER_CONFIG.keys()) self.M_filter = LabeledQComboBox(filter_methods, "Filter method", init_value="identity", parent=win_right) L_right.addWidget(self.M_filter, 1, 0, alignment=widget_align) self.M_filter.assign_callback(self.M_filter_callback) # Select filtering chunk size chunk_size_choices = [ str(i) for i in [2, 5, 10, 15, 20, 30, 40, 60, 80, 100, 200] ] self.M_chunk_size = LabeledQComboBox(chunk_size_choices, "Chunk size") L_right.addWidget(self.M_chunk_size, 2, 0, alignment=widget_align) self.M_chunk_size.assign_callback(self.M_chunk_size_callback) self.M_chunk_size.setCurrentText(str(self.ChunkFilter.chunk_size)) # Three semantically-flexible filtering FloatSliders self.filter_sliders = [ FloatSlider(parent=win_right, min_width=slider_min_width) for j in range(3) ] for i in range(len(self.filter_sliders)): L_right.addWidget(self.filter_sliders[i], i + 3, 0, alignment=widget_align) self.filter_sliders[i].assign_callback( getattr(self, "filter_slider_%d_callback" % i)) self.filter_sliders[i].hide() # Button to change ROI self.B_change_roi = QPushButton("Change ROI", win_right) L_right.addWidget(self.B_change_roi, 6, 0, alignment=widget_align) self.B_change_roi.clicked.connect(self.B_change_roi_callback) # Button to change frame range self.B_change_frame_range = QPushButton("Change frame range", win_right) L_right.addWidget(self.B_change_frame_range, 7, 0, alignment=widget_align) self.B_change_frame_range.clicked.connect( self.B_change_frame_range_callback) # Select detection method detect_methods = keys_to_str(DETECT_SLIDER_CONFIG.keys()) self.M_detect = LabeledQComboBox(detect_methods, "Detect method", init_value="llr", parent=win_right) L_right.addWidget(self.M_detect, 0, 1, alignment=widget_align) # Set the initial detection method and arguments init_detect_method = 'llr' self.M_detect.setCurrentText(init_detect_method) self.detect_kwargs = {DETECT_SLIDER_CONFIG[init_detect_method][i]['name']: \ DETECT_SLIDER_CONFIG[init_detect_method][i]['init_value'] \ for i in DETECT_SLIDER_CONFIG[init_detect_method].keys()} self.detect_kwargs['method'] = init_detect_method self.M_detect.assign_callback(self.M_detect_callback) # Four semantically-flexible detection FloatSliders self.detect_sliders = [ FloatSlider(parent=win_right, min_width=slider_min_width) for j in range(4) ] for i in range(len(self.detect_sliders)): L_right.addWidget(self.detect_sliders[i], i + 1, 1, alignment=widget_align) self.detect_sliders[i].assign_callback( getattr(self, "detect_slider_%d_callback" % i)) # Autoscale the detection threshold self.B_auto_threshold = QPushButton("Rescale threshold", parent=win_right) L_right.addWidget(self.B_auto_threshold, 6, 1, alignment=widget_align) self.B_auto_threshold.clicked.connect(self.B_auto_threshold_callback) # Overlay detections as symbols self.B_spot_overlay_state = False self.B_spot_overlay = QPushButton("Overlay detections", parent=win_right) L_right.addWidget(self.B_spot_overlay, 7, 1, alignment=widget_align) self.B_spot_overlay.clicked.connect(self.B_spot_overlay_callback) # Change the symbol used for spot overlays symbol_choices = ['+', 'o', 'open +'] self.M_symbol = LabeledQComboBox(symbol_choices, "Spot symbol", init_value='o', parent=win_right) L_right.addWidget(self.M_symbol, 5, 1, alignment=widget_align) self.M_symbol.assign_callback(self.M_symbol_callback) # Save result to file self.B_save = QPushButton("Save settings", parent=win_right) L_right.addWidget(self.B_save, 8, 1, alignment=widget_align) self.B_save.clicked.connect(self.B_save_callback) # Show individual spots self.B_show_spots = QPushButton("Show individual spots", parent=win_right) L_right.addWidget(self.B_show_spots, 9, 1, alignment=widget_align) self.B_show_spots.clicked.connect(self.B_show_spots_callback) ## EMPTY WIDGETS for j in range(8, 24): _ql = QLabel(win_right) L_right.addWidget(_ql, j, 0, alignment=widget_align) ## KEYBOARD SHORTCUTS - tab right/left through frames self.left_shortcut = QShortcut(QKeySequence(QtGui_Qt.Key_Left), self.win) self.right_shortcut = QShortcut(QKeySequence(QtGui_Qt.Key_Right), self.win) self.left_shortcut.activated.connect(self.tab_prev_frame) self.right_shortcut.activated.connect(self.tab_next_frame) ## INITIALIZATION self.change_detect_method(init_detect_method) self.filter() self.detect() self.auto_threshold() self.update_images(1, 2, 3, autoRange=True, autoLevels=True, autoHistogramRange=True) # Resize GUI self.win.resize(self.gui_width, self.gui_height) # Show the main window self.win.show()
def setupLayout(self): self.layout = QHBoxLayout(self) self.splitter = QSplitter(Qt.Horizontal) self.settingswidget = QWidget(self) self.settingswidget.setMaximumWidth(400) self.settingslayout = QVBoxLayout() self.percolationWidget = PercolationWidget() self.graph_type_combobox = QComboBox(self) self.graph_type_combobox.addItems(self.graph_names) self.graph_type_combobox.currentIndexChanged.connect( self.handleGraphTypeChanged) self.graph_type_combobox.setFocusPolicy(Qt.NoFocus) self.settingslayout.addWidget(self.graph_type_combobox) self.p_slider_layout = QHBoxLayout() self.settingslayout.addLayout(self.p_slider_layout) self.p_slider_layout.addWidget(QLabel("Set p value: ", self)) self.p_slider_label = QLabel(self) self.p_slider = QSlider(Qt.Horizontal, self) self.p_slider.valueChanged.connect(self.handlePSliderChange) self.p_slider_layout.addWidget(self.p_slider) self.p_slider_layout.addWidget(self.p_slider_label) self.N_slider_layout = QHBoxLayout() self.settingslayout.addLayout(self.N_slider_layout) self.N_slider_layout.addWidget(QLabel("Set size (N): ", self)) self.N_slider_label = QLabel(self) self.N_slider = QSlider(Qt.Horizontal, self) self.N_slider.valueChanged.connect(self.handleNSliderChange) self.N_slider_layout.addWidget(self.N_slider) self.N_slider_layout.addWidget(self.N_slider_label) # wether to refresh edges each time or keep edges to add to/remove from self.refresh_edges_checkbox = QCheckBox( "Refresh Edges instead of Adding/Removing", self) self.refresh_edges_checkbox.stateChanged.connect( self.handleRefreshCheckboxChange) self.settingslayout.addWidget(self.refresh_edges_checkbox) self.settingslayout.addSpacerItem( QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)) self.plot_widget = PlotWidget(name="clustersize by p") self.settingslayout.addWidget(self.plot_widget) self.plot_widget.setLabel('left', 'maximum cluster size', units='%') self.plot_widget.setLabel('bottom', 'p', units='') self.plot_widget.setXRange(0, 1) self.plot_widget.setYRange(0, 1) self.plot = ScatterPlotItem() self.plot_widget.addItem(self.plot) self.plot_clear_button = QPushButton("Clear plot") self.plot_clear_button.clicked.connect(self.handlePlotClearButton) self.settingslayout.addWidget(self.plot_clear_button) self.settingswidget.setLayout(self.settingslayout) self.settingswidget.setMinimumSize(50, 50) self.splitter.addWidget(self.settingswidget) self.splitter.addWidget(self.percolationWidget) self.layout.addWidget(self.splitter) self.percolationWidget.graphUpdated.connect(self.handleGraphUpdated) self.setWindowTitle('Percolation Model') self.setFocus()