Using the following function, one can fit a cubic spline on input points P:
def plotCurve(P):
pts = np.vstack([P, P[0]])
x, y = pts.T
i = np.arange(len(pts))
interp_i = np.linspace(0, i.max(), 100000 * i.max())
xi = interp1d(i, x, kind='cubic')(interp_i)
yi = interp1d(i, y, kind='cubic')(interp_i)
fig, ax = plt.subplots()
fig,ax=plt.subplots()
ax.plot(xi, yi)
ax.plot(x, y, 'ko')
#plt.show()
return xi,yi
The input points P can be of the following form:
P=[(921,1181),(951,1230),(993,1243),(1035,1230),
(1065,1181),(1045,1130),(993,1130),(945,1130)]
Now, I wish to make these points of P draggable, such that as and when we change the position of any point, the spline gets refitted on the new points.
Using this as a reference: https://matplotlib.org/1.4.3/examples/event_handling/poly_editor.html (event handling in matplotlib), I have the following code:
"""
This is an example to show how to build cross-GUI applications using
matplotlib event handling to interact with objects on the canvas
"""
import numpy as np
from matplotlib.lines import Line2D
from matplotlib.artist import Artist
from matplotlib.mlab import dist_point_to_segment
class PolygonInteractor:
"""
An polygon editor.
Key-bindings
't' toggle vertex markers on and off. When vertex markers are on,
you can move them, delete them
'd' delete the vertex under point
'i' insert a vertex at point. You must be within epsilon of the
line connecting two existing vertices
"""
showverts = True
epsilon = 5 # max pixel distance to count as a vertex hit
def __init__(self, ax, poly):
if poly.figure is None:
raise RuntimeError('You must first add the polygon to a figure or canvas before defining the interactor')
self.ax = ax
canvas = poly.figure.canvas
self.poly = poly
x, y = zip(*self.poly.xy)
self.line = Line2D(x, y, marker='o', markerfacecolor='r', animated=True)
self.ax.add_line(self.line)
#self._update_line(poly)
cid = self.poly.add_callback(self.poly_changed)
self._ind = None # the active vert
canvas.mpl_connect('draw_event', self.draw_callback)
canvas.mpl_connect('button_press_event', self.button_press_callback)
canvas.mpl_connect('key_press_event', self.key_press_callback)
canvas.mpl_connect('button_release_event', self.button_release_callback)
canvas.mpl_connect('motion_notify_event', self.motion_notify_callback)
self.canvas = canvas
def