88This example demonstrates a cross-GUI application using Matplotlib event
99handling to interact with and modify objects on the canvas.
1010"""
11+
1112import numpy as np
12- import matplotlib .path as mpath
13- import matplotlib .patches as mpatches
13+ from matplotlib .backend_bases import MouseButton
14+ from matplotlib .path import Path
15+ from matplotlib .patches import PathPatch
1416import matplotlib .pyplot as plt
1517
16- Path = mpath .Path
1718
1819fig , ax = plt .subplots ()
1920
2728 (Path .CURVE4 , (3 , 0.05 )),
2829 (Path .CURVE4 , (2.0 , - 0.5 )),
2930 (Path .CLOSEPOLY , (1.58 , - 2.57 )),
30- ]
31+ ]
3132
3233codes , verts = zip (* pathdata )
33- path = mpath .Path (verts , codes )
34- patch = mpatches .PathPatch (path , facecolor = 'green' , edgecolor = 'yellow' , alpha = 0.5 )
34+ path = Path (verts , codes )
35+ patch = PathPatch (
36+ path , facecolor = 'green' , edgecolor = 'yellow' , alpha = 0.5 )
3537ax .add_patch (patch )
3638
3739
3840class PathInteractor :
3941 """
4042 An path editor.
4143
42- Key-bindings
43-
44- 't' toggle vertex markers on and off. When vertex markers are on,
45- you can move them, delete them
46-
47-
44+ Press 't' to toggle vertex markers on and off. When vertex markers are on,
45+ they can be dragged with the mouse.
4846 """
4947
5048 showverts = True
@@ -59,30 +57,18 @@ def __init__(self, pathpatch):
5957
6058 x , y = zip (* self .pathpatch .get_path ().vertices )
6159
62- self .line , = ax .plot (x , y , marker = 'o' , markerfacecolor = 'r' , animated = True )
60+ self .line , = ax .plot (
61+ x , y , marker = 'o' , markerfacecolor = 'r' , animated = True )
6362
64- self ._ind = None # the active vert
63+ self ._ind = None # the active vertex
6564
66- canvas .mpl_connect ('draw_event' , self .draw_callback )
67- canvas .mpl_connect ('button_press_event' , self .button_press_callback )
68- canvas .mpl_connect ('key_press_event' , self .key_press_callback )
69- canvas .mpl_connect ('button_release_event' , self .button_release_callback )
70- canvas .mpl_connect ('motion_notify_event' , self .motion_notify_callback )
65+ canvas .mpl_connect ('draw_event' , self .on_draw )
66+ canvas .mpl_connect ('button_press_event' , self .on_button_press )
67+ canvas .mpl_connect ('key_press_event' , self .on_key_press )
68+ canvas .mpl_connect ('button_release_event' , self .on_button_release )
69+ canvas .mpl_connect ('motion_notify_event' , self .on_motion_notify )
7170 self .canvas = canvas
7271
73- def draw_callback (self , event ):
74- self .background = self .canvas .copy_from_bbox (self .ax .bbox )
75- self .ax .draw_artist (self .pathpatch )
76- self .ax .draw_artist (self .line )
77- self .canvas .blit (self .ax .bbox )
78-
79- def pathpatch_changed (self , pathpatch ):
80- """This method is called whenever the pathpatch object is called."""
81- # only copy the artist props to the line (except visibility)
82- vis = self .line .get_visible ()
83- plt .Artist .update_from (self .line , pathpatch )
84- self .line .set_visible (vis ) # don't use the pathpatch visibility state
85-
8672 def get_ind_under_point (self , event ):
8773 """
8874 Return the index of the point closest to the event position or *None*
@@ -100,25 +86,29 @@ def get_ind_under_point(self, event):
10086
10187 return ind
10288
103- def button_press_callback (self , event ):
89+ def on_draw (self , event ):
90+ """Callback for draws."""
91+ self .background = self .canvas .copy_from_bbox (self .ax .bbox )
92+ self .ax .draw_artist (self .pathpatch )
93+ self .ax .draw_artist (self .line )
94+ self .canvas .blit (self .ax .bbox )
95+
96+ def on_button_press (self , event ):
10497 """Callback for mouse button presses."""
105- if not self .showverts :
106- return
107- if event .inaxes is None :
108- return
109- if event .button != 1 :
98+ if (event .inaxes is None
99+ or event .button != MouseButton .LEFT
100+ or not self .showverts ):
110101 return
111102 self ._ind = self .get_ind_under_point (event )
112103
113- def button_release_callback (self , event ):
104+ def on_button_release (self , event ):
114105 """Callback for mouse button releases."""
115- if not self .showverts :
116- return
117- if event .button != 1 :
106+ if (event .button != MouseButton .LEFT
107+ or not self .showverts ):
118108 return
119109 self ._ind = None
120110
121- def key_press_callback (self , event ):
111+ def on_key_press (self , event ):
122112 """Callback for key presses."""
123113 if not event .inaxes :
124114 return
@@ -127,24 +117,19 @@ def key_press_callback(self, event):
127117 self .line .set_visible (self .showverts )
128118 if not self .showverts :
129119 self ._ind = None
130-
131120 self .canvas .draw ()
132121
133- def motion_notify_callback (self , event ):
122+ def on_motion_notify (self , event ):
134123 """Callback for mouse movements."""
135- if not self .showverts :
136- return
137- if self ._ind is None :
138- return
139- if event .inaxes is None :
140- return
141- if event .button != 1 :
124+ if (self ._ind is None
125+ or event .inaxes is None
126+ or event .button != MouseButton .LEFT
127+ or not self .showverts ):
142128 return
143- x , y = event .xdata , event .ydata
144129
145130 vertices = self .pathpatch .get_path ().vertices
146131
147- vertices [self ._ind ] = x , y
132+ vertices [self ._ind ] = event . xdata , event . ydata
148133 self .line .set_data (zip (* vertices ))
149134
150135 self .canvas .restore_region (self .background )
0 commit comments