def run(self): """ Create original line, movable line, background "line" (just points), and fitted curve lines. Create figure and subplot, register the callbacks, and show the plot. The movable line and the curve lines are in the regions. """ rcParams["keymap.quit"] = ["ctrl+w", "cmd+w"] # Changes matplotlib's default quit keys self._process_args() self._io_manager = io.Manager(self._args) # Read the data sets outside of Regions so we can discover the x, y # range of the data to use for the initial GUI size: self._input_data_sets = self._io_manager.get_movable_data_sets() self._background_data_sets = self._io_manager.get_background_data_sets() self._setup_GUI() self._regions = regions.Regions( ax=self._ax, args=self._args, input_data_sets=self._input_data_sets, xy_limits=self._xy_limits, io_manager=self._io_manager) self._register_callbacks() # Create rectangle selector for selecting multiple points self._selector = widgets.RectangleSelector(self._ax, self.line_select_callback, drawtype='box', useblit=True, button=[1, 3], # don't use middle button spancoords='pixels') self._selector.set_active(False) # Main routine: display all figures and block until all figures have # been closed: pyplot.show()
def test_rectangle_resize_square_center_aspect(use_data_coordinates): ax = get_ax() ax.set_aspect(0.8) def onselect(epress, erelease): pass tool = widgets.RectangleSelector(ax, onselect, interactive=True, use_data_coordinates=use_data_coordinates) # Create rectangle click_and_drag(tool, start=(70, 65), end=(120, 115)) assert tool.extents == (70.0, 120.0, 65.0, 115.0) tool.add_state('square') tool.add_state('center') if use_data_coordinates: # resize E handle extents = tool.extents xdata, ydata, width = extents[1], extents[3], extents[1] - extents[0] xdiff, ycenter = 10, extents[2] + (extents[3] - extents[2]) / 2 xdata_new, ydata_new = xdata + xdiff, ydata ychange = width / 2 + xdiff click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new)) assert_allclose(tool.extents, [extents[0] - xdiff, xdata_new, ycenter - ychange, ycenter + ychange]) else: # resize E handle extents = tool.extents xdata, ydata = extents[1], extents[3] xdiff = 10 xdata_new, ydata_new = xdata + xdiff, ydata ychange = xdiff * 1 / tool._aspect_ratio_correction click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new)) assert_allclose(tool.extents, [extents[0] - xdiff, xdata_new, 46.25, 133.75])
def __init__(self, ax=None): if ax is None: self.ax = plt.gca() else: self.ax = ax self.width = self.ax.get_xlim()[1] self.height = self.ax.get_ylim()[1] # create the widget for selecting the range useblit = backend.supports_blitting() self.selector = \ widgets.RectangleSelector(self.ax, self.select_callback, drawtype='box', useblit=useblit, button=[1]) # left button # the rectangle marking the selected area self.selected = None self.selected_marker = patches.Rectangle((0, -5), 0, 0, color='y', alpha=0.5) self.ax.add_patch(self.selected_marker)
def __init__(self, zoomable_backend, viewer, min_zoom_width=10, min_zoom_height=10): """ Constructor Parameters : * renderer - The fractal renderer associated with the Zoom Functionality * viewer - The PlotPlayer instance used for playback * min_zoom_width (optional) - Minimum zoom box width * min_zoom_height (optional) - Minimum zoom box height """ self._zoomable_backend = zoomable_backend self._viewer = viewer animation_axes = self._viewer.get_render_manager().get_animation_axes() self._zoom_box = widgets.RectangleSelector(animation_axes, self.select_zoom_coords, useblit=True, minspanx=min_zoom_width, minspany=min_zoom_height, button=[_LEFT_MOUSE_BUTTON], interactive=True) figure = viewer.get_window_manager().get_figure() figure.canvas.mpl_connect('button_press_event', self._handle_mouse_button_press) figure.canvas.mpl_connect('button_release_event', self._handle_mouse_button_release)
def recMask(): ax = plt.gca() lines = ax.get_lines() assert len(lines) == 1 lines = lines[0] x,y = lines.get_data() def on_rectangle_select(event_press, event_release): 'args the press and release events' x1, y1 = event_press.xdata, event_press.ydata x2, y2 = event_release.xdata, event_release.ydata print "RECT: (%3.2f, %3.2f) --> (%3.2f, %3.2f)" % (x1, y1, x2, y2) if x1>x2: x1, x2 = x2, x1 if y1>y2: y1, y2 = y2, y1 mask = (x>=x1) & (x<=x2) & (y>=y1) & (y<=y2) return mask rect_select = widgets.RectangleSelector( ax, on_rectangle_select, drawtype='box', useblit=True, button=[1,], # use left button minspanx=5, minspany=5, spancoords='pixels', # ignore rects that are too small );
def test_selector_clear_method(selector): ax = get_ax() def onselect(*args): pass if selector == 'span': tool = widgets.SpanSelector(ax, onselect, 'horizontal', interactive=True, ignore_event_outside=True) else: tool = widgets.RectangleSelector(ax, onselect, interactive=True) click_and_drag(tool, start=(10, 10), end=(100, 120)) assert tool._selection_completed assert tool.visible if selector == 'span': assert tool.extents == (10, 100) tool.clear() assert not tool._selection_completed assert not tool.visible # Do another cycle of events to make sure we can click_and_drag(tool, start=(10, 10), end=(50, 120)) assert tool._selection_completed assert tool.visible if selector == 'span': assert tool.extents == (10, 50)
def selectRectangleROI(cube: pwsdt.ICBase, displayIndex: t_.Optional[int] = None) -> np.ndarray: """ Allow the user to draw a rectangular ROI on an image of the acquisition. Args: displayIndex (int): is used to display a particular z-slice for mask drawing. If None then the mean along Z is displayed. Returns an array of vertices of the rectangle. Returns: np.ndarray: An array of the 4 XY vertices of the rectangle. """ import warnings warnings.warn("This method has been moved to the `pwspy_gui.utility` module and will be removed in the future.", category=DeprecationWarning) verts = [None] if displayIndex is None: displayIndex = cube.data.shape[2]//2 fig, ax = plt.subplots() ax.imshow(cube.data[:, :, displayIndex]) fig.suptitle("Close to accept ROI") def rectSelect(mins, maxes): verts[0] = ((mins.ydata, mins.xdata), (maxes.ydata, mins.xdata), (maxes.ydata, maxes.xdata), (mins.ydata, maxes.xdata)) r = widgets.RectangleSelector(ax, rectSelect) fig.show() while plt.fignum_exists(fig.number): fig.canvas.flush_events() return np.array(verts[0])
def run(self): """ runs the kymograph aligner """ # show the images self.fig = plt.figure() self.ax = plt.gca() plt.subplots_adjust(bottom=0.2) # prepare image to work with image = self.kymograph._make_image(self.kymograph.offsets) height, width = image.shape window = self.window_margin self.data = np.empty((height, width + 2*window), np.double) + np.nan self.data[:, window:width + window] = image self.image = self.ax.imshow(self.data, interpolation='none', aspect='auto', cmap=plt.get_cmap('gray')) self.ax.set_title(self.title) # internal data self.active = True self.result = 'cancel' self._ax_points = None # create the widget for selecting the range useblit = graphics.backend_supports_blitting() self.selector = \ widgets.RectangleSelector(self.ax, self.select_callback, drawtype='box', useblit=useblit, button=[1]) # only use the left button # the rectangle marking the selected area self.selected = slice(0, 0) self.selected_marker = patches.Rectangle((0, -5), self.data.shape[1], 0, color='y', alpha=0.5) self.ax.add_patch(self.selected_marker) # add buttons ax_align = plt.axes([0.5, 0.05, 0.1, 0.075]) bn_align = widgets.Button(ax_align, 'Align All') bn_align.on_clicked(self.clicked_align) ax_ok = plt.axes([0.7, 0.05, 0.1, 0.075]) bn_ok = widgets.Button(ax_ok, 'Save') bn_ok.on_clicked(self.clicked_ok) ax_cancel = plt.axes([0.81, 0.05, 0.1, 0.075]) bp_cancel = widgets.Button(ax_cancel, 'Cancel') bp_cancel.on_clicked(self.clicked_cancel) # initialize the interaction with the image self.fig.canvas.mpl_connect('key_release_event', self.key_callback) # process result plt.show() return self.result
def interactive_ROI(info, directory_1): def on_key(event): global pass_accept if event.key == 'enter': pass_accept = False plt.close('all') elif event.key == 'backspace': pass_accept = True plt.close('all') def onselect(eclick, erelease): if eclick.ydata > erelease.ydata: eclick.ydata, erelease.ydata = erelease.ydata, eclick.ydata if eclick.xdata > erelease.xdata: eclick.xdata, erelease.xdata = erelease.xdata, eclick.xdata x[:] = eclick.xdata, erelease.xdata y[:] = erelease.ydata, erelease.ydata - erelease.xdata + eclick.xdata print('Press Enter to save or BACKSPACE to choose again') ax.set_xlim(min(x), max(x)) ax.set_ylim(max(y), min(y)) ax.axis('off') ax.set_yticklabels([]) ax.set_xticklabels([]) fig.canvas.mpl_connect("key_press_event", on_key) print('') print('----------------------- INTERACTIVE ROI -----------------------') while pass_accept: fig = plt.figure() ax = fig.add_subplot(111) print('Highlight the area of the ROI with the crusor') x, y = [], [] rs = widgets.RectangleSelector(ax, onselect, drawtype='box', rectprops=dict(facecolor='red', edgecolor='black', alpha=0.2, fill=True)) ax.axis('off') ax.set_yticklabels([]) ax.set_xticklabels([]) plt.imshow(info) plt.show() zoom = info[int(np.min(y)):int(np.max(y)), int(np.min(x)):int(np.max(x))] corner_coord = (x, y) np.save(directory_1 + '/zoom_coord.npy', [corner_coord[0], corner_coord[1]]) np.save(directory_1 + '/zoom.npy', zoom) return zoom, corner_coord
def test_rect_visibility(fig_test, fig_ref): # Check that requesting an invisible selector makes it invisible ax_test = fig_test.subplots() _ = fig_ref.subplots() def onselect(verts): pass tool = widgets.RectangleSelector(ax_test, onselect, props={'visible': False}) tool.extents = (0.2, 0.8, 0.3, 0.7)
def test_legend_off(): """For ellipse, test out the key modifiers""" (ax, legend) = create_plt_with_legend_off() def onselect(epress, erelease): pass tool = widgets.RectangleSelector(ax, onselect) do_event(tool, 'on_key_press', xdata=100, ydata=100, button=1, key='t') do_event(tool, 'on_key_release', xdata=100, ydata=100, button=1, key='t') assert legend.get_visible() == True
def measure_lines(self): """ shows an interface for measuring lines """ # create the widget for selecting the range useblit = graphics.backend_supports_blitting() self.selector = \ widgets.RectangleSelector(self.ax, self.select_callback, drawtype='line', lineprops=self.lineprops, useblit=useblit, button=[1]) self.line = self.ax.plot([-1, -1], [-1, -1], **self.lineprops)[0] plt.show()
def __init__(self, ax): """Base class for interactively creating plans in a 2D bounding box. Parameters ---------- ax : matplotlib.axes.Axes The axes to install the widget on """ self.ax = ax self.widget = mwidgets.RectangleSelector(self.ax, self._onselect, useblit=True, interactive=True) self._pt1 = self._pt2 = None
def plotResModel(self, res_range=(0, 4), res_num=9): """ plot the resistivity model with finite element mesh on and scale is in meters, which makes everything a lot easier to handle at the moment. """ self._make_resisitivity_range(res_range[0], res_range[1], res_num) # call plot2DmModel to draw figure and plot mesh grid self.mesh_plot = self.plot2DModel(femesh="on", yscale="m") # connect to a button press event for changing resistivity values in # the plot self.cid = self.mesh_plot.ax.figure.canvas.mpl_connect( "button_press_event", self.get_mclick_xy ) # connect to a key press event for changing resistivity values self.cid_pmres = self.mesh_plot.ax.figure.canvas.mpl_connect( "key_press_event", self.pmRes ) # make a rectangular selector self.rect_selector = widgets.RectangleSelector( self.mesh_plot.ax, self.rect_onselect, drawtype="box", useblit=True ) # make a radio boxe for changing the resistivity values easily self.radio_res_ax = self.mesh_plot.fig.add_axes(self.radio_res_loc) self.radio_res_labels = ["air", "sea"] + [ "{0:.4g}".format(rr) for rr in self.res_range[2:] ] self.radio_res = widgets.RadioButtons( self.radio_res_ax, self.radio_res_labels, active=self.res_ii ) self.radio_res.on_clicked(self.set_res_value) # calculate minimum block width self.mesh_width = np.min( [ abs(om.meshx[0, ii + 1] - xx) for ii, xx in enumerate(self.meshx[0, 7:-7], 7) ] ) self._caluculate_midpoints()
def test_rectange_add_remove_set(): ax = get_ax() def onselect(epress, erelease): pass tool = widgets.RectangleSelector(ax, onselect=onselect, interactive=True) # Draw rectangle click_and_drag(tool, start=(100, 100), end=(130, 140)) assert tool.extents == (100, 130, 100, 140) assert len(tool._state) == 0 for state in ['rotate', 'square', 'center']: tool.add_state(state) assert len(tool._state) == 1 tool.remove_state(state) assert len(tool._state) == 0
def SelectRectangle(self): fig = plt.figure() ax = fig.add_subplot(111) plt_image = plt.imshow(self.PILImage) rs = widgets.RectangleSelector(ax, self.__onselect, drawtype='box', rectprops=dict(facecolor='red', edgecolor='black', alpha=0.2, fill=True)) plt.show(block=True) x = [np.int(rs.corners[0][0]), np.int(rs.corners[0][2])] y = [np.int(rs.corners[1][0]), np.int(rs.corners[1][2])] rect = np.array([x, y]) return rs
def getTarget(self): print("start cropping") fig = plt.figure() fig.canvas.set_window_title('Select crop') ax = fig.add_subplot(111) filename = image_list[self.count] im = Image.open(filename) arr = np.asarray(im) plt_image = plt.imshow(arr) rs = widgets.RectangleSelector(ax, self.onselect, drawtype='box', rectprops=dict(facecolor='red', edgecolor='black', alpha=0.5, fill=True)) plt.show()
def test_rectangle_add_state(): ax = get_ax() def onselect(epress, erelease): pass tool = widgets.RectangleSelector(ax, onselect, interactive=True) # Create rectangle click_and_drag(tool, start=(70, 65), end=(125, 130)) with pytest.raises(ValueError): tool.add_state('unsupported_state') with pytest.raises(ValueError): tool.add_state('clear') tool.add_state('move') tool.add_state('square') tool.add_state('center')
def test_rectangle_selector_onselect(interactive): # check when press and release events take place at the same position ax = get_ax() def onselect(vmin, vmax): ax._got_onselect = True tool = widgets.RectangleSelector(ax, onselect, interactive=interactive) # move outside of axis click_and_drag(tool, start=(100, 110), end=(150, 120)) assert tool.ax._got_onselect assert tool.extents == (100.0, 150.0, 110.0, 120.0) # Reset tool.ax._got_onselect tool.ax._got_onselect = False click_and_drag(tool, start=(10, 100), end=(10, 100)) assert tool.ax._got_onselect
def test_rectangle_resize(): ax = get_ax() def onselect(epress, erelease): pass tool = widgets.RectangleSelector(ax, onselect, interactive=True) # Create rectangle click_and_drag(tool, start=(0, 10), end=(100, 120)) assert tool.extents == (0.0, 100.0, 10.0, 120.0) # resize NE handle extents = tool.extents xdata, ydata = extents[1], extents[3] xdata_new, ydata_new = xdata + 10, ydata + 5 click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new)) assert tool.extents == (extents[0], xdata_new, extents[2], ydata_new) # resize E handle extents = tool.extents xdata, ydata = extents[1], extents[2] + (extents[3] - extents[2]) / 2 xdata_new, ydata_new = xdata + 10, ydata click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new)) assert tool.extents == (extents[0], xdata_new, extents[2], extents[3]) # resize W handle extents = tool.extents xdata, ydata = extents[0], extents[2] + (extents[3] - extents[2]) / 2 xdata_new, ydata_new = xdata + 15, ydata click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new)) assert tool.extents == (xdata_new, extents[1], extents[2], extents[3]) # resize SW handle extents = tool.extents xdata, ydata = extents[0], extents[2] xdata_new, ydata_new = xdata + 20, ydata + 25 click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new)) assert tool.extents == (xdata_new, extents[1], ydata_new, extents[3])
def test_rectangle_selector_ignore_outside(ignore_event_outside): ax = get_ax() def onselect(vmin, vmax): ax._got_onselect = True tool = widgets.RectangleSelector(ax, onselect, ignore_event_outside=ignore_event_outside) click_and_drag(tool, start=(100, 110), end=(150, 120)) assert tool.ax._got_onselect assert tool.extents == (100.0, 150.0, 110.0, 120.0) # Reset ax._got_onselect = False # Trigger event outside of span click_and_drag(tool, start=(150, 150), end=(160, 160)) if ignore_event_outside: # event have been ignored and span haven't changed. assert not ax._got_onselect assert tool.extents == (100.0, 150.0, 110.0, 120.0) else: # A new shape is created assert ax._got_onselect assert tool.extents == (150.0, 160.0, 150.0, 160.0)