import matplotlib.pyplot as plt
import matplotlib.patches as patches
[docs]class DraggablePoint:
"""
This class is used to managed points which can be dragged around a grid for debugging purposes.
This class is mot current used in typical analysis or visualized.
"""
lock = None # only one can be animated at a time
def __init__(self, point, move_callback=None):
"""
The DraggablePoint object creates a point which has a particular movement callback when its location change
is released.
:param point: the point location to be dragged
:param move_callback: the callback to fire whenever a movement is completed (i.e. when on_release fires)
"""
self.move_callback = move_callback
self.point = point
self.cidmotion = self.point.figure.canvas.mpl_connect('motion_notify_event', self.on_motion)
self.cidrelease = self.point.figure.canvas.mpl_connect('button_release_event', self.on_release)
self.cidpress = self.point.figure.canvas.mpl_connect('button_press_event', self.on_press)
self.press = None
self.background = None
[docs] def connect(self, move_callback=None):
"""
This function is used to connect a movement callback function which can be used for redrawing based on updated
draggable point locations.
:param move_callback: the callback to fire whenever a movement is completed (i.e. when on_release fires)
"""
self.move_callback = move_callback
# connect to all the events we need
pass
[docs] def on_press(self, event):
"""
When the draggable object is pressed, this function fires.
:param event: the event object associated with the object press
:return: None
"""
if event.inaxes != self.point.axes:
return
if DraggablePoint.lock is not None:
return
contains, attrd = self.point.contains(event)
if not contains:
return
self.press = self.point.center, event.xdata, event.ydata
DraggablePoint.lock = self
# draw everything but the selected rectangle and store the pixel buffer
canvas = self.point.figure.canvas
axes = self.point.axes
self.point.set_animated(True)
canvas.draw()
self.background = canvas.copy_from_bbox(self.point.axes.bbox)
# now redraw just the rectangle
axes.draw_artist(self.point)
# and blit just the redrawn area
canvas.blit(axes.bbox)
[docs] def on_motion(self, event):
"""
When the draggable object is moved around, this function fires.
:param event: the event object associated with the object movement
:return: None
"""
if DraggablePoint.lock is not self:
return
if event.inaxes != self.point.axes:
return
self.point.center, xpress, ypress = self.press
dx = event.xdata - xpress
dy = event.ydata - ypress
self.point.center = (self.point.center[0]+dx, self.point.center[1]+dy)
canvas = self.point.figure.canvas
axes = self.point.axes
# restore the background region
canvas.restore_region(self.background)
# redraw just the current rectangle
axes.draw_artist(self.point)
# blit just the redrawn area
canvas.blit(axes.bbox)
# noinspection PyUnusedLocal
[docs] def on_release(self, e):
"""
When the draggable point is release, this function fires.
:param e: the event object associated with the object release
:return: None
"""
if self.move_callback:
self.move_callback()
# on release we reset the press data
if DraggablePoint.lock is not self:
return
self.press = None
DraggablePoint.lock = None
# turn off the rect animation property and reset the background
self.point.set_animated(False)
self.background = None
# redraw the full figure
self.point.figure.canvas.draw()
[docs] def disconnect(self):
# disconnect all the stored connection ids
"""
"""
self.point.figure.canvas.mpl_disconnect(self.cidpress)
self.point.figure.canvas.mpl_disconnect(self.cidrelease)
self.point.figure.canvas.mpl_disconnect(self.cidmotion)
[docs]def test_draggable_points():
"""
This function allows quick, easy testing of the DraggablePoints class for the purpose of manually dragging
points around for debugging purposes for the algorithms in this package.
This module is mot current used in typical analysis or visualized.
"""
fig = plt.figure()
ax = fig.add_subplot(111)
drs = []
circles = [patches.Circle((0.32, 0.3), 0.03, fc='r', alpha=0.5),
patches.Circle((0.3, 0.3), 0.03, fc='g', alpha=0.5)]
for circ in circles:
ax.add_patch(circ)
dr = DraggablePoint(circ)
dr.connect()
drs.append(dr)
plt.show()