3333from matplotlib .patches import Patch , Rectangle , Shadow , FancyBboxPatch
3434from matplotlib .collections import LineCollection , RegularPolyCollection , \
3535 CircleCollection
36- from matplotlib .transforms import Bbox , BboxBase , TransformedBbox , BboxTransformTo
36+ from matplotlib .transforms import Bbox , BboxBase , TransformedBbox , BboxTransformTo , BboxTransformFrom
3737
38- from matplotlib .offsetbox import HPacker , VPacker , TextArea , DrawingArea
38+ from matplotlib .offsetbox import HPacker , VPacker , TextArea , DrawingArea , DraggableOffsetBox
3939
4040
41- class DraggableLegend :
42- """helper code for a draggable legend -- see Legend.draggable"""
43-
41+ class DraggableLegend (DraggableOffsetBox ):
4442 def __init__ (self , legend ):
45- self .legend = legend
46- self .gotLegend = False
47-
48- c1 = legend .figure .canvas .mpl_connect ('motion_notify_event' , self .on_motion )
49- c2 = legend .figure .canvas .mpl_connect ('pick_event' , self .on_pick )
50- c3 = legend .figure .canvas .mpl_connect ('button_release_event' , self .on_release )
51- legend .set_picker (self .my_legend_picker )
52- self .cids = [c1 , c2 , c3 ]
53-
54- def on_motion (self , evt ):
55- if self .gotLegend :
56- dx = evt .x - self .mouse_x
57- dy = evt .y - self .mouse_y
58- loc_in_canvas = self .legend_x + dx , self .legend_y + dy
59- loc_in_norm_axes = self .legend .parent .transAxes .inverted ().transform_point (loc_in_canvas )
60- self .legend ._loc = tuple (loc_in_norm_axes )
61- self .legend .figure .canvas .draw ()
62-
63- def my_legend_picker (self , legend , evt ):
64- return self .legend .legendPatch .contains (evt )
43+ self .legend = legend
44+ DraggableOffsetBox .__init__ (self , legend , legend ._legend_box )
6545
66- def on_pick (self , evt ):
67- legend = self .legend
68- if evt .artist == legend :
69- bbox = self .legend .get_window_extent ()
70- self .mouse_x = evt .mouseevent .x
71- self .mouse_y = evt .mouseevent .y
72- self .legend_x = bbox .xmin
73- self .legend_y = bbox .ymin
74- self .gotLegend = 1
46+ def artist_picker (self , legend , evt ):
47+ return self .legend .legendPatch .contains (evt )
7548
76- def on_release (self , event ):
77- if self .gotLegend :
78- self .gotLegend = False
49+ def finalize_offset (self ):
50+ loc_in_canvas = self .get_loc_in_canvas ()
7951
80- def disconnect ( self ):
81- 'disconnect the callbacks'
82- for cid in self . cids :
83- self . legend . figure . canvas . mpl_disconnect ( cid )
52+ bbox = self . legend . get_bbox_to_anchor ()
53+ _bbox_transform = BboxTransformFrom ( bbox )
54+ self . legend . _loc = tuple ( _bbox_transform . transform_point ( loc_in_canvas ))
55+
8456
8557
8658class Legend (Artist ):
@@ -323,7 +295,6 @@ def __init__(self, parent, handles, labels,
323295 'Falling back on "upper right".' )
324296 loc = 1
325297
326- self ._loc = loc
327298 self ._mode = mode
328299 self .set_bbox_to_anchor (bbox_to_anchor , bbox_transform )
329300
@@ -357,6 +328,8 @@ def __init__(self, parent, handles, labels,
357328 # init with null renderer
358329 self ._init_legend_box (handles , labels )
359330
331+ self ._loc = loc
332+
360333 self .set_title (title )
361334
362335 self ._last_fontsize_points = self ._fontsize
@@ -373,6 +346,28 @@ def _set_artist_props(self, a):
373346 a .set_transform (self .get_transform ())
374347
375348
349+ def _set_loc (self , loc ):
350+ # find_offset function will be provided to _legend_box and
351+ # _legend_box will draw itself at the location of the return
352+ # value of the find_offset.
353+ self ._loc_real = loc
354+ if loc == 0 :
355+ _findoffset = self ._findoffset_best
356+ else :
357+ _findoffset = self ._findoffset_loc
358+
359+ #def findoffset(width, height, xdescent, ydescent):
360+ # return _findoffset(width, height, xdescent, ydescent, renderer)
361+
362+ self ._legend_box .set_offset (_findoffset )
363+
364+ self ._loc_real = loc
365+
366+ def _get_loc (self ):
367+ return self ._loc_real
368+
369+ _loc = property (_get_loc , _set_loc )
370+
376371 def _findoffset_best (self , width , height , xdescent , ydescent , renderer ):
377372 "Helper function to locate the legend at its best position"
378373 ox , oy = self ._find_best_position (width , height , renderer )
@@ -401,19 +396,6 @@ def draw(self, renderer):
401396 renderer .open_group ('legend' )
402397
403398
404- # find_offset function will be provided to _legend_box and
405- # _legend_box will draw itself at the location of the return
406- # value of the find_offset.
407- if self ._loc == 0 :
408- _findoffset = self ._findoffset_best
409- else :
410- _findoffset = self ._findoffset_loc
411-
412- def findoffset (width , height , xdescent , ydescent ):
413- return _findoffset (width , height , xdescent , ydescent , renderer )
414-
415- self ._legend_box .set_offset (findoffset )
416-
417399 fontsize = renderer .points_to_pixels (self ._fontsize )
418400
419401 # if mode == fill, set the width of the legend_box to the
0 commit comments