From: <jd...@us...> - 2008-05-29 21:38:00
|
Revision: 5311 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5311&view=rev Author: jdh2358 Date: 2008-05-29 14:37:55 -0700 (Thu, 29 May 2008) Log Message: ----------- added path editor Modified Paths: -------------- trunk/matplotlib/examples/api/path_patch_demo.py Added Paths: ----------- trunk/matplotlib/examples/event_handling/path_editor.py Modified: trunk/matplotlib/examples/api/path_patch_demo.py =================================================================== --- trunk/matplotlib/examples/api/path_patch_demo.py 2008-05-29 21:12:59 UTC (rev 5310) +++ trunk/matplotlib/examples/api/path_patch_demo.py 2008-05-29 21:37:55 UTC (rev 5311) @@ -5,6 +5,9 @@ Path = mpath.Path +fig = plt.figure() +ax = fig.add_subplot(111) + pathdata = [ (Path.MOVETO, (0, 0)), (Path.CURVE4, (-1, 0)), @@ -19,13 +22,10 @@ codes, verts = zip(*pathdata) path = mpath.Path(verts, codes) - patch = mpatches.PathPatch(path, facecolor='green', edgecolor='yellow', alpha=0.5) - -fig = plt.figure() -ax = fig.add_subplot(111) ax.add_patch(patch) + ax.set_xlim(-5,5) ax.set_ylim(-5,5) Added: trunk/matplotlib/examples/event_handling/path_editor.py =================================================================== --- trunk/matplotlib/examples/event_handling/path_editor.py (rev 0) +++ trunk/matplotlib/examples/event_handling/path_editor.py 2008-05-29 21:37:55 UTC (rev 5311) @@ -0,0 +1,145 @@ +import numpy as np +import matplotlib.path as mpath +import matplotlib.patches as mpatches +import matplotlib.pyplot as plt +import matplotlib.mlab as mlab + +Path = mpath.Path + +fig = plt.figure() +ax = fig.add_subplot(111) + +pathdata = [ + (Path.MOVETO, (0, 0)), + (Path.CURVE4, (-1, 0.1)), + (Path.CURVE4, (-1, 0.9)), + (Path.CURVE4, (0, 1)), + (Path.LINETO, (2, 1)), + (Path.CURVE4, (3, 0.9)), + (Path.CURVE4, (3, 0.1)), + (Path.CURVE4, (2, 0)), + (Path.CLOSEPOLY, (0, 0)), + ] + +codes, verts = zip(*pathdata) +path = mpath.Path(verts, codes) +patch = mpatches.PathPatch(path, facecolor='green', edgecolor='yellow', alpha=0.5) +ax.add_patch(patch) + + +class PathInteractor: + """ + An path editor. + + Key-bindings + + 't' toggle vertex markers on and off. When vertex markers are on, + you can move them, delete them + + + """ + + showverts = True + epsilon = 5 # max pixel distance to count as a vertex hit + + def __init__(self, pathpatch): + + self.ax = pathpatch.axes + canvas = self.ax.figure.canvas + self.pathpatch = pathpatch + self.pathpatch.set_animated(True) + + x, y = zip(*self.pathpatch.get_path().vertices) + + self.line, = ax.plot(x,y,marker='o', markerfacecolor='r', animated=True) + + 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 draw_callback(self, event): + self.background = self.canvas.copy_from_bbox(self.ax.bbox) + self.ax.draw_artist(self.pathpatch) + self.ax.draw_artist(self.line) + self.canvas.blit(self.ax.bbox) + + def pathpatch_changed(self, pathpatch): + 'this method is called whenever the pathpatchgon object is called' + # only copy the artist props to the line (except visibility) + vis = self.line.get_visible() + Artist.update_from(self.line, pathpatch) + self.line.set_visible(vis) # don't use the pathpatch visibility state + + + def get_ind_under_point(self, event): + 'get the index of the vertex under point if within epsilon tolerance' + + # display coords + xy = np.asarray(self.pathpatch.get_path().vertices) + xyt = self.pathpatch.get_transform().transform(xy) + xt, yt = xyt[:, 0], xyt[:, 1] + d = np.sqrt((xt-event.x)**2 + (yt-event.y)**2) + ind = d.argmin() + + if d[ind]>=self.epsilon: + ind = None + + return ind + + def button_press_callback(self, event): + 'whenever a mouse button is pressed' + if not self.showverts: return + if event.inaxes==None: return + if event.button != 1: return + self._ind = self.get_ind_under_point(event) + + def button_release_callback(self, event): + 'whenever a mouse button is released' + if not self.showverts: return + if event.button != 1: return + self._ind = None + + def key_press_callback(self, event): + 'whenever a key is pressed' + if not event.inaxes: return + if event.key=='t': + self.showverts = not self.showverts + self.line.set_visible(self.showverts) + if not self.showverts: self._ind = None + + self.canvas.draw() + + def motion_notify_callback(self, event): + 'on mouse movement' + if not self.showverts: return + if self._ind is None: return + if event.inaxes is None: return + if event.button != 1: return + x,y = event.xdata, event.ydata + + # todo: expose me + vertices = self.pathpatch.get_path().vertices + + vertices[self._ind] = x,y + self.line.set_data(zip(*vertices)) + + self.canvas.restore_region(self.background) + self.ax.draw_artist(self.pathpatch) + self.ax.draw_artist(self.line) + self.canvas.blit(self.ax.bbox) + + +interactor = PathInteractor(patch) +ax.set_title('drag vertices to update path') +ax.set_xlim(-5,5) +ax.set_ylim(-5,5) + +plt.show() + + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |