ENH: Only do constrained layout at draw...#20229
Conversation
Benchmarkshttps://github.com/matplotlib/mpl-bench
master:This PR: |
|
This is inspired by #19892 where we will probably move towards making layout managers more modular.... |
|
One note - for constrained_layout, at least, the figure does need to know that it is being used before any colorbars are added so that it can use the non-gridspec colorbars. So, in general, its not possible to strip all layout manager state to draw time. However, this PR is still useful because it allows more layout manager state to be determined at draw time. |
|
I'd like to get this in so #20426 can get in for 3.5. Note this is a relatively straightforward change, despite its apparent length. The logic for creating the layout boxes that comprise constrained_layout are created at draw-time instead of when the figure and gridspecs are created. |
|
|
||
|
|
||
| def _make_layout_margins(fig, renderer, *, w_pad=0, h_pad=0, | ||
| def _make_layout_margins(_layoutgrids, fig, renderer, *, w_pad=0, h_pad=0, |
There was a problem hiding this comment.
Changes from here and below are just adding the _layoutgrids structure to all the methods....
| return _layoutgrids | ||
|
|
||
|
|
||
| def _make_layoutgrids(fig, _layoutgrids): |
There was a problem hiding this comment.
this logic was all in figure.py.
| return _layoutgrids | ||
|
|
||
|
|
||
| def _make_layoutgrids_gs(_layoutgrids, gs): |
There was a problem hiding this comment.
This logic was all in gridspecs.py
| """ | ||
| return self._parent.get_constrained_layout_pads(relative=relative) | ||
|
|
||
| def init_layoutgrid(self): |
There was a problem hiding this comment.
This was moved to _constrained_layout Not how there are no _layoutgrids attached to the figure any longer...
There was a problem hiding this comment.
Do you want to add a changelog note?
There was a problem hiding this comment.
Do we need one for private attributes?
| width_ratios=width_ratios, | ||
| height_ratios=height_ratios) | ||
|
|
||
| # set up layoutgrid for constrained_layout: |
There was a problem hiding this comment.
All moved to _constrained_layout.py and happens at draw time...
| _layoutgrids[fig] = layoutgrid.LayoutGrid( | ||
| parent=parentlb, | ||
| name=(parentlb.name + '.' + 'panellb' + | ||
| layoutgrid.seq_id()), |
There was a problem hiding this comment.
Perhaps you can have a seq_id(<prefix>) function to avoid all these string manipulations everywhere.
(possibly in a separate PR)
There was a problem hiding this comment.
Sure, I just moved it into LayoutGrid. The names were just for debug purposes to keep track of what each grid was supposed to be containing.
Benchmark with 30 draws per benchmark:master:This PR:Same benchmark, but
|
|
I'll pop this to "merge with single review". There are no API changes, and its operating on something we still nominally consider experimental. |
| return layoutgrids | ||
|
|
||
|
|
||
| def make_layoutgrids(fig, layoutgrids): |
There was a problem hiding this comment.
All the others take layoutgrids first; should this not do the same also?
There was a problem hiding this comment.
This is (usually) called first, so the layoutgrids is only if we are doing the call recursively....
5eec6c5 to
e61bf9f
Compare
|
I think you missed a couple of the alignment comments, but otherwise LGTM. |
e61bf9f to
eacda99
Compare
fixed now, thanks... |
PR Summary
This PR moves all of the state for constrained_layout out of
figureandgridspecexcept for the kwargs in figure. There are a few clear advantages.This may have a minor speed hit because all the layout boxes are made each draw, but I doubt its very significant
PR Checklist
pytestpasses).flake8on changed files to check).flake8-docstringsand runflake8 --docstring-convention=all).doc/users/next_whats_new/(follow instructions in README.rst there).doc/api/next_api_changes/(follow instructions in README.rst there).