Skip to content

Fix StackVertical._fix_limits to reliably push joined subplot tick labels inside frame edges#74

Merged
gb119 merged 2 commits intomainfrom
copilot/fix-stackvertical-axes-limits
Mar 11, 2026
Merged

Fix StackVertical._fix_limits to reliably push joined subplot tick labels inside frame edges#74
gb119 merged 2 commits intomainfrom
copilot/fix-stackvertical-axes-limits

Conversation

Copy link
Contributor

Copilot AI commented Mar 11, 2026

StackVertical._fix_limits is supposed to expand y-axis limits so tick labels never bleed across the shared frame line into an adjacent panel, but it had three bugs that made the adjustment unreliable or entirely inoperative.

Bugs fixed

  • Reversed condition for upper-limit checkyticks[-2] < 1.0 - dy should be >. The top-edge adjustment almost never fired, leaving tick labels on the upper edges of middle/bottom subplots free to overflow into the panel above.

  • Fragile heuristic tick indexingyticks[1] / yticks[-2] assumed the auto-locator always places outermost ticks just outside the visible frame. Replaced with an explicit visibility-window search (-0.01 ≤ ta ≤ 1.01 in axes units) to find the true extremal visible ticks.

  • Auto-locator feedback loop — after widening ylim, AutoLocator recalculated ticks and could place a new tick at the enlarged boundary, recreating the overflow. A FixedLocator is now installed whenever limits are changed, freezing tick positions.

Algebraic formulas replace approximate transforms

The old code approximated new limits using the pre-adjustment transform, giving slightly wrong results. The new code solves the placement equations directly:

# Bottom-only (top subplot):  place T_bottom at axes position dy
new_lower = (t_bottom_data - dy * ylim[1]) / (1.0 - dy)

# Top-only (bottom subplot):  place T_top at axes position 1 - dy
new_upper = ylim[0] + (t_top_data - ylim[0]) / (1.0 - dy)

# Both edges (middle subplot): symmetric solution
total_range = (t_top_data - t_bottom_data) / (1.0 - 2.0 * dy)
new_lower = t_bottom_data - dy * total_range
new_upper = t_top_data   + dy * total_range

Log-scale axes skipped

Applying the linear-mapping formulas to a log-scale axis produced non-positive limits and a matplotlib UserWarning. Non-linear y-scales are now detected and skipped early in _fix_limits.

Tests

New test module tests/stonerplots/test_stack_vertical.py covers bottom/top tick clearance per-panel, FixedLocator installation, joined=False (no-op), 2- and 5-panel stacks, and the single-tick edge case.


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

…oined subplots

Three bugs fixed:
1. Reversed condition (`<` → `>`) for upper-limit check meant the top-edge
   adjustment almost never fired.
2. Heuristic index-based tick selection replaced with a visibility-window
   search finding the actual min/max visible tick.
3. FixedLocator now freezes tick positions after a limit expansion to prevent
   the auto-locator from placing new edge ticks that would recreate the overlap.

Also skip _fix_limits for non-linear (e.g. log) y-scales where the linear
transform assumption does not hold, avoiding spurious UserWarning from matplotlib.

New test module added: tests/stonerplots/test_stack_vertical.py

Co-authored-by: gb119 <4428426+gb119@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix exit code in StackVertical for better subplot adjustments Fix StackVertical._fix_limits to reliably push joined subplot tick labels inside frame edges Mar 11, 2026
@gb119 gb119 marked this pull request as ready for review March 11, 2026 15:16
@gb119 gb119 merged commit 827d3a7 into main Mar 11, 2026
6 of 7 checks passed
@gb119 gb119 deleted the copilot/fix-stackvertical-axes-limits branch March 11, 2026 15:16
@codacy-production
Copy link

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
-0.03% (target: -1.00%) 90.91%
Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (ff9cef1) 1022 953 93.25%
Head commit (c249335) 1047 (+25) 976 (+23) 93.22% (-0.03%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#74) 33 30 90.91%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

See your quality gate settings    Change summary preferences

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