Пример #1
0
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