Skip to content

Commit 4541b46

Browse files
committed
Preserve multi-panel figure size in visual-test compare()
`compare()` previously forced every figure into a single 5-inch canvas with constrained layout. For multi-panel figures (e.g. scanpy-style color=[...] or multiple coordinate systems) this crammed the panels together and pushed each panel's per-axis colorbar/legend into the neighbouring panel. Only normalize size + layout for single-panel figures (count gridspec-placed axes; colorbar/legend insets have no subplotspec). Multi-panel figures keep their own size and spacing; the thumbnail is produced by the existing resize step. Single-panel baselines are unaffected; multi-panel baselines are regenerated.
1 parent 0f01e84 commit 4541b46

1 file changed

Lines changed: 19 additions & 10 deletions

File tree

tests/conftest.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -503,18 +503,27 @@ def compare(cls, basename: str, tolerance: float | None = None):
503503

504504
width, height = CANVAS_WIDTH, CANVAS_HEIGHT # base dimensions; actual PNG may grow/shrink
505505
fig = plt.gcf()
506-
fig.set_size_inches(width / DPI, height / DPI)
507-
fig.set_dpi(DPI)
508-
509-
# Try to get a reasonable layout first (helps with axes/labels)
510-
if not fig.get_constrained_layout():
511-
try:
512-
fig.set_layout_engine("constrained")
513-
except (ValueError, RuntimeError):
506+
507+
# Count the real panels (gridspec-placed axes); colorbar/legend inset axes have no
508+
# subplotspec. For single-panel figures we normalise size + layout as before. For
509+
# multi-panel figures we keep the figure's own size and spacing, otherwise forcing the
510+
# whole grid into a single-panel canvas squeezes each panel's colorbar/legend into the
511+
# neighbouring panel. The small thumbnail is produced purely by the resize step below.
512+
n_panels = sum(1 for sub_ax in fig.axes if sub_ax.get_subplotspec() is not None)
513+
514+
if n_panels <= 1:
515+
fig.set_size_inches(width / DPI, height / DPI)
516+
fig.set_dpi(DPI)
517+
518+
# Try to get a reasonable layout first (helps with axes/labels)
519+
if not fig.get_constrained_layout():
514520
try:
515-
fig.tight_layout(pad=2.0, rect=[0.02, 0.02, 0.98, 0.98])
521+
fig.set_layout_engine("constrained")
516522
except (ValueError, RuntimeError):
517-
fig.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1)
523+
try:
524+
fig.tight_layout(pad=2.0, rect=[0.02, 0.02, 0.98, 0.98])
525+
except (ValueError, RuntimeError):
526+
fig.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1)
518527

519528
plt.figure(fig.number) # ensure this figure is current
520529

0 commit comments

Comments
 (0)