@@ -1990,14 +1990,10 @@ def on_key_press(self, event):
19901990self .update ()
19911991return
19921992for (state ,modifier )in self ._state_modifier_keys .items ():
1993- if modifier in key .split ('+' ):
1994- # rotate and data_coordinates are enable/disable
1995- # on key press
1996- if (state in ['rotate' ,'data_coordinates' ]and
1997- state in self ._state ):
1998- self ._state .discard (state )
1999- else :
2000- self ._state .add (state )
1993+ # 'rotate' and 'data_coordinates' are added in _default_state
1994+ if (modifier in key .split ('+' )and
1995+ state not in ['rotate' ,'data_coordinates' ]):
1996+ self ._state .add (state )
20011997self ._on_key_press (event )
20021998
20031999def _on_key_press (self ,event ):
@@ -2007,9 +2003,9 @@ def on_key_release(self, event):
20072003"""Key release event handler and validator."""
20082004if self .active :
20092005key = event .key or ''
2006+ key = key .replace ('ctrl' ,'control' )
20102007for (state ,modifier )in self ._state_modifier_keys .items ():
2011- if (modifier in key .split ('+' )and
2012- state not in ['rotate' ,'data_coordinates' ]):
2008+ if modifier in key .split ('+' ):
20132009self ._state .discard (state )
20142010self ._on_key_release (event )
20152011
@@ -2795,7 +2791,8 @@ def __init__(self, ax, onselect, drawtype='box',
27952791self ._interactive = interactive
27962792self .drag_from_anywhere = drag_from_anywhere
27972793self .ignore_event_outside = ignore_event_outside
2798- self ._rotation = 0
2794+ self ._rotation = 0.0
2795+ self ._aspect_ratio_correction = 1.0
27992796
28002797if drawtype == 'none' :# draw a line but make it invisible
28012798_api .warn_deprecated (
@@ -2814,6 +2811,7 @@ def __init__(self, ax, onselect, drawtype='box',
28142811_props = props
28152812self .visible = _props .pop ('visible' ,self .visible )
28162813self ._to_draw = self ._init_shape (** _props )
2814+ self ._set_aspect_ratio_correction ()
28172815self .ax .add_patch (self ._to_draw )
28182816if drawtype == 'line' :
28192817_api .warn_deprecated (
@@ -2909,6 +2907,7 @@ def _press(self, event):
29092907self .set_visible (True )
29102908
29112909self ._extents_on_press = self .extents
2910+ self ._rotation_on_press = self ._rotation
29122911
29132912return False
29142913
@@ -2984,13 +2983,8 @@ def _onmove(self, event):
29842983dy = event .ydata - eventpress .ydata
29852984refmax = None
29862985if 'data_coordinates' in state :
2987- aspect_ratio = 1
29882986refx ,refy = dx ,dy
29892987else :
2990- figure_size = self .ax .get_figure ().get_size_inches ()
2991- ll ,ur = self .ax .get_position ()* figure_size
2992- width ,height = ur - ll
2993- aspect_ratio = height / width * self .ax .get_data_ratio ()
29942988refx = event .xdata / (eventpress .xdata + 1e-6 )
29952989refy = event .ydata / (eventpress .ydata + 1e-6 )
29962990
@@ -3001,8 +2995,9 @@ def _onmove(self, event):
30012995a = np .array ([eventpress .xdata ,eventpress .ydata ])
30022996b = np .array (self .center )
30032997c = np .array ([event .xdata ,event .ydata ])
3004- self ._rotation = (np .arctan2 (c [1 ]- b [1 ],c [0 ]- b [0 ])-
3005- np .arctan2 (a [1 ]- b [1 ],a [0 ]- b [0 ]))
2998+ angle = (np .arctan2 (c [1 ]- b [1 ],c [0 ]- b [0 ])-
2999+ np .arctan2 (a [1 ]- b [1 ],a [0 ]- b [0 ]))
3000+ self ._rotation = self ._rotation_on_press + angle
30063001
30073002# resize an existing shape
30083003elif self ._active_handle and self ._active_handle != 'C' :
@@ -3017,10 +3012,10 @@ def _onmove(self, event):
30173012refmax = max (refx ,refy ,key = abs )
30183013if self ._active_handle in ['E' ,'W' ]or refmax == refx :
30193014dw = event .xdata - center [0 ]
3020- dh = dw / aspect_ratio
3015+ dh = dw
30213016else :
30223017dh = event .ydata - center [1 ]
3023- dw = dh * aspect_ratio
3018+ dw = dh
30243019else :
30253020dw = sizepress [0 ]/ 2
30263021dh = sizepress [1 ]/ 2
@@ -3053,10 +3048,10 @@ def _onmove(self, event):
30533048refmax = max (refx ,refy ,key = abs )
30543049if self ._active_handle in ['E' ,'W' ]or refmax == refx :
30553050sign = np .sign (event .ydata - y0 )
3056- y1 = y0 + sign * abs (x1 - x0 )/ aspect_ratio
3051+ y1 = y0 + sign * abs (x1 - x0 )
30573052else :
30583053sign = np .sign (event .xdata - x0 )
3059- x1 = x0 + sign * abs (y1 - y0 )* aspect_ratio
3054+ x1 = x0 + sign * abs (y1 - y0 )
30603055
30613056# move existing shape
30623057elif self ._active_handle == 'C' :
@@ -3083,9 +3078,9 @@ def _onmove(self, event):
30833078if 'square' in state :
30843079refmax = max (refx ,refy ,key = abs )
30853080if refmax == refx :
3086- dy = dx / aspect_ratio
3081+ dy = dx
30873082else :
3088- dx = dy * aspect_ratio
3083+ dx = dy
30893084
30903085# from center
30913086if 'center' in state :
@@ -3102,6 +3097,18 @@ def _onmove(self, event):
31023097
31033098self .extents = x0 ,x1 ,y0 ,y1
31043099
3100+ def _on_key_press (self ,event ):
3101+ key = event .key or ''
3102+ key = key .replace ('ctrl' ,'control' )
3103+ for (state ,modifier )in self ._state_modifier_keys .items ():
3104+ if modifier in key .split ('+' ):
3105+ if state in ['rotate' ,'data_coordinates' ]:
3106+ if state in self ._default_state :
3107+ self ._default_state .discard (state )
3108+ else :
3109+ self ._default_state .add (state )
3110+ self ._set_aspect_ratio_correction ()
3111+
31053112@property
31063113def _rect_bbox (self ):
31073114if self ._drawtype == 'box' :
@@ -3112,8 +3119,19 @@ def _rect_bbox(self):
31123119y0 ,y1 = min (y ),max (y )
31133120return x0 ,y0 ,x1 - x0 ,y1 - y0
31143121
3122+ def _set_aspect_ratio_correction (self ):
3123+ if 'data_coordinates' in self ._state | self ._default_state :
3124+ self ._aspect_ratio_correction = 1
3125+ else :
3126+ self ._aspect_ratio_correction = self .ax ._get_aspect_ratio ()
3127+ self ._to_draw ._aspect_ratio_correction = self ._aspect_ratio_correction
3128+
31153129def _get_rotation_transform (self ):
3116- return Affine2D ().rotate_around (* self .center ,self ._rotation )
3130+ return Affine2D ().translate (- self .center [0 ],- self .center [1 ]) \
3131+ .scale (1 ,self ._aspect_ratio_correction ) \
3132+ .rotate (self ._rotation ) \
3133+ .scale (1 ,1 / self ._aspect_ratio_correction ) \
3134+ .translate (* self .center )
31173135
31183136@property
31193137def corners (self ):
@@ -3285,7 +3303,7 @@ def _draw_shape(self, extents):
32853303self ._to_draw .center = center
32863304self ._to_draw .width = 2 * a
32873305self ._to_draw .height = 2 * b
3288- self ._to_draw .set_angle ( self .rotation )
3306+ self ._to_draw .angle = self .rotation
32893307else :
32903308rad = np .deg2rad (np .arange (31 )* 12 )
32913309x = a * np .cos (rad )+ center [0 ]