diff --git a/lib/matplotlib/_constrained_layout.py b/lib/matplotlib/_constrained_layout.py index f5f23581bd9d..ca62bed3e107 100644 --- a/lib/matplotlib/_constrained_layout.py +++ b/lib/matplotlib/_constrained_layout.py @@ -538,14 +538,10 @@ def match_submerged_margins(layoutgrids, fig): # interior columns: if len(ss1.colspan) > 1: - maxsubl = np.max( - lg1.margin_vals['left'][ss1.colspan[1:]] + - lg1.margin_vals['leftcb'][ss1.colspan[1:]] - ) - maxsubr = np.max( - lg1.margin_vals['right'][ss1.colspan[:-1]] + - lg1.margin_vals['rightcb'][ss1.colspan[:-1]] - ) + leftcb = lg1.margin_vals['leftcb'][ss1.colspan[1:]] + rightcb = lg1.margin_vals['rightcb'][ss1.colspan[:-1]] + maxsubl = np.max(lg1.margin_vals['left'][ss1.colspan[1:]] + leftcb) + maxsubr = np.max(lg1.margin_vals['right'][ss1.colspan[:-1]] + rightcb) for ax2 in axs: ss2 = ax2.get_subplotspec() lg2 = layoutgrids[ss2.get_gridspec()] @@ -560,22 +556,17 @@ def match_submerged_margins(layoutgrids, fig): lg2.margin_vals['rightcb'][ss2.colspan[:-1]]) if maxsubr2 > maxsubr: maxsubr = maxsubr2 - for i in ss1.colspan[1:]: - lg1.edit_margin_min('left', maxsubl, cell=i) - for i in ss1.colspan[:-1]: - lg1.edit_margin_min('right', maxsubr, cell=i) + for i, cb in zip(ss1.colspan[1:], leftcb): + lg1.edit_margin_min('left', maxsubl - cb, cell=i) + for i, cb in zip(ss1.colspan[:-1], rightcb): + lg1.edit_margin_min('right', maxsubr - cb, cell=i) # interior rows: if len(ss1.rowspan) > 1: - maxsubt = np.max( - lg1.margin_vals['top'][ss1.rowspan[1:]] + - lg1.margin_vals['topcb'][ss1.rowspan[1:]] - ) - maxsubb = np.max( - lg1.margin_vals['bottom'][ss1.rowspan[:-1]] + - lg1.margin_vals['bottomcb'][ss1.rowspan[:-1]] - ) - + topcb = lg1.margin_vals['topcb'][ss1.rowspan[1:]] + bottomcb = lg1.margin_vals['bottomcb'][ss1.rowspan[:-1]] + maxsubt = np.max(lg1.margin_vals['top'][ss1.rowspan[1:]] + topcb) + maxsubb = np.max(lg1.margin_vals['bottom'][ss1.rowspan[:-1]] + bottomcb) for ax2 in axs: ss2 = ax2.get_subplotspec() lg2 = layoutgrids[ss2.get_gridspec()] @@ -589,10 +580,10 @@ def match_submerged_margins(layoutgrids, fig): lg2.margin_vals['bottom'][ss2.rowspan[:-1]] + lg2.margin_vals['bottomcb'][ss2.rowspan[:-1]] ), maxsubb]) - for i in ss1.rowspan[1:]: - lg1.edit_margin_min('top', maxsubt, cell=i) - for i in ss1.rowspan[:-1]: - lg1.edit_margin_min('bottom', maxsubb, cell=i) + for i, cb in zip(ss1.rowspan[1:], topcb): + lg1.edit_margin_min('top', maxsubt - cb, cell=i) + for i, cb in zip(ss1.rowspan[:-1], bottomcb): + lg1.edit_margin_min('bottom', maxsubb - cb, cell=i) return axs diff --git a/lib/matplotlib/tests/baseline_images/test_constrainedlayout/constrained_layout12.png b/lib/matplotlib/tests/baseline_images/test_constrainedlayout/constrained_layout12.png index 6f5625ae2605..b4565e4c5c18 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_constrainedlayout/constrained_layout12.png and b/lib/matplotlib/tests/baseline_images/test_constrainedlayout/constrained_layout12.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_constrainedlayout/constrained_layout17.png b/lib/matplotlib/tests/baseline_images/test_constrainedlayout/constrained_layout17.png index 7ac78631798e..1b801d37ac98 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_constrainedlayout/constrained_layout17.png and b/lib/matplotlib/tests/baseline_images/test_constrainedlayout/constrained_layout17.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_constrainedlayout/constrained_layout8.png b/lib/matplotlib/tests/baseline_images/test_constrainedlayout/constrained_layout8.png index 99ba9f294a7a..5bcd4248fe2e 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_constrainedlayout/constrained_layout8.png and b/lib/matplotlib/tests/baseline_images/test_constrainedlayout/constrained_layout8.png differ diff --git a/lib/matplotlib/tests/test_constrainedlayout.py b/lib/matplotlib/tests/test_constrainedlayout.py index df2dbd6f43bd..20260f431cd3 100644 --- a/lib/matplotlib/tests/test_constrainedlayout.py +++ b/lib/matplotlib/tests/test_constrainedlayout.py @@ -741,3 +741,37 @@ def test_submerged_subfig(): for ax in axs[1:]: assert np.allclose(ax.get_position().bounds[-1], axs[0].get_position().bounds[-1], atol=1e-6) + + +def test_submerged_height_gap(): + """Test that the gap between rows does not depend on the number of columns.""" + + mosaic1 = "AC;BC" + mosaic2 = "ACDE;BCDE" + + fig1, ax_dir1 = plt.subplot_mosaic(mosaic1, layout='constrained') + fig2, ax_dir2 = plt.subplot_mosaic(mosaic2, layout='constrained') + for fig in fig1, fig2: + fig.get_layout_engine().set(h_pad=0.2) + fig.draw_without_rendering() + + for label in 'A', 'B': + np.testing.assert_allclose(ax_dir1[label].get_position().bounds[-1], + ax_dir2[label].get_position().bounds[-1]) + + +def test_submerged_width_gap(): + """Test that the gap between columns does not depend on the number of rows.""" + + mosaic1 = "AB;CC" + mosaic2 = "AB;CC;DD" + + fig1, ax_dir1 = plt.subplot_mosaic(mosaic1, layout='constrained') + fig2, ax_dir2 = plt.subplot_mosaic(mosaic2, layout='constrained') + for fig in fig1, fig2: + fig.get_layout_engine().set(w_pad=0.2) + fig.draw_without_rendering() + + for label in 'A', 'B': + np.testing.assert_allclose(ax_dir1[label].get_position().bounds[-2], + ax_dir2[label].get_position().bounds[-2])