| 27 | |
| 28 | |
| 29 | class DraggablePoint: |
| 30 | lock = None # only one can be animated at a time |
| 31 | |
| 32 | def __init__(self, point, bodyParts, individual_names=None, likelihood=None): |
| 33 | self.point = point |
| 34 | self.bodyParts = bodyParts |
| 35 | self.individual_names = individual_names |
| 36 | self.likelihood = likelihood |
| 37 | self.press = None |
| 38 | self.background = None |
| 39 | self.final_point = (0.0, 0.0) |
| 40 | self.annot = self.point.axes.annotate( |
| 41 | "", |
| 42 | xy=(0, 0), |
| 43 | xytext=(20, 20), |
| 44 | textcoords="offset points", |
| 45 | bbox=dict(boxstyle="round", fc="w"), |
| 46 | arrowprops=dict(arrowstyle="->"), |
| 47 | ) |
| 48 | self.annot.set_visible(False) |
| 49 | self.coords = [] |
| 50 | |
| 51 | def connect(self): |
| 52 | "connect to all the events we need" |
| 53 | |
| 54 | self.cidpress = self.point.figure.canvas.mpl_connect("button_press_event", self.on_press) |
| 55 | self.cidrelease = self.point.figure.canvas.mpl_connect("button_release_event", self.on_release) |
| 56 | self.cidmotion = self.point.figure.canvas.mpl_connect("motion_notify_event", self.on_motion) |
| 57 | self.cidhover = self.point.figure.canvas.mpl_connect("motion_notify_event", self.on_hover) |
| 58 | |
| 59 | def on_press(self, event): |
| 60 | """Define the event for the button press!""" |
| 61 | if event.inaxes != self.point.axes: |
| 62 | return |
| 63 | if DraggablePoint.lock is not None: |
| 64 | return |
| 65 | contains, attrd = self.point.contains(event) |
| 66 | if not contains: |
| 67 | return |
| 68 | if event.button == 1: |
| 69 | """This button press corresponds to the left click.""" |
| 70 | self.press = (self.point.center), event.xdata, event.ydata |
| 71 | DraggablePoint.lock = self |
| 72 | canvas = self.point.figure.canvas |
| 73 | axes = self.point.axes |
| 74 | self.point.set_animated(True) |
| 75 | canvas.draw() |
| 76 | self.background = canvas.copy_from_bbox(self.point.axes.bbox) |
| 77 | axes.draw_artist(self.point) |
| 78 | canvas.blit(axes.bbox) |
| 79 | elif event.button == 2: |
| 80 | """To remove a predicted label. |
| 81 | |
| 82 | Internally, the coordinates of the selected predicted label is replaced with |
| 83 | nan. The user needs to middle click for the event. After right click the |
| 84 | data point is removed from the plot. |
| 85 | """ |
| 86 | message = f"Do you want to remove the label {self.bodyParts}?" |