class _draggable_circles: def __init__(self, ax, position, radius, color, linestyle): self.ax = ax self.canvas = ax.figure.canvas self.position = position self.radius = radius self.circle = Circle(position, radius, color=color, linestyle=linestyle, fill=False) delta = min([ self.ax.get_xlim()[1] - self.ax.get_xlim()[0], self.ax.get_ylim()[1] - self.ax.get_ylim()[0] ]) self.currently_selected = False self.center_dot = Circle(position, delta / 200, color=color) self.circle_artist = self.ax.add_artist(self.circle) self.center_dot_artist = self.ax.add_artist(self.center_dot) self.center_dot_artist.set_visible(False) self.canvas.draw_idle() def circle_picker(self, mouseevent): if (mouseevent.xdata is None) or (mouseevent.ydata is None): return False, dict() center_xdata, center_ydata = self.circle.get_center() radius = self.circle.get_radius() tolerance = 0.05 d = np.sqrt((center_xdata - mouseevent.xdata)**2 + (center_ydata - mouseevent.ydata)**2) if d >= radius * (1 - tolerance) and d <= radius * (1 + tolerance): pickx = center_xdata picky = center_ydata props = dict(pickx=pickx, picky=picky) return True, props else: return False, dict() def click_position_finder(self, event): self.initial_click_position = (event.xdata, event.ydata) def drag_circle(self, event): if event.xdata and event.ydata: self.canvas.restore_region(self.background) centervector = (self.position[0] - self.initial_click_position[0], self.position[1] - self.initial_click_position[1]) newcenter = (centervector[0] + event.xdata, centervector[1] + event.ydata) self.center_dot.set_center(newcenter) self.circle.set_center(newcenter) self.ax.draw_artist(self.circle_artist) self.ax.draw_artist(self.center_dot_artist) self.canvas.blit(self.ax.bbox) def change_circle_size(self, event): if event.xdata and event.ydata: self.canvas.restore_region(self.background) newradius = ((self.position[0] - event.xdata)**2 + (self.position[1] - event.ydata)**2)**0.5 self.circle.set_radius(newradius) self.ax.draw_artist(self.circle_artist) self.ax.draw_artist(self.center_dot_artist) self.canvas.blit(self.ax.bbox) def start_event(self, event): if self.currently_selected: return self.currently_selected = True self.center_dot_artist.set_visible(False) self.circle_artist.set_visible(False) self.canvas.draw() self.background = self.canvas.copy_from_bbox(self.ax.bbox) self.circle_artist.set_visible(True) self.releaser = self.canvas.mpl_connect("button_press_event", self.releaseonclick) if event.button == 1: self.canvas.draw_idle() self.follower = self.canvas.mpl_connect("motion_notify_event", self.change_circle_size) if event.button == 3: self.click_position_finder(event) self.center_dot_artist.set_visible(True) self.canvas.draw_idle() self.follower = self.canvas.mpl_connect("motion_notify_event", self.drag_circle) def releaseonclick(self, event): self.radius = self.circle.get_radius() self.position = self.circle.get_center() self.center_dot_artist.set_visible(False) self.canvas.mpl_disconnect(self.follower) self.canvas.mpl_disconnect(self.releaser) self.canvas.draw_idle() self.currently_selected = False def clear(self): self.circle.remove() self.canvas.draw() return self.radius