Skip to content

Commit c7ad89d

Browse files
committed
MNT: revert _constrained_layout_changes
1 parent e420451 commit c7ad89d

File tree

3 files changed

+60
-57
lines changed

3 files changed

+60
-57
lines changed

doc/api/next_api_changes/behavior/22745-JMK.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ No need to specify renderer for get_tightbbox and get_window_extent
33

44
The ``get_tightbbox`` and `~.Artist.get_window_extent` methods
55
no longer require the *renderer* kwarg, saving users from having to
6-
querry it from ``fig.canvas.get_renderer``. Currently, all Artists are
7-
aware of their parent figure (``artist.figure``), and if the *renderer*
6+
querry it from ``fig.canvas.get_renderer``. If the *renderer*
87
kwarg is not supplied these methods first check if there is a cached renderer
98
from a previous draw and use that. If there is no cahched renderer, then
109
the methods will use ``fig.canvas.get_renderer()`` as a fallback.

lib/matplotlib/_constrained_layout.py

Lines changed: 58 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,40 @@
1111
layout. Axes manually placed via ``figure.add_axes()`` will not.
1212
1313
See Tutorial: :doc:`/tutorials/intermediate/constrainedlayout_guide`
14+
15+
General idea:
16+
-------------
17+
18+
First, a figure has a gridspec that divides the figure into nrows and ncols,
19+
with heights and widths set by ``height_ratios`` and ``width_ratios``,
20+
often just set to 1 for an equal grid.
21+
22+
Subplotspecs that are derived from this gridspec can contain either a
23+
``SubPanel``, a ``GridSpecFromSubplotSpec``, or an ``Axes``. The ``SubPanel``
24+
and ``GridSpecFromSubplotSpec`` are dealt with recursively and each contain an
25+
analogous layout.
26+
27+
Each ``GridSpec`` has a ``_layoutgrid`` attached to it. The ``_layoutgrid``
28+
has the same logical layout as the ``GridSpec``. Each row of the grid spec
29+
has a top and bottom "margin" and each column has a left and right "margin".
30+
The "inner" height of each row is constrained to be the same (or as modified
31+
by ``height_ratio``), and the "inner" width of each column is
32+
constrained to be the same (as modified by ``width_ratio``), where "inner"
33+
is the width or height of each column/row minus the size of the margins.
34+
35+
Then the size of the margins for each row and column are determined as the
36+
max width of the decorators on each axes that has decorators in that margin.
37+
For instance, a normal axes would have a left margin that includes the
38+
left ticklabels, and the ylabel if it exists. The right margin may include a
39+
colorbar, the bottom margin the xaxis decorations, and the top margin the
40+
title.
41+
42+
With these constraints, the solver then finds appropriate bounds for the
43+
columns and rows. It's possible that the margins take up the whole figure,
44+
in which case the algorithm is not applied and a warning is raised.
45+
46+
See the tutorial doc:`/tutorials/intermediate/constrainedlayout_guide`
47+
for more discussion of the algorithm with examples.
1448
"""
1549

1650
import logging
@@ -22,40 +56,6 @@
2256
import matplotlib._layoutgrid as mlayoutgrid
2357

2458

25-
# General idea:
26-
# -------------
27-
#
28-
# First, a figure has a gridspec that divides the figure into nrows and ncols,
29-
# with heights and widths set by ``height_ratios`` and ``width_ratios``,
30-
# often just set to 1 for an equal grid.
31-
#
32-
# Subplotspecs that are derived from this gridspec can contain either a
33-
# ``SubPanel``, a ``GridSpecFromSubplotSpec``, or an ``Axes``. The
34-
# ``SubPanel`` and ``GridSpecFromSubplotSpec`` are dealt with recursively and
35-
# each contain an analogous layout.
36-
#
37-
# Each ``GridSpec`` has a ``_layoutgrid`` attached to it. The ``_layoutgrid``
38-
# has the same logical layout as the ``GridSpec``. Each row of the grid spec
39-
# has a top and bottom "margin" and each column has a left and right "margin".
40-
# The "inner" height of each row is constrained to be the same (or as modified
41-
# by ``height_ratio``), and the "inner" width of each column is
42-
# constrained to be the same (as modified by ``width_ratio``), where "inner"
43-
# is the width or height of each column/row minus the size of the margins.
44-
#
45-
# Then the size of the margins for each row and column are determined as the
46-
# max width of the decorators on each axes that has decorators in that margin.
47-
# For instance, a normal axes would have a left margin that includes the
48-
# left ticklabels, and the ylabel if it exists. The right margin may include a
49-
# colorbar, the bottom margin the xaxis decorations, and the top margin the
50-
# title.
51-
#
52-
# With these constraints, the solver then finds appropriate bounds for the
53-
# columns and rows. It's possible that the margins take up the whole figure,
54-
# in which case the algorithm is not applied and a warning is raised.
55-
#
56-
# See the tutorial doc:`/tutorials/intermediate/constrainedlayout_guide`
57-
# for more discussion of the algorithm with examples.
58-
5959
_log = logging.getLogger(__name__)
6060

6161

@@ -71,6 +71,8 @@ def do_constrained_layout(fig, h_pad, w_pad,
7171
fig : Figure
7272
``Figure`` instance to do the layout in.
7373
74+
renderer : Renderer
75+
Renderer to use.
7476
7577
h_pad, w_pad : float
7678
Padding around the axes elements in figure-normalized units.
@@ -91,6 +93,7 @@ def do_constrained_layout(fig, h_pad, w_pad,
9193
layoutgrid : private debugging structure
9294
"""
9395

