Skip to content

Commit e0bb291

Browse files
committed
ENH: check if colorbar added
1 parent 28621ee commit e0bb291

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

lib/matplotlib/figure.py

+28-4
Original file line numberDiff line numberDiff line change
@@ -2336,6 +2336,23 @@ def __init__(self,
23362336
# list of child gridspecs for this figure
23372337
self._gridspecs = []
23382338

2339+
def _check_layout_engines_compat(self, old, new):
2340+
"""
2341+
Helper for set_layout engine
2342+
2343+
If the figure has used the old engine and added a colorbar then the
2344+
value of colorbar_gridspec must be the same on the new engine.
2345+
"""
2346+
if old is None or old.colorbar_gridspec == new.colorbar_gridspec:
2347+
return True
2348+
# colorbar layout different, so check if any colorbars are on the
2349+
# figure...
2350+
for ax in self.axes:
2351+
if hasattr(ax, '_colorbar'):
2352+
# colorbars list themselvs as a colorbar.
2353+
return False
2354+
return True
2355+
23392356
def set_layout_engine(self, layout=None, **kwargs):
23402357
"""
23412358
Set the layout engine for this figure.
@@ -2359,14 +2376,21 @@ def set_layout_engine(self, layout=None, **kwargs):
23592376
self._layout_engine = None
23602377
return
23612378
if layout == 'tight':
2362-
self._layout_engine = TightLayoutEngine(**kwargs)
2379+
new_layout_engine = TightLayoutEngine(**kwargs)
23632380
elif layout == 'constrained':
2364-
self._layout_engine = ConstrainedLayoutEngine(**kwargs)
2381+
new_layout_engine = ConstrainedLayoutEngine(**kwargs)
23652382
elif isinstance(layout, LayoutEngine):
2366-
self._layout_engine = layout
2383+
new_layout_engine = layout
23672384
else:
23682385
raise ValueError(f"Invalid value for 'layout': {layout!r}")
2369-
self._layout_engine.set_figure(self)
2386+
2387+
if self._check_layout_engines_compat(self._layout_engine,
2388+
new_layout_engine):
2389+
self._layout_engine = new_layout_engine
2390+
else:
2391+
_api.warn_external('Colorbar layout of new layout engine not '
2392+
'compatible with old engine, and a colorbar '
2393+
'has been created. Engine not changed.')
23702394

23712395
def get_layout_engine(self):
23722396
return self._layout_engine

lib/matplotlib/tests/test_figure.py

+24
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,30 @@ def test_invalid_layouts():
598598
match="Invalid value for 'layout'"):
599599
Figure(layout='foobar')
600600

601+
# test that layouts can be swapped if no colorbar:
602+
fig, ax = plt.subplots(layout="constrained")
603+
fig.set_layout_engine("tight")
604+
assert isinstance(fig.get_layout_engine(), TightLayoutEngine)
605+
fig.set_layout_engine("constrained")
606+
assert isinstance(fig.get_layout_engine(), ConstrainedLayoutEngine)
607+
608+
# test that layouts cannot be swapped if there is a colorbar:
609+
fig, ax = plt.subplots(layout="constrained")
610+
pc = ax.pcolormesh(np.random.randn(2, 2))
611+
fig.colorbar(pc)
612+
with pytest.warns(UserWarning, match='Colorbar layout of new layout'):
613+
fig.set_layout_engine("tight")
614+
# check that engine didn't change
615+
assert isinstance(fig.get_layout_engine(), ConstrainedLayoutEngine)
616+
617+
fig, ax = plt.subplots(layout="tight")
618+
pc = ax.pcolormesh(np.random.randn(2, 2))
619+
fig.colorbar(pc)
620+
with pytest.warns(UserWarning, match='Colorbar layout of new layout'):
621+
fig.set_layout_engine("constrained")
622+
# check that engine didn't change
623+
assert isinstance(fig.get_layout_engine(), TightLayoutEngine)
624+
601625

602626
@check_figures_equal(extensions=["png", "pdf"])
603627
def test_add_artist(fig_test, fig_ref):

0 commit comments

Comments
 (0)