@@ -90,7 +90,7 @@ def _make_inset_locator(bounds, trans, parent):
90
90
`.Axes.inset_axes`.
91
91
92
92
A locator gets used in `Axes.set_aspect` to override the default
93
- locations... It is a function that takes an axes object and
93
+ locations. It is a function that takes an axes object and
94
94
a renderer and tells `set_aspect` where it is to be placed.
95
95
96
96
Here *rect* is a rectangle [l, b, w, h] that specifies the
@@ -111,6 +111,80 @@ def inset_locator(ax, renderer):
111
111
return inset_locator
112
112
113
113
114
+ def _make_inset_locator_anchored (loc , borderpad , width , height ,
115
+ bbox_to_anchor , transform , parent ):
116
+ """
117
+ Helper function to locate inset axes, used in
118
+ `.Axes.inset_axes`.
119
+
120
+ A locator gets used in `Axes.set_aspect` to override the default
121
+ locations. It is a function that takes an axes object and
122
+ a renderer and tells `set_aspect` where it is to be placed.
123
+
124
+ Here *rect* is a rectangle [l, b, w, h] that specifies the
125
+ location for the axes in the transform given by *trans* on the
126
+ *parent*.
127
+ """
128
+ codes = {'upper right' : 'NE' ,
129
+ 'upper left' : 'NW' ,
130
+ 'lower left' : 'SW' ,
131
+ 'lower right' : 'SE' ,
132
+ 'right' : 'E' ,
133
+ 'left' : 'W' ,
134
+ 'bottom' : 'S' ,
135
+ 'top' : 'N' ,
136
+ 'center left' : 'W' ,
137
+ 'center right' : 'E' ,
138
+ 'lower center' : 'S' ,
139
+ 'upper center' : 'N' ,
140
+ 'center' : 'C'
141
+ }
142
+
143
+ if loc in codes :
144
+ loc = codes [loc ]
145
+ if loc not in ['N' , 'S' , 'E' , 'W' , 'NE' , 'NW' , 'SE' , 'SW' , 'C' ]:
146
+ warnings .warn ('inset_axes location "{}" not recognized; '
147
+ 'Set to "NE".' .format (loc ))
148
+ loc = 'NE'
149
+ _loc = loc
150
+ _parent = parent
151
+ _borderpadder = borderpad
152
+ if _borderpadder is None :
153
+ _borderpadder = _parent .xaxis .get_ticklabels ()[0 ].get_size () * 0.5
154
+
155
+ _basebox = mtransforms .Bbox .from_bounds (0 , 0 , width , height )
156
+
157
+ _transform = transform
158
+ if _transform is None :
159
+ _transform = mtransforms .BboxTransformTo (_parent .bbox )
160
+
161
+ _bbox_to_anchor = bbox_to_anchor
162
+ if not isinstance (_bbox_to_anchor , mtransforms .BboxBase ):
163
+ try :
164
+ l = len (_bbox_to_anchor )
165
+ except TypeError :
166
+ raise ValueError ("Invalid argument for bbox_to_anchor : %s" %
167
+ str (_bbox_to_anchor ))
168
+ if l == 2 :
169
+ _bbox_to_anchor = [_bbox_to_anchor [0 ], _bbox_to_anchor [1 ],
170
+ width , height ]
171
+ _bbox_to_anchor = mtransforms .Bbox .from_bounds (* _bbox_to_anchor )
172
+ _bbox_to_anchor = mtransforms .TransformedBbox (_bbox_to_anchor ,
173
+ _transform )
174
+
175
+ def inset_locator (ax , renderer ):
176
+ bbox = mtransforms .TransformedBbox (_basebox , _transform )
177
+ borderpad = renderer .points_to_pixels (_borderpadder )
178
+ anchored_box = bbox .anchored (loc ,
179
+ container = _bbox_to_anchor .padded (- borderpad ))
180
+ tr = _parent .figure .transFigure .inverted ()
181
+ anchored_box = mtransforms .TransformedBbox (anchored_box , tr )
182
+
183
+ return anchored_box
184
+
185
+ return inset_locator
186
+
187
+
114
188
# The axes module contains all the wrappers to plotting functions.
115
189
# All the other methods should go in the _AxesBase class.
116
190
@@ -419,7 +493,8 @@ def _remove_legend(self, legend):
419
493
self .legend_ = None
420
494
421
495
def inset_axes (self , bounds , * , transform = None , zorder = 5 ,
422
- ** kwargs ):
496
+ borderaxespad = None , width = None , height = None ,
497
+ bbox_to_anchor = None , ** kwargs ):
423
498
"""
424
499
Add a child inset axes to this existing axes.
425
500
@@ -431,13 +506,28 @@ def inset_axes(self, bounds, *, transform=None, zorder=5,
431
506
Parameters
432
507
----------
433
508
434
- bounds : [x0, y0, width, height]
435
- Lower-left corner of inset axes, and its width and height.
509
+ bounds : [x0, y0, width, height] or string.
510
+ If four-tupple: lower-left corner of inset axes, and its width and
511
+ height.
512
+
513
+ If a string, then locations such as "NE", "N", "NW", "W", etc,
514
+ or "upper right", "top", "upper left", etc (see `~.axes.legend`)
515
+ for codes. (Note we do *not* support the numerical codes).
436
516
437
517
transform : `.Transform`
438
518
Defaults to `ax.transAxes`, i.e. the units of *rect* are in
439
519
axes-relative coordinates.
440
520
521
+ width, height : number
522
+ width and height of the inset axes. Only used if ``bounds`` is
523
+ a string. Units are set by ``transform``, and default to
524
+ axes-relative co-ordinates.
525
+
526
+ borderaxespad : number
527
+ If ``bounds`` is a string, this is the padding between the inset
528
+ axes and the parent axes in points. Defaults to half the fontsize
529
+ of the tick labels.
530
+
441
531
zorder : number
442
532
Defaults to 5 (same as `.Axes.legend`). Adjust higher or lower
443
533
to change whether it is above or below data plotted on the
@@ -470,9 +560,22 @@ def inset_axes(self, bounds, *, transform=None, zorder=5,
470
560
transform = self .transAxes
471
561
label = kwargs .pop ('label' , 'inset_axes' )
472
562
473
- # This puts the rectangle into figure-relative coordinates.
474
- inset_locator = _make_inset_locator (bounds , transform , self )
475
- bb = inset_locator (None , None )
563
+ if isinstance (bounds , str ):
564
+ # i.e. NE, S, etc
565
+ if width is None :
566
+ width = 0.25
567
+ if height is None :
568
+ height = 0.25
569
+ if bbox_to_anchor is None :
570
+ bbox_to_anchor = self .bbox
571
+ inset_locator = _make_inset_locator_anchored (bounds ,
572
+ borderaxespad , width , height , bbox_to_anchor ,
573
+ transform , self )
574
+ else :
575
+ # This puts the rectangle into figure-relative coordinates.
576
+ inset_locator = _make_inset_locator (bounds , transform , self )
577
+
578
+ bb = inset_locator (None , self .figure .canvas .get_renderer ())
476
579
477
580
inset_ax = Axes (self .figure , bb .bounds , zorder = zorder ,
478
581
label = label , ** kwargs )
@@ -549,6 +652,7 @@ def indicate_inset(self, bounds, inset_ax=None, *, transform=None,
549
652
550
653
# to make the axes connectors work, we need to apply the aspect to
551
654
# the parent axes.
655
+
552
656
self .apply_aspect ()
553
657
554
658
if transform is None :
@@ -563,7 +667,7 @@ def indicate_inset(self, bounds, inset_ax=None, *, transform=None,
563
667
564
668
if inset_ax is not None :
565
669
# want to connect the indicator to the rect....
566
-
670
+ inset_ax . apply_aspect ()
567
671
pos = inset_ax .get_position () # this is in fig-fraction.
568
672
coordsA = 'axes fraction'
569
673
connects = []
0 commit comments