96+
renderer = fig._get_renderer()
9497
# make layoutgrid tree...
9598
layoutgrids = make_layoutgrids(fig, None, rect=rect)
9699
if not layoutgrids['hasgrids']:
@@ -107,9 +110,9 @@ def do_constrained_layout(fig, h_pad, w_pad,
107110

108111
# make margins for all the axes and subfigures in the
109112
# figure. Add margins for colorbars...
110-
make_layout_margins(layoutgrids, fig, h_pad=h_pad,
113+
make_layout_margins(layoutgrids, fig, renderer, h_pad=h_pad,
111114
w_pad=w_pad, hspace=hspace, wspace=wspace)
112-
make_margin_suptitles(layoutgrids, fig, h_pad=h_pad,
115+
make_margin_suptitles(layoutgrids, fig, renderer, h_pad=h_pad,
113116
w_pad=w_pad)
114117

115118
# if a layout is such that a columns (or rows) margin has no
@@ -121,7 +124,7 @@ def do_constrained_layout(fig, h_pad, w_pad,
121124
layoutgrids[fig].update_variables()
122125

123126
if check_no_collapsed_axes(layoutgrids, fig):
124-
reposition_axes(layoutgrids, fig, h_pad=h_pad,
127+
reposition_axes(layoutgrids, fig, renderer, h_pad=h_pad,
125128
w_pad=w_pad, hspace=hspace, wspace=wspace)
126129
else:
127130
_api.warn_external('constrained_layout not applied because '
@@ -282,7 +285,7 @@ def get_margin_from_padding(obj, *, w_pad=0, h_pad=0,
282285
return margin
283286

284287

285-
def make_layout_margins(layoutgrids, fig, *, w_pad=0, h_pad=0,
288+
def make_layout_margins(layoutgrids, fig, renderer, *, w_pad=0, h_pad=0,
286289
hspace=0, wspace=0):
287290
"""
288291
For each axes, make a margin between the *pos* layoutbox and the
@@ -293,7 +296,7 @@ def make_layout_margins(layoutgrids, fig, *, w_pad=0, h_pad=0,
293296
"""
294297
for sfig in fig.subfigs: # recursively make child panel margins
295298
ss = sfig._subplotspec
296-
make_layout_margins(layoutgrids, sfig,
299+
make_layout_margins(layoutgrids, sfig, renderer,
297300
w_pad=w_pad, h_pad=h_pad,
298301
hspace=hspace, wspace=wspace)
299302

@@ -313,7 +316,7 @@ def make_layout_margins(layoutgrids, fig, *, w_pad=0, h_pad=0,
313316

314317
margin = get_margin_from_padding(ax, w_pad=w_pad, h_pad=h_pad,
315318
hspace=hspace, wspace=wspace)
316-
pos, bbox = get_pos_and_bbox(ax)
319+
pos, bbox = get_pos_and_bbox(ax, renderer)
317320
# the margin is the distance between the bounding box of the axes
318321
# and its position (plus the padding from above)
319322
margin['left'] += pos.x0 - bbox.x0
@@ -330,7 +333,7 @@ def make_layout_margins(layoutgrids, fig, *, w_pad=0, h_pad=0,
330333
# colorbars can be child of more than one subplot spec:
331334
cbp_rspan, cbp_cspan = get_cb_parent_spans(cbax)
332335
loc = cbax._colorbar_info['location']
333-
cbpos, cbbbox = get_pos_and_bbox(cbax)
336+
cbpos, cbbbox = get_pos_and_bbox(cbax, renderer)
334337
if loc == 'right':
335338
if cbp_cspan.stop == ss.colspan.stop:
336339
# only increase if the colorbar is on the right edge
@@ -366,7 +369,7 @@ def make_layout_margins(layoutgrids, fig, *, w_pad=0, h_pad=0,
366369
layoutgrids[gs].edit_outer_margin_mins(margin, ss)
367370

368371

369-
def make_margin_suptitles(layoutgrids, fig, *, w_pad=0, h_pad=0):
372+
def make_margin_suptitles(layoutgrids, fig, renderer, *, w_pad=0, h_pad=0):
370373
# Figure out how large the suptitle is and make the
371374
# top level figure margin larger.
372375

@@ -379,29 +382,29 @@ def make_margin_suptitles(layoutgrids, fig, *, w_pad=0, h_pad=0):
379382
w_pad_local = padbox.width
380383

381384
for sfig in fig.subfigs:
382-
make_margin_suptitles(layoutgrids, sfig,
385+
make_margin_suptitles(layoutgrids, sfig, renderer,
383386
w_pad=w_pad, h_pad=h_pad)
384387

385388
if fig._suptitle is not None and fig._suptitle.get_in_layout():
386389
p = fig._suptitle.get_position()
387390
if getattr(fig._suptitle, '_autopos', False):
388391
fig._suptitle.set_position((p[0], 1 - h_pad_local))
389-
bbox = inv_trans_fig(fig._suptitle.get_tightbbox())
392+
bbox = inv_trans_fig(fig._suptitle.get_tightbbox(renderer))
390393
layoutgrids[fig].edit_margin_min('top', bbox.height + 2 * h_pad)
391394

392395
if fig._supxlabel is not None and fig._supxlabel.get_in_layout():
393396
p = fig._supxlabel.get_position()
394397
if getattr(fig._supxlabel, '_autopos', False):
395398
fig._supxlabel.set_position((p[0], h_pad_local))
396-
bbox = inv_trans_fig(fig._supxlabel.get_tightbbox())
399+
bbox = inv_trans_fig(fig._supxlabel.get_tightbbox(renderer))
397400
layoutgrids[fig].edit_margin_min('bottom',
398401
bbox.height + 2 * h_pad)
399402

400403
if fig._supylabel is not None and fig._supylabel.get_in_layout():
401404
p = fig._supylabel.get_position()
402405
if getattr(fig._supylabel, '_autopos', False):
403406
fig._supylabel.set_position((w_pad_local, p[1]))
404-
bbox = inv_trans_fig(fig._supylabel.get_tightbbox())
407+
bbox = inv_trans_fig(fig._supylabel.get_tightbbox(renderer))
405408
layoutgrids[fig].edit_margin_min('left', bbox.width + 2 * w_pad)
406409

407410

@@ -522,14 +525,14 @@ def get_cb_parent_spans(cbax):
522525
return rowspan, colspan
523526

524527

525-
def get_pos_and_bbox(ax):
528+
def get_pos_and_bbox(ax, renderer):
526529
"""
527530
Get the position and the bbox for the axes.
528531
529532
Parameters
530533
----------
531534
ax
532-
535+
renderer
533536
534537
Returns
535538
-------
@@ -542,15 +545,15 @@ def get_pos_and_bbox(ax):
542545
pos = ax.get_position(original=True)
543546
# pos is in panel co-ords, but we need in figure for the layout
544547
pos = pos.transformed(fig.transSubfigure - fig.transFigure)
545-
tightbbox = martist._get_tightbbox_for_layout_only(ax)
548+
tightbbox = martist._get_tightbbox_for_layout_only(ax, renderer)
546549
if tightbbox is None:
547550
bbox = pos
548551
else:
549552
bbox = tightbbox.transformed(fig.transFigure.inverted())
550553
return pos, bbox
551554

552555

553-
def reposition_axes(layoutgrids, fig, *,
556+
def reposition_axes(layoutgrids, fig, renderer, *,
554557
w_pad=0, h_pad=0, hspace=0, wspace=0):
555558
"""
556559
Reposition all the axes based on the new inner bounding box.
@@ -560,7 +563,7 @@ def reposition_axes(layoutgrids, fig, *,
560563
bbox = layoutgrids[sfig].get_outer_bbox()
561564
sfig._redo_transform_rel_fig(
562565
bbox=bbox.transformed(trans_fig_to_subfig))
563-
reposition_axes(layoutgrids, sfig,
566+
reposition_axes(layoutgrids, sfig, renderer,
564567
w_pad=w_pad, h_pad=h_pad,
565568
wspace=wspace, hspace=hspace)
566569

@@ -588,11 +591,11 @@ def reposition_axes(layoutgrids, fig, *,
588591
offset = {'left': 0, 'right': 0, 'bottom': 0, 'top': 0}
589592
for nn, cbax in enumerate(ax._colorbars[::-1]):
590593
if ax == cbax._colorbar_info['parents'][0]:
591-
reposition_colorbar(layoutgrids, cbax,
594+
reposition_colorbar(layoutgrids, cbax, renderer,
592595
offset=offset)
593596

594597

595-
def reposition_colorbar(layoutgrids, cbax, *, offset=None):
598+
def reposition_colorbar(layoutgrids, cbax, renderer, *, offset=None):
596599
"""
597600
Place the colorbar in its new place.
598601
@@ -601,6 +604,7 @@ def reposition_colorbar(layoutgrids, cbax, *, offset=None):
601604
cbax : Axes
602605
Axes for the colorbar
603606
607+
renderer :
604608
w_pad, h_pad : float
605609
width and height padding (in fraction of figure)
606610
hspace, wspace : float
@@ -627,7 +631,7 @@ def reposition_colorbar(layoutgrids, cbax, *, offset=None):
627631
aspect = cbax._colorbar_info['aspect']
628632
shrink = cbax._colorbar_info['shrink']
629633

630-
cbpos, cbbbox = get_pos_and_bbox(cbax)
634+
cbpos, cbbbox = get_pos_and_bbox(cbax, renderer)
631635

632636
# Colorbar gets put at extreme edge of outer bbox of the subplotspec
633637
# It needs to be moved in by: 1) a pad 2) its "margin" 3) by

lib/matplotlib/_tight_layout.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ def get_subplotspec_list(axes_list, grid_spec=None):
232232
return subplotspec_list
233233

234234

235-
def get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer=None,
235+
def get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer,
236236
pad=1.08, h_pad=None, w_pad=None, rect=None):
237237
"""
238238
Return subplot parameters for tight-layouted-figure with specified padding.

0 commit comments

Comments
 (0)