8000 Merge pull request #24312 from anntzer/ual · matplotlib/matplotlib@c176b86 · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c176b86

Browse files
authored
Merge pull request #24312 from anntzer/ual
Deprecate axes_divider.AxesLocator.
2 parents 4dce4a7 + d03c325 commit c176b86

File tree

4 files changed

+102
-56
lines changed

4 files changed

+102
-56
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
``axes_grid1.axes_divider`` API changes
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
The ``AxesLocator`` class is deprecated. The ``new_locator`` method of divider
5+
instances now instead returns an opaque callable (which can still be passed to
6+
``ax.set_axes_locator``).
7+
8+
``Divider.locate`` is deprecated; use ``Divider.new_locator(...)(ax, renderer)``
9+
instead.

galleries/users_explain/toolkits/axes_grid.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@
302302
horiz = [...] # Some other horizontal constraints.
303303
divider = Divider(fig, rect, horiz, vert)
304304
305-
then use `.Divider.new_locator` to create an `.AxesLocator` instance for a
305+
then use `.Divider.new_locator` to create an axes locator callable for a
306306
given grid entry::
307307
308308
locator = divider.new_locator(nx=0, ny=1) # Grid entry (1, 0).
@@ -311,7 +311,7 @@
311311
312312
ax.set_axes_locator(locator)
313313
314-
The `.AxesLocator` is a callable object that returns the location and size of
314+
The axes locator callable returns the location and size of
315315
the cell at the first column and the second row.
316316
317317
Locators that spans over multiple cells can be created with, e.g.::

lib/mpl_toolkits/axes_grid1/axes_divider.py

Lines changed: 83 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
Helper classes to adjust the positions of multiple axes at drawing time.
33
"""
44

5+
import functools
6+
57
import numpy as np
68

79
import 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")
267309
class 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)

lib/mpl_toolkits/axes_grid1/tests/test_axes_grid1.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -608,9 +608,14 @@ def test_grid_axes_position(direction):
608608
fig = plt.figure()
609609
grid = Grid(fig, 111, (2, 2), direction=direction)
610610
loc = [ax.get_axes_locator() for ax in np.ravel(grid.axes_row)]
611-
assert loc[1]._nx > loc[0]._nx and loc[2]._ny < loc[0]._ny
612-
assert loc[0]._nx == loc[2]._nx and loc[0]._ny == loc[1]._ny
613-
assert loc[3]._nx == loc[1]._nx and loc[3]._ny == loc[2]._ny
611+
# Test nx.
612+
assert loc[1].args[0] > loc[0].args[0]
613+
assert loc[0].args[0] == loc[2].args[0]
614+
assert loc[3].args[0] == loc[1].args[0]
615+
# Test ny.
616+
assert loc[2].args[1] < loc[0].args[1]
617+
assert loc[0].args[1] == loc[1].args[1]
618+
assert loc[3].args[1] == loc[2].args[1]
614619

615620

616621
@pytest.mark.parametrize('rect, ngrids, error, message', (

0 commit comments

Comments
 (0)
0