Skip hidden y-axis offset text when positioning titles (fix #31881)#31885
Skip hidden y-axis offset text when positioning titles (fix #31881)#31885gaoflow wants to merge 1 commit into
Conversation
The y-axis offset text of an inner subplot that shares its y axis is hidden but still carries text. _update_title_position only checked get_text(), so since matplotlib#31285 (which makes a hidden text report a null, non-finite tight bbox) the offset text pushed the title -- and the subplot position computed by tight_layout -- to inf/NaN. Drawing then raised "cannot convert float NaN to integer". Only consider the offset text for title placement when it is visible.
|
Thank you for opening your first PR into Matplotlib! If you have not heard from us in a week or so, please leave a new comment below and that should bring it to our attention. Most of our reviewers are volunteers and sometimes things fall through the cracks. We also ask that you please finish addressing any review comments on this PR and wait for it to be merged (or closed) before opening a new one, as it can be a valuable learning experience to go through the review process. You can also join us on discourse chat for real-time discussion. For details on testing, writing docs, and our review process, please see the developer guide. We strive to be a welcoming and open project. Please follow our Code of Conduct. |
|
Thanks for the welcome! To answer the AI question directly: yes, this PR was written with AI assistance (Claude), working under my direction and review. I drove the debugging — reproducing the crash headlessly, bisecting it to #31285, and tracing the Happy to adjust the approach, comment, or test if you'd prefer a different fix location (e.g. guarding the bbox itself rather than the visibility check). |
|
Note on CI: the one red job (Azure Main Pytest Windows_py313) failed on |
PR summary
Fixes #31881 —
plt.subplots(1, 2, sharey=True, tight_layout=True)with per-subplot titles and large y-values raisedValueError: cannot convert float NaN to integeron draw. Regression in 3.11.0, bisected by @ksunden to #31285.Root cause
On the inner subplot the y axis is shared, so its offset text is hidden (
set_visible(False)) but still carries text (e.g.'1e53').Axes._update_title_positiondecides whether to lift the title above the offset text by checking onlyoffsetText.get_text(), not its visibility:Since #31285,
Text.get_tightbboxreturnsBbox.null()for hidden/empty text.Bbox.null()is[[inf, inf], [-inf, -inf]], which hasxmin=-inf, xmax=+inf— so it behaves as an infinite box underintersection, making the guard pass and settingtop = bb.ymax = inf. The title is then placed aty = inf; its window extent feedstight_layout, which computes a NaN subplot position, and the subsequentYAxis.get_tick_spacedoesint(np.floor(NaN))→ the error.Fix
A hidden offset text is not drawn, so it should not influence the title position. Only consider it when it is visible. This also fixes the (silently broken) title placement that occurs without
tight_layout— the title was being moved to infinity there too, just without a downstream crash.Test
test_title_above_hidden_offsetreproduces the issue and asserts the title and subplot positions stay finite. It fails onmain(raises the originalValueError) and passes with the fix. The existingtest_title_above_offsetcovers the visible-offset case, which is unchanged.I verified the change against an installed 3.11.0 build by patching the single edited file (the change is pure-Python).