Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 357bac5

Browse files
authored
Merge pull request #22452 from tacaswell/enh_null_layout_engine
ENH: add ability to remove layout engine
2 parents 5d3124d + 4725daa commit 357bac5

File tree

3 files changed

+69
-10
lines changed

3 files changed

+69
-10
lines changed

lib/matplotlib/figure.py

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@
3535

3636
from matplotlib.axes import Axes, SubplotBase, subplot_class_factory
3737
from matplotlib.gridspec import GridSpec
38-
from matplotlib.layout_engine import (ConstrainedLayoutEngine,
39-
TightLayoutEngine, LayoutEngine)
38+
from matplotlib.layout_engine import (
39+
ConstrainedLayoutEngine, TightLayoutEngine, LayoutEngine,
40+
PlaceHolderLayoutEngine
41+
)
4042
import matplotlib.legend as mlegend
4143
from matplotlib.patches import Rectangle
4244
from matplotlib.text import Text
@@ -2440,7 +2442,9 @@ def _check_layout_engines_compat(self, old, new):
24402442
If the figure has used the old engine and added a colorbar then the
24412443
value of colorbar_gridspec must be the same on the new engine.
24422444
"""
2443-
if old is None or old.colorbar_gridspec == new.colorbar_gridspec:
2445+
if old is None or new is None:
2446+
return True
2447+
if old.colorbar_gridspec == new.colorbar_gridspec:
24442448
return True
24452449
# colorbar layout different, so check if any colorbars are on the
24462450
# figure...
@@ -2456,15 +2460,29 @@ def set_layout_engine(self, layout=None, **kwargs):
24562460
24572461
Parameters
24582462
----------
2459-
layout: {'constrained', 'compressed', 'tight'} or `~.LayoutEngine`
2460-
'constrained' will use `~.ConstrainedLayoutEngine`,
2461-
'compressed' will also use ConstrainedLayoutEngine, but with a
2462-
correction that attempts to make a good layout for fixed-aspect
2463-
ratio Axes. 'tight' uses `~.TightLayoutEngine`. Users and
2464-
libraries can define their own layout engines as well.
2463+
layout: {'constrained', 'compressed', 'tight', 'none'} or \
2464+
`LayoutEngine` or None
2465+
2466+
- 'constrained' will use `~.ConstrainedLayoutEngine`
2467+
- 'compressed' will also use `~.ConstrainedLayoutEngine`, but with
2468+
a correction that attempts to make a good layout for fixed-aspect
2469+
ratio Axes.
2470+
- 'tight' uses `~.TightLayoutEngine`
2471+
- 'none' removes layout engine.
2472+
2473+
If `None`, the behavior is controlled by :rc:`figure.autolayout`
2474+
(which if `True` behaves as if 'tight' were passed) and
2475+
:rc:`figure.constrained_layout.use` (which if `True` behaves as if
2476+
'constrained' were passed). If both are `True`,
2477+
:rc:`figure.autolayout` takes priority.
2478+
2479+
Users and libraries can define their own layout engines and pass
2480+
the instance directly as well.
2481+
24652482
kwargs: dict
24662483
The keyword arguments are passed to the layout engine to set things
24672484
like padding and margin sizes. Only used if *layout* is a string.
2485+
24682486
"""
24692487
if layout is None:
24702488
if mpl.rcParams['figure.autolayout']:
@@ -2481,6 +2499,14 @@ def set_layout_engine(self, layout=None, **kwargs):
24812499
elif layout == 'compressed':
24822500
new_layout_engine = ConstrainedLayoutEngine(compress=True,
24832501
**kwargs)
2502+
elif layout == 'none':
2503+
if self._layout_engine is not None:
2504+
new_layout_engine = PlaceHolderLayoutEngine(
2505+
self._layout_engine.adjust_compatible,
2506+
self._layout_engine.colorbar_gridspec
2507+
)
2508+
else:
2509+
new_layout_engine = None
24842510
elif isinstance(layout, LayoutEngine):
24852511
new_layout_engine = layout
24862512
else:

lib/matplotlib/layout_engine.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,30 @@ def execute(self, fig):
100100
raise NotImplementedError
101101

102102

103+
class PlaceHolderLayoutEngine(LayoutEngine):
104+
"""
105+
This layout engine does not adjust the figure layout at all.
106+
107+
The purpose of this `.LayoutEngine` is to act as a place holder when the
108+
user removes a layout engine to ensure an incompatible `.LayoutEngine` can
109+
not be set later.
110+
111+
Parameters
112+
----------
113+
adjust_compatible, colorbar_gridspec : bool
114+
Allow the PlaceHolderLayoutEngine to mirror the behavior of whatever
115+
layout engine it is replacing.
116+
117+
"""
118+
def __init__(self, adjust_compatible, colorbar_gridspec, **kwargs):
119+
self._adjust_compatible = adjust_compatible
120+
self._colorbar_gridspec = colorbar_gridspec
121+
super().__init__(**kwargs)
122+
123+
def execute(self, fig):
124+
return
125+
126+
103127
class TightLayoutEngine(LayoutEngine):
104128
"""
105129
Implements the ``tight_layout`` geometry management. See

lib/matplotlib/tests/test_figure.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
from matplotlib.axes import Axes
1919
from matplotlib.figure import Figure, FigureBase
2020
from matplotlib.layout_engine import (ConstrainedLayoutEngine,
21-
TightLayoutEngine)
21+
TightLayoutEngine,
22+
PlaceHolderLayoutEngine)
2223
from matplotlib.ticker import AutoMinorLocator, FixedFormatter, ScalarFormatter
2324
import matplotlib.pyplot as plt
2425
import matplotlib.dates as mdates
@@ -579,6 +580,9 @@ def test_invalid_layouts():
579580
fig, ax = plt.subplots(layout="constrained")
580581
pc = ax.pcolormesh(np.random.randn(2, 2))
581582
fig.colorbar(pc)
583+
with pytest.raises(RuntimeError, match='Colorbar layout of new layout'):
584+
fig.set_layout_engine("tight")
585+
fig.set_layout_engine("none")
582586
with pytest.raises(RuntimeError, match='Colorbar layout of new layout'):
583587
fig.set_layout_engine("tight")
584588

@@ -587,6 +591,11 @@ def test_invalid_layouts():
587591
fig.colorbar(pc)
588592
with pytest.raises(RuntimeError, match='Colorbar layout of new layout'):
589593
fig.set_layout_engine("constrained")
594+
fig.set_layout_engine("none")
595+
assert isinstance(fig.get_layout_engine(), PlaceHolderLayoutEngine)
596+
597+
with pytest.raises(RuntimeError, match='Colorbar layout of new layout'):
598+
fig.set_layout_engine("constrained")
590599

591600

592601
@check_figures_equal(extensions=["png", "pdf"])

0 commit comments

Comments
 (0)