fix: Correct label positioning across figure sizes and DPIs#711
Conversation
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
There was a problem hiding this comment.
Pull request overview
This PR fixes inconsistent mh.<exp>.label positioning across figure sizes/DPIs by correcting point-to-axis-fraction conversions in mplhep.label. The update ensures font sizes (points) are converted via points→inches (/ 72) rather than incorrectly treating points as pixels (/ dpi), and refreshes pytest-mpl baselines accordingly.
Changes:
- Correct point→axis-fraction conversion in
_fontsize_axisby converting points to inches (fontsize_points / 72) instead of dividing by DPI. - Fix
append_textauto-spacing correction terms to use points→inches (fontsize / 72) rather than points→pixels (/ dpi). - Update pytest-mpl baseline images to reflect the corrected spacing/placement.
Reviewed changes
Copilot reviewed 1 out of 19 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/mplhep/label.py | Fixes unit conversion for font-size-derived spacing so label/append offsets scale consistently across DPI and figure sizes. |
| tests/baseline/test_style_dune.png | Updated visual baseline for DUNE style after spacing correction. |
| tests/baseline/test_style_atlas.png | Updated visual baseline for ATLAS style after spacing correction. |
| tests/baseline/test_labeltext_loc.png | Updated visual baseline for label text placement tests. |
| tests/baseline/test_label_loc.png | Updated visual baseline for label location tests. |
| tests/baseline/test_dune_label_loc.png | Updated visual baseline for DUNE label location tests. |
| tests/baseline/test_append_text_multiline.png | Updated visual baseline for multiline append_text placement after spacing correction. |
Rescues #711 / refs #709. The dimensional bug Jules's PR identified is real: `fontsize` is in points (1pt = 1/72 in) and `ax_height * dpi = ax_height_px`, so `fontsize / ax_height / dpi` is points-per-pixel, not an axis-fraction. But applying the points->inches conversion naively (PR #711 as opened) inflates every label gap by 100/72 ~= 1.39x at the default DPI, which would silently shift every existing CMS/ATLAS/etc. label slightly to the right and require regenerating 18 baselines. This version applies the dimensional fix AND retunes the calibration constants so that, at the legacy default DPI of 100, the rendered pixel gap is bit-for-bit identical to the current behaviour: FONT_WIDTH_CORRECTION_FACTOR : 3 -> 3 * 100/72 FONT_HEIGHT_CORRECTION_FACTOR: 10 -> 10 * 100/72 _inside_pad multiplier : 100 -> 72 (since _fontsize_axis is now a true axis-fraction, not the pt/(ax_height_in*dpi) hybrid) Verified: - pixel gap is constant across figsize (10x10, 12x5, 16x4, 20x3, 6x6, 5x12, 8x6) at every DPI tested - pixel gap scales linearly with DPI (constant 0.087" everywhere) i.e. constant physical inches across dpi=50/100/200/300 - at dpi=100 the rendered pixel gap (8.67px) matches main exactly - full suite (323 tests) passes with the original baselines, no regeneration needed
5e95a00 to
6411c7d
Compare
|
Force-pushed a revised version of the fix. Same correct math (points→inches, no What changed vs the original commit
Why retuneWithout the calibration constants, the dimensionally-correct formula makes every label gap ~38% wider at default DPI (factor 100/72 ≈ 1.388). That would silently shift CMS/ATLAS/etc. labels everywhere and was the reason 18 baselines moved in the original PR. Pre-tuning the correction factors by Verification
So the fix is now strictly a DPI-correctness improvement that's invisible at the default DPI and only kicks in when users render at non-100 DPI (e.g. 🤖 Generated with Claude Code |
Two regression guards for the dpi-vs-points fix: - test_cms_label_dpi_invariance: pytest-mpl visual at figsize=(12, 5), dpi=200 covering both loc=0 (label outside axes) and loc=2 (stacked inside). Catches reintroduction of the pixel-pinned gap, which at dpi=200 would shrink the gap to a sliver next to the DPI-scaled text. - test_cms_label_gap_is_dpi_invariant: assertion test that renders the label at dpi=50/100/200/300 and asserts the CMS<->Preliminary gap is constant in inches across all DPIs. Math-only, font-rendering independent.
This PR addresses issue #709 where the positioning of
mh.<exp>.label(such as the gap between "CMS" and "Preliminary") was inconsistent across different figure sizes and aspect ratios.The root cause was traced to how font sizes (which are provided in typography points, 1 point = 1/72 inch) were being converted into axis fraction units. The code was incorrectly dividing the point size by
ax.figure.dpi(effectively treating points as pixels) instead of by72.This has been fixed in
_fontsize_axisandappend_textwithinsrc/mplhep/label.pyby properly converting points to inches viafontsize / 72. Test baselines generated viapytest-mplhave been updated to reflect this corrected spacing.PR created automatically by Jules for task 14182033389645325178 started by @andrzejnovak