22Helper classes to adjust the positions of multiple axes at drawing time.
33"""
44
5+ import functools
6+
57import numpy as np
68
79import matplotlib as mpl
@@ -99,6 +101,9 @@ def get_anchor(self):
99101 """Return the anchor."""
100102 return self ._anchor
101103
104+ def get_subplotspec (self ):
105+ return None
106+
102107 def set_horizontal (self , h ):
103108 """
104109 Parameters
@@ -162,8 +167,44 @@ def _calc_offsets(sizes, k):
162167 # the resulting cumulative offset positions.
163168 return np .cumsum ([0 , * (sizes @ [k , 1 ])])
164169
170+ def new_locator (self , nx , ny , nx1 = None , ny1 = None ):
171+ """
172+ Return an axes locator callable for the specified cell.
173+
174+ Parameters
175+ ----------
176+ nx, nx1 : int
177+ Integers specifying the column-position of the
178+ cell. When *nx1* is None, a single *nx*-th column is
179+ specified. Otherwise, location of columns spanning between *nx*
180+ to *nx1* (but excluding *nx1*-th column) is specified.
181+ ny, ny1 : int
182+ Same as *nx* and *nx1*, but for row positions.
183+ """
184+ if nx1 is None :
185+ nx1 = nx + 1
186+ if ny1 is None :
187+ ny1 = ny + 1
188+ # append_size("left") adds a new size at the beginning of the
189+ # horizontal size lists; this shift transforms e.g.
190+ # new_locator(nx=2, ...) into effectively new_locator(nx=3, ...). To
191+ # take that into account, instead of recording nx, we record
192+ # nx-self._xrefindex, where _xrefindex is shifted by 1 by each
193+ # append_size("left"), and re-add self._xrefindex back to nx in
194+ # _locate, when the actual axes position is computed. Ditto for y.
195+ xref = self ._xrefindex
196+ yref = self ._yrefindex
197+ locator = functools .partial (
198+ self ._locate , nx - xref , ny - yref , nx1 - xref , ny1 - yref )
199+ locator .get_subplotspec = self .get_subplotspec
200+ return locator
201+
202+ @_api .deprecated (
203+ "3.8" , alternative = "divider.new_locator(...)(ax, renderer)" )
165204 def locate (self , nx , ny , nx1 = None , ny1 = None , axes = None , renderer = None ):
166205 """
206+ Implementation of ``divider.new_locator().__call__``.
207+
167208 Parameters
168209 ----------
169210 nx, nx1 : int
@@ -176,6 +217,25 @@ def locate(self, nx, ny, nx1=None, ny1=None, axes=None, renderer=None):
176217 axes
177218 renderer
178219 """
220+ xref = self ._xrefindex
221+ yref = self ._yrefindex
222+ return self ._locate (
223+ nx - xref , (nx + 1 if nx1 is None else nx1 ) - xref ,
224+ ny - yref , (ny + 1 if ny1 is None else ny1 ) - yref ,
225+ axes , renderer )
226+
227+ def _locate (self , nx , ny , nx1 , ny1 , axes , renderer ):
228+ """
229+ Implementation of ``divider.new_locator().__call__``.
230+
231+ The axes locator callable returned by ``new_locator()`` is created as
232+ a `functools.partial` of this method with *nx*, *ny*, *nx1*, and *ny1*
233+ specifying the requested cell.
234+ """
235+ nx += self ._xrefindex
236+ nx1 += self ._xrefindex
237+ ny += self ._yrefindex
238+ ny1 += self ._yrefindex
179239
180240 fig_w , fig_h = self ._fig .bbox .size / self ._fig .dpi
181241 x , y , w , h = self .get_position_runtime (axes , renderer )
@@ -211,25 +271,6 @@ def locate(self, nx, ny, nx1=None, ny1=None, axes=None, renderer=None):
211271
212272 return mtransforms .Bbox .from_bounds (x1 , y1 , w1 , h1 )
213273
214- def new_locator (self , nx , ny , nx1 = None , ny1 = None ):
215- """
216- Return a new `.AxesLocator` for the specified cell.
217-
218- Parameters
219- ----------
220- nx, nx1 : int
221- Integers specifying the column-position of the
222- cell. When *nx1* is None, a single *nx*-th column is
223- specified. Otherwise, location of columns spanning between *nx*
224- to *nx1* (but excluding *nx1*-th column) is specified.
225- ny, ny1 : int
226- Same as *nx* and *nx1*, but for row positions.
227- """
228- return AxesLocator (
229- self , nx , ny ,
230- nx1 if nx1 is not None else nx + 1 ,
231- ny1 if ny1 is not None else ny + 1 )
232-
233274 def append_size (self , position , size ):
234275 _api .check_in_list (["left" , "right" , "bottom" , "top" ],
235276 position = position )
@@ -264,6 +305,7 @@ def add_auto_adjustable_area(self, use_axes, pad=0.1, adjust_dirs=None):
264305 self .append_size (d , Size ._AxesDecorationsSize (use_axes , d ) + pad )
265306
266307
308+ @_api .deprecated ("3.8" )
267309class AxesLocator :
268310 """
269311 A callable object which returns the position and size of a given
@@ -400,24 +442,17 @@ def new_horizontal(self, size, pad=None, pack_start=False, **kwargs):
400442 """
401443 if pad is None :
402444 pad = mpl .rcParams ["figure.subplot.wspace" ] * self ._xref
445+ pos = "left" if pack_start else "right"
403446 if pad :
404447 if not isinstance (pad , Size ._Base ):
405448 pad = Size .from_any (pad , fraction_ref = self ._xref )
406- if pack_start :
407- self ._horizontal .insert (0 , pad )
408- self ._xrefindex += 1
409- else :
410- self ._horizontal .append (pad )
449+ self .append_size (pos , pad )
411450 if not isinstance (size , Size ._Base ):
412451 size = Size .from_any (size , fraction_ref = self ._xref )
413- if pack_start :
414- self ._horizontal .insert (0 , size )
415- self ._xrefindex += 1
416- locator = self .new_locator (nx = 0 , ny = self ._yrefindex )
417- else :
418- self ._horizontal .append (size )
419- locator = self .new_locator (
420- nx = len (self ._horizontal ) - 1 , ny = self ._yrefindex )
452+ self .append_size (pos , size )
453+ locator = self .new_locator (
454+ nx = 0 if pack_start else len (self ._horizontal ) - 1 ,
455+ ny = self ._yrefindex )
421456 ax = self ._get_new_axes (** kwargs )
422457 ax .set_axes_locator (locator )
423458 return ax
@@ -432,24 +467,17 @@ def new_vertical(self, size, pad=None, pack_start=False, **kwargs):
432467 """
433468 if pad is None :
434469 pad = mpl .rcParams ["figure.subplot.hspace" ] * self ._yref
470+ pos = "bottom" if pack_start else "top"
435471 if pad :
436472 if not isinstance (pad , Size ._Base ):
437473 pad = Size .from_any (pad , fraction_ref = self ._yref )
438- if pack_start :
439- self ._vertical .insert (0 , pad )
440- self ._yrefindex += 1
441- else :
442- self ._vertical .append (pad )
474+ self .append_size (pos , pad )
443475 if not isinstance (size , Size ._Base ):
444476 size = Size .from_any (size , fraction_ref = self ._yref )
445- if pack_start :
446- self ._vertical .insert (0 , size )
447- self ._yrefindex += 1
448- locator = self .new_locator (nx = self ._xrefindex , ny = 0 )
449- else :
450- self ._vertical .append (size )
451- locator = self .new_locator (
452- nx = self ._xrefindex , ny = len (self ._vertical ) - 1 )
477+ self .append_size (pos , size )
478+ locator = self .new_locator (
479+ nx = self ._xrefindex ,
480+ ny = 0 if pack_start else len (self ._vertical ) - 1 )
453481 ax = self ._get_new_axes (** kwargs )
454482 ax .set_axes_locator (locator )
455483 return ax
@@ -563,7 +591,7 @@ class HBoxDivider(SubplotDivider):
563591
564592 def new_locator (self , nx , nx1 = None ):
565593 """
566- Create a new `.AxesLocator` for the specified cell.
594+ Create an axes locator callable for the specified cell.
567595
568596 Parameters
569597 ----------
@@ -573,10 +601,12 @@ def new_locator(self, nx, nx1=None):
573601 specified. Otherwise, location of columns spanning between *nx*
574602 to *nx1* (but excluding *nx1*-th column) is specified.
575603 """
576- return AxesLocator ( self , nx , 0 , nx1 if nx1 is not None else nx + 1 , 1 )
604+ return super (). new_locator ( nx , 0 , nx1 , 0 )
577605
578- def locate (self , nx , ny , nx1 = None , ny1 = None , axes = None , renderer = None ):
606+ def _locate (self , nx , ny , nx1 , ny1 , axes , renderer ):
579607 # docstring inherited
608+ nx += self ._xrefindex
609+ nx1 += self ._xrefindex
580610 fig_w , fig_h = self ._fig .bbox .size / self ._fig .dpi
581611 x , y , w , h = self .get_position_runtime (axes , renderer )
582612 summed_ws = self .get_horizontal_sizes (renderer )
@@ -598,7 +628,7 @@ class VBoxDivider(SubplotDivider):
598628
599629 def new_locator (self , ny , ny1 = None ):
600630 """
601- Create a new `.AxesLocator` for the specified cell.
631+ Create an axes locator callable for the specified cell.
602632
603633 Parameters
604634 ----------
@@ -608,10 +638,12 @@ def new_locator(self, ny, ny1=None):
608638 specified. Otherwise, location of rows spanning between *ny*
609639 to *ny1* (but excluding *ny1*-th row) is specified.
610640 """
611- return AxesLocator ( self , 0 , ny , 1 , ny1 if ny1 is not None else ny + 1 )
641+ return super (). new_locator ( 0 , ny , 0 , ny1 )
612642
613- def locate (self , nx , ny , nx1 = None , ny1 = None , axes = None , renderer = None ):
643+ def _locate (self , nx , ny , nx1 , ny1 , axes , renderer ):
614644 # docstring inherited
645+ ny += self ._yrefindex
646+ ny1 += self ._yrefindex
615647 fig_w , fig_h = self ._fig .bbox .size / self ._fig .dpi
616648 x , y , w , h = self .get_position_runtime (axes , renderer )
617649 summed_hs = self .get_vertical_sizes (renderer )
0 commit comments