Skip to content

swev-id: matplotlib__matplotlib-25960 honor subfigure spacing#68

Open
casey-brooks wants to merge 1 commit intomatplotlib__matplotlib-25960from
noa/issue-281
Open

swev-id: matplotlib__matplotlib-25960 honor subfigure spacing#68
casey-brooks wants to merge 1 commit intomatplotlib__matplotlib-25960from
noa/issue-281

Conversation

@casey-brooks
Copy link

Summary

  • implement subfigure bbox computation that honors explicit wspace/hspace in non-constrained layouts
  • add geometry-based tests covering horizontal, vertical, default, and nested spacing
  • ensure constrained layout path continues to rely on provided bboxes

Testing

  • pytest lib/matplotlib/tests/test_figure.py -k 'subfigures_wspace_spacing or subfigures_hspace_spacing or subfigures_default_spacing_none or nested_subfigures_inherit_spacing'
  • pytest lib/matplotlib/tests/test_figure.py -k 'subfigure_spanning or subfigure_tightbbox' --maxfail=1
  • flake8 lib/matplotlib/figure.py lib/matplotlib/tests/test_figure.py

Issue

Fixes #64

Reproduction Steps

  1. From matplotlib__matplotlib-25960, run pytest lib/matplotlib/tests/test_figure.py -k 'subfigures_wspace_spacing or subfigures_hspace_spacing or nested_subfigures_inherit_spacing'

Observed Failure (pre-fix)

============================= test session starts ==============================
platform linux -- Python 3.10.19, pytest-9.0.2, pluggy-1.6.0
rootdir: /workspace/matplotlib
configfile: pytest.ini
plugins: timeout-2.4.0, rerunfailures-16.1, xvfb-3.1.1, cov-7.0.0, xdist-3.8.0
collected 148 items / 144 deselected / 4 selected

lib/matplotlib/tests/test_figure.py FF.F                                 [100%]

=================================== FAILURES ===================================
________________________ test_subfigures_wspace_spacing ________________________

    def test_subfigures_wspace_spacing():
        fig = plt.figure()
        left, right = fig.subfigures(1, 2, wspace=0.2)
    
        expected_gap = 0.2 / (2 + 0.2 * (2 - 1))
        gap = right.bbox_relative.x0 - left.bbox_relative.x1
    
>       assert gap == pytest.approx(expected_gap)
E       assert 0.0 == 0.09090909090909091 ± 9.1e-08
E         
E         comparison failed
E         Obtained: 0.0
E         Expected: 0.09090909090909091 ± 9.1e-08

lib/matplotlib/tests/test_figure.py:312: AssertionError
________________________ test_subfigures_hspace_spacing ________________________

    def test_subfigures_hspace_spacing():
        fig = plt.figure()
        top, bottom = fig.subfigures(2, 1, hspace=0.3)
    
        expected_gap = 0.3 / (2 + 0.3 * (2 - 1))
        gap = top.bbox_relative.y0 - bottom.bbox_relative.y1
    
>       assert gap == pytest.approx(expected_gap)
E       assert 0.0 == 0.13043478260869565 ± 1.3e-07
E         
E         comparison failed
E         Obtained: 0.0
E         Expected: 0.13043478260869565 ± 1.3e-07

lib/matplotlib/tests/test_figure.py:324: AssertionError
____________________ test_nested_subfigures_inherit_spacing ____________________

    def test_nested_subfigures_inherit_spacing():
        fig = plt.figure()
        left, _ = fig.subfigures(1, 2, wspace=0.1)
        top, bottom = left.subfigures(2, 1, hspace=0.25)
    
        expected_gap = 0.25 / (2 + 0.25 * (2 - 1))
        gap = top.bbox_relative.y0 - bottom.bbox_relative.y1
    
>       assert gap == pytest.approx(expected_gap)
E       assert 0.0 == 0.1111111111111111 ± 1.1e-07
E         
E         comparison failed
E         Obtained: 0.0
E         Expected: 0.1111111111111111 ± 1.1e-07

lib/matplotlib/tests/test_figure.py:347: AssertionError
=========================== short test summary info ============================
FAILED lib/matplotlib/tests/test_figure.py::test_subfigures_wspace_spacing - ...
FAILED lib/matplotlib/tests/test_figure.py::test_subfigures_hspace_spacing - ...
FAILED lib/matplotlib/tests/test_figure.py::test_nested_subfigures_inherit_spacing
================= 3 failed, 1 passed, 144 deselected in 0.32s ==================

Fix

  • SubFigure now delegates spacing-aware bbox calculation to GridSpec using a dummy SubplotParams so non-constrained wspace/hspace offsets create gaps while constrained layout keeps passing explicit bboxes.
  • Added regression tests verifying non-constrained spacing works horizontally, vertically, and within nested subfigures, plus default spacing remains unchanged.

@casey-brooks casey-brooks requested a review from a team December 25, 2025 13:14
@casey-brooks
Copy link
Author

Local Validation

  • pytest lib/matplotlib/tests/test_figure.py -k 'subfigures_wspace_spacing or subfigures_hspace_spacing or subfigures_default_spacing_none or nested_subfigures_inherit_spacing' # 4 passed, 144 deselected
  • pytest lib/matplotlib/tests/test_figure.py -k 'subfigure_spanning or subfigure_tightbbox' --maxfail=1 # 2 passed, 146 deselected
  • flake8 lib/matplotlib/figure.py lib/matplotlib/tests/test_figure.py # no issues

Copy link

@noa-lucent noa-lucent left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid fix. SubFigure now reuses GridSpec spacing logic so the manual wspace/hspace gaps materialize in the non-constrained path while bboxes provided by constrained layout stay untouched. New geometry assertions cover horizontal, vertical, default, and nested scenarios. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants