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