Skip to content

Commit bdfaea4

Browse files
authored
ENH: Fix support for matplotlib's constrained_layout (#25261) (#39394)
1 parent b66160d commit bdfaea4

File tree

6 files changed

+49
-11
lines changed

6 files changed

+49
-11
lines changed

doc/source/whatsnew/v1.3.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ Plotting
386386
^^^^^^^^
387387

388388
- Bug in :func:`scatter_matrix` raising when 2d ``ax`` argument passed (:issue:`16253`)
389-
-
389+
- Prevent warnings when matplotlib's ``constrained_layout`` is enabled (:issue:`25261`)
390390
-
391391

392392
Groupby/resample/rolling

pandas/plotting/_matplotlib/boxplot.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@
1616
from pandas.io.formats.printing import pprint_thing
1717
from pandas.plotting._matplotlib.core import LinePlot, MPLPlot
1818
from pandas.plotting._matplotlib.style import get_standard_colors
19-
from pandas.plotting._matplotlib.tools import create_subplots, flatten_axes
19+
from pandas.plotting._matplotlib.tools import (
20+
create_subplots,
21+
flatten_axes,
22+
maybe_adjust_figure,
23+
)
2024

2125
if TYPE_CHECKING:
2226
from matplotlib.axes import Axes
@@ -229,7 +233,7 @@ def _grouped_plot_by_column(
229233

230234
byline = by[0] if len(by) == 1 else by
231235
fig.suptitle(f"Boxplot grouped by {byline}")
232-
fig.subplots_adjust(bottom=0.15, top=0.9, left=0.1, right=0.9, wspace=0.2)
236+
maybe_adjust_figure(fig, bottom=0.15, top=0.9, left=0.1, right=0.9, wspace=0.2)
233237

234238
return result
235239

@@ -436,7 +440,7 @@ def boxplot_frame_groupby(
436440
)
437441
ax.set_title(pprint_thing(key))
438442
ret.loc[key] = d
439-
fig.subplots_adjust(bottom=0.15, top=0.9, left=0.1, right=0.9, wspace=0.2)
443+
maybe_adjust_figure(fig, bottom=0.15, top=0.9, left=0.1, right=0.9, wspace=0.2)
440444
else:
441445
keys, frames = zip(*grouped)
442446
if grouped.axis == 0:

pandas/plotting/_matplotlib/hist.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from pandas.plotting._matplotlib.tools import (
1414
create_subplots,
1515
flatten_axes,
16+
maybe_adjust_figure,
1617
set_ticks_props,
1718
)
1819

@@ -296,8 +297,8 @@ def plot_group(group, ax):
296297
axes, xlabelsize=xlabelsize, xrot=xrot, ylabelsize=ylabelsize, yrot=yrot
297298
)
298299

299-
fig.subplots_adjust(
300-
bottom=0.15, top=0.9, left=0.1, right=0.9, hspace=0.5, wspace=0.3
300+
maybe_adjust_figure(
301+
fig, bottom=0.15, top=0.9, left=0.1, right=0.9, hspace=0.5, wspace=0.3
301302
)
302303
return axes
303304

@@ -456,6 +457,6 @@ def hist_frame(
456457
set_ticks_props(
457458
axes, xlabelsize=xlabelsize, xrot=xrot, ylabelsize=ylabelsize, yrot=yrot
458459
)
459-
fig.subplots_adjust(wspace=0.3, hspace=0.3)
460+
maybe_adjust_figure(fig, wspace=0.3, hspace=0.3)
460461

461462
return axes

pandas/plotting/_matplotlib/misc.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@
1111

1212
from pandas.io.formats.printing import pprint_thing
1313
from pandas.plotting._matplotlib.style import get_standard_colors
14-
from pandas.plotting._matplotlib.tools import create_subplots, set_ticks_props
14+
from pandas.plotting._matplotlib.tools import (
15+
create_subplots,
16+
do_adjust_figure,
17+
maybe_adjust_figure,
18+
set_ticks_props,
19+
)
1520

1621
if TYPE_CHECKING:
1722
from matplotlib.axes import Axes
@@ -39,7 +44,7 @@ def scatter_matrix(
3944
fig, axes = create_subplots(naxes=naxes, figsize=figsize, ax=ax, squeeze=False)
4045

4146
# no gaps between subplots
42-
fig.subplots_adjust(wspace=0, hspace=0)
47+
maybe_adjust_figure(fig, wspace=0, hspace=0)
4348

4449
mask = notna(df)
4550

@@ -329,7 +334,8 @@ def bootstrap_plot(
329334
for axis in axes:
330335
plt.setp(axis.get_xticklabels(), fontsize=8)
331336
plt.setp(axis.get_yticklabels(), fontsize=8)
332-
plt.tight_layout()
337+
if do_adjust_figure(fig):
338+
plt.tight_layout()
333339
return fig
334340

335341

pandas/plotting/_matplotlib/tools.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,31 @@
1919
if TYPE_CHECKING:
2020
from matplotlib.axes import Axes
2121
from matplotlib.axis import Axis
22+
from matplotlib.figure import Figure
2223
from matplotlib.lines import Line2D
2324
from matplotlib.table import Table
2425

2526

27+
def do_adjust_figure(fig: Figure):
28+
"""Whether fig has constrained_layout enabled."""
29+
if not hasattr(fig, "get_constrained_layout"):
30+
return False
31+
return not fig.get_constrained_layout()
32+
33+
34+
def maybe_adjust_figure(fig: Figure, *args, **kwargs):
35+
"""Call fig.subplots_adjust unless fig has constrained_layout enabled."""
36+
if do_adjust_figure(fig):
37+
fig.subplots_adjust(*args, **kwargs)
38+
39+
2640
def format_date_labels(ax: Axes, rot):
2741
# mini version of autofmt_xdate
2842
for label in ax.get_xticklabels():
2943
label.set_ha("right")
3044
label.set_rotation(rot)
3145
fig = ax.get_figure()
32-
fig.subplots_adjust(bottom=0.2)
46+
maybe_adjust_figure(fig, bottom=0.2)
3347

3448

3549
def table(

pandas/tests/plotting/frame/test_frame_subplots.py

+13
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,19 @@ def test_subplots_sharex_false(self):
482482
tm.assert_numpy_array_equal(axs[0].get_xticks(), expected_ax1)
483483
tm.assert_numpy_array_equal(axs[1].get_xticks(), expected_ax2)
484484

485+
def test_subplots_constrained_layout(self):
486+
# GH 25261
487+
idx = date_range(start="now", periods=10)
488+
df = DataFrame(np.random.rand(10, 3), index=idx)
489+
kwargs = {}
490+
if hasattr(self.plt.Figure, "get_constrained_layout"):
491+
kwargs["constrained_layout"] = True
492+
fig, axes = self.plt.subplots(2, **kwargs)
493+
with tm.assert_produces_warning(None):
494+
df.plot(ax=axes[0])
495+
with tm.ensure_clean(return_filelike=True) as path:
496+
self.plt.savefig(path)
497+
485498
@pytest.mark.parametrize(
486499
"index_name, old_label, new_label",
487500
[

0 commit comments

Comments
 (0)