2
2
Helper classes to adjust the positions of multiple axes at drawing time.
3
3
"""
4
4
5
+ import functools
6
+
5
7
import numpy as np
6
8
7
9
import matplotlib as mpl
@@ -99,6 +101,9 @@ def get_anchor(self):
99
101
"""Return the anchor."""
100
102
return self ._anchor
101
103
104
+ def get_subplotspec (self ):
105
+ return None
106
+
102
107
def set_horizontal (self , h ):
103
108
"""
104
109
Parameters
@@ -162,8 +167,44 @@ def _calc_offsets(sizes, k):
162
167
# the resulting cumulative offset positions.
163
168
return np .cumsum ([0 , * (sizes @ [k , 1 ])])
164
169
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.7" , alternative = "divider.new_locator(...)(ax, renderer)" )
165
204
def locate (self , nx , ny , nx1 = None , ny1 = None , axes = None , renderer = None ):
166
205
"""
206
+ Implementation of ``divider.new_locator().__call__``.
207
+
167
208
Parameters
168
209
----------
169
210
nx, nx1 : int
@@ -176,6 +217,25 @@ def locate(self, nx, ny, nx1=None, ny1=None, axes=None, renderer=None):
176
217
axes
177
218
renderer
178
219
"""
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
179
239
180
240
fig_w , fig_h = self ._fig .bbox .size / self ._fig .dpi
181
241
x , y , w , h = self .get_position_runtime (axes , renderer )
@@ -201,43 +261,11 @@ def locate(self, nx, ny, nx1=None, ny1=None, axes=None, renderer=None):
201
261
oy = self ._calc_offsets (vsizes , k_v )
202
262
x0 , y0 = x , y
203
263
204
- if nx1 is None :
205
- _api .warn_deprecated (
206
- "3.5" , message = "Support for passing nx1=None to mean nx+1 is "
207
- "deprecated since %(since)s; in a future version, nx1=None "
208
- "will mean 'up to the last cell'." )
209
- nx1 = nx + 1
210
- if ny1 is None :
211
- _api .warn_deprecated (
212
- "3.5" , message = "Support for passing ny1=None to mean ny+1 is "
213
- "deprecated since %(since)s; in a future version, ny1=None "
214
- "will mean 'up to the last cell'." )
215
- ny1 = ny + 1
216
-
217
264
x1 , w1 = x0 + ox [nx ] / fig_w , (ox [nx1 ] - ox [nx ]) / fig_w
218
265
y1 , h1 = y0 + oy [ny ] / fig_h , (oy [ny1 ] - oy [ny ]) / fig_h
219
266
220
267
return mtransforms .Bbox .from_bounds (x1 , y1 , w1 , h1 )
221
268
222
- def new_locator (self , nx , ny , nx1 = None , ny1 = None ):
223
- """
224
- Return a new `.AxesLocator` for the specified cell.
225
-
226
- Parameters
227
- ----------
228
- nx, nx1 : int
229
- Integers specifying the column-position of the
230
- cell. When *nx1* is None, a single *nx*-th column is
231
- specified. Otherwise, location of columns spanning between *nx*
232
- to *nx1* (but excluding *nx1*-th column) is specified.
233
- ny, ny1 : int
234
- Same as *nx* and *nx1*, but for row positions.
235
- """
236
- return AxesLocator (
237
- self , nx , ny ,
238
- nx1 if nx1 is not None else nx + 1 ,
239
- ny1 if ny1 is not None else ny + 1 )
240
-
241
269
def append_size (self , position , size ):
242
270
_api .check_in_list (["left" , "right" , "bottom" , "top" ],
243
271
position = position )
@@ -272,6 +300,7 @@ def add_auto_adjustable_area(self, use_axes, pad=0.1, adjust_dirs=None):
272
300
self .append_size (d , Size ._AxesDecorationsSize (use_axes , d ) + pad )
273
301
274
302
303
+ @_api .deprecated ("3.7" )
275
304
class AxesLocator :
276
305
"""
277
306
A callable object which returns the position and size of a given
@@ -299,16 +328,8 @@ def __init__(self, axes_divider, nx, ny, nx1=None, ny1=None):
299
328
self ._nx , self ._ny = nx - _xrefindex , ny - _yrefindex
300
329
301
330
if nx1 is None :
302
- _api .warn_deprecated (
303
- "3.5" , message = "Support for passing nx1=None to mean nx+1 is "
304
- "deprecated since %(since)s; in a future version, nx1=None "
305
- "will mean 'up to the last cell'." )
306
331
nx1 = nx + 1
307
332
if ny1 is None :
308
- _api .warn_deprecated (
309
- "3.5" , message = "Support for passing ny1=None to mean ny+1 is "
310
- "deprecated since %(since)s; in a future version, ny1=None "
311
- "will mean 'up to the last cell'." )
312
333
ny1 = ny + 1
313
334
314
335
self ._nx1 = nx1 - _xrefindex
@@ -416,24 +437,17 @@ def new_horizontal(self, size, pad=None, pack_start=False, **kwargs):
416
437
"""
417
438
if pad is None :
418
439
pad = mpl .rcParams ["figure.subplot.wspace" ] * self ._xref
440
+ pos = "left" if pack_start else "right"
419
441
if pad :
420
442
if not isinstance (pad , Size ._Base ):
421
443
pad = Size .from_any (pad , fraction_ref = self ._xref )
422
- if pack_start :
423
- self ._horizontal .insert (0 , pad )
424
- self ._xrefindex += 1
425
- else :
426
- self ._horizontal .append (pad )
444
+ self .append_size (pos , pad )
427
445
if not isinstance (size , Size ._Base ):
428
446
size = Size .from_any (size , fraction_ref = self ._xref )
429
- if pack_start :
430
- self ._horizontal .insert (0 , size )
431
- self ._xrefindex += 1
432
- locator = self .new_locator (nx = 0 , ny = self ._yrefindex )
433
- else :
434
- self ._horizontal .append (size )
435
- locator = self .new_locator (
436
- nx = len (self ._horizontal ) - 1 , ny = self ._yrefindex )
447
+ self .append_size (pos , size )
448
+ locator = self .new_locator (
449
+ nx = 0 if pack_start else len (self ._horizontal ) - 1 ,
450
+ ny = self ._yrefindex )
437
451
ax = self ._get_new_axes (** kwargs )
438
452
ax .set_axes_locator (locator )
439
453
return ax
@@ -448,24 +462,17 @@ def new_vertical(self, size, pad=None, pack_start=False, **kwargs):
448
462
"""
449
463
if pad is None :
450
464
pad = mpl .rcParams ["figure.subplot.hspace" ] * self ._yref
465
+ pos = "bottom" if pack_start else "top"
451
466
if pad :
452
467
if not isinstance (pad , Size ._Base ):
453
468
pad = Size .from_any (pad , fraction_ref = self ._yref )
454
- if pack_start :
455
- self ._vertical .insert (0 , pad )
456
- self ._yrefindex += 1
457
- else :
458
- self ._vertical .append (pad )
469
+ self .append_size (pos , pad )
459
470
if not isinstance (size , Size ._Base ):
460
471
size = Size .from_any (size , fraction_ref = self ._yref )
461
- if pack_start :
462
- self ._vertical .insert (0 , size )
463
- self ._yrefindex += 1
464
- locator = self .new_locator (nx = self ._xrefindex , ny = 0 )
465
- else :
466
- self ._vertical .append (size )
467
- locator = self .new_locator (
468
- nx = self ._xrefindex , ny = len (self ._vertical ) - 1 )
472
+ self .append_size (pos , size )
473
+ locator = self .new_locator (
474
+ nx = self ._xrefindex ,
475
+ ny = 0 if pack_start else len (self ._vertical ) - 1 )
469
476
ax = self ._get_new_axes (** kwargs )
470
477
ax .set_axes_locator (locator )
471
478
return ax
@@ -579,7 +586,7 @@ class HBoxDivider(SubplotDivider):
579
586
580
587
def new_locator (self , nx , nx1 = None ):
581
588
"""
582
- Create a new `.AxesLocator` for the specified cell.
589
+ Create an axes locator callable for the specified cell.
583
590
584
591
Parameters
585
592
----------
@@ -589,22 +596,18 @@ def new_locator(self, nx, nx1=None):
589
596
specified. Otherwise, location of columns spanning between *nx*
590
597
to *nx1* (but excluding *nx1*-th column) is specified.
591
598
"""
592
- return AxesLocator ( self , nx , 0 , nx1 if nx1 is not None else nx + 1 , 1 )
599
+ return super (). new_locator ( nx , 0 , nx1 , 0 )
593
600
594
- def locate (self , nx , ny , nx1 = None , ny1 = None , axes = None , renderer = None ):
601
+ def _locate (self , nx , ny , nx1 , ny1 , axes , renderer ):
595
602
# docstring inherited
603
+ nx += self ._xrefindex
604
+ nx1 += self ._xrefindex
596
605
fig_w , fig_h = self ._fig .bbox .size / self ._fig .dpi
597
606
x , y , w , h = self .get_position_runtime (axes , renderer )
598
607
summed_ws = self .get_horizontal_sizes (renderer )
599
608
equal_hs = self .get_vertical_sizes (renderer )
600
609
x0 , y0 , ox , hh = _locate (
601
610
x , y , w , h , summed_ws , equal_hs , fig_w , fig_h , self .get_anchor ())
602
- if nx1 is None :
603
- _api .warn_deprecated (
604
- "3.5" , message = "Support for passing nx1=None to mean nx+1 is "
605
- "deprecated since %(since)s; in a future version, nx1=None "
606
- "will mean 'up to the last cell'." )
607
- nx1 = nx + 1
608
611
x1 , w1 = x0 + ox [nx ] / fig_w , (ox [nx1 ] - ox [nx ]) / fig_w
609
612
y1 , h1 = y0 , hh
610
613
return mtransforms .Bbox .from_bounds (x1 , y1 , w1 , h1 )
@@ -618,7 +621,7 @@ class VBoxDivider(SubplotDivider):
618
621
619
622
def new_locator (self , ny , ny1 = None ):
620
623
"""
621
- Create a new `.AxesLocator` for the specified cell.
624
+ Create an axes locator callable for the specified cell.
622
625
623
626
Parameters
624
627
----------
@@ -628,22 +631,18 @@ def new_locator(self, ny, ny1=None):
628
631
specified. Otherwise, location of rows spanning between *ny*
629
632
to *ny1* (but excluding *ny1*-th row) is specified.
630
633
"""
631
- return AxesLocator ( self , 0 , ny , 1 , ny1 if ny1 is not None else ny + 1 )
634
+ return super (). new_locator ( 0 , ny , 0 , ny1 )
632
635
633
- def locate (self , nx , ny , nx1 = None , ny1 = None , axes = None , renderer = None ):
636
+ def _locate (self , nx , ny , nx1 , ny1 , axes , renderer ):
634
637
# docstring inherited
638
+ ny += self ._yrefindex
639
+ ny1 += self ._yrefindex
635
640
fig_w , fig_h = self ._fig .bbox .size / self ._fig .dpi
636
641
x , y , w , h = self .get_position_runtime (axes , renderer )
637
642
summed_hs = self .get_vertical_sizes (renderer )
638
643
equal_ws = self .get_horizontal_sizes (renderer )
639
644
y0 , x0 , oy , ww = _locate (
640
645
y , x , h , w , summed_hs , equal_ws , fig_h , fig_w , self .get_anchor ())
641
- if ny1 is None :
642
- _api .warn_deprecated (
643
- "3.5" , message = "Support for passing ny1=None to mean ny+1 is "
644
- "deprecated since %(since)s; in a future version, ny1=None "
645
- "will mean 'up to the last cell'." )
646
- ny1 = ny + 1
647
646
x1 , w1 = x0 , ww
648
647
y1 , h1 = y0 + oy [ny ] / fig_h , (oy [ny1 ] - oy [ny ]) / fig_h
649
648
return mtransforms .Bbox .from_bounds (x1 , y1 , w1 , h1 )
0 commit comments