FIX: snap near-integer arc windings to a full circle on polar plots (#20388, #26972)#31844
Conversation
rcomer
left a comment
There was a problem hiding this comment.
Thanks @SharadhNaidu, this fix makes sense to me and I have even learned something as I did not know about np.nextafter!
I am wondering if we actually need the polar-specific tests. Obviously for the purpose of this work is it necessary to verify that the reported polar cases are fixed. However, the fix is entirely within path.py, and the underlying problem is now covered by the computationally cheaper tests in test_path.py.
|
I suggest to also rebase you branch against |
done , rebased and working on the current main |
matplotlib#26972) On polar plots, radial gridlines and the outer spine could collapse to a near-empty arc. The root cause is Path.arc's angle-unwrap step: a span of 360*n plus a tiny floating-point rounding error was reduced modulo 360 to a near-zero arc instead of a full circle. Detect spans that are within floating-point tolerance of a whole number of turns and draw a complete circle; otherwise unwrap theta2 to the shortest arc within 360 degrees as before. The change is byte-identical for all non-degenerate inputs, so no call sites need to change. Adds unit coverage for the snap/unwrap behaviour and end-to-end polar gridline and spine regression tests.
- Replace the 1e-9 magic tolerance with 1e-12 turns, justified by the observed error from the polar transform pipeline (machine-epsilon level, under 1e-15 turns), via np.rint(n_turns). - Snap on any non-zero whole number of turns (abs winding), restoring the legacy full-circle behaviour for exact negative multiples such as Path.arc(0, -360); the previous rework collapsed those to an empty arc. - Add regression tests for negative full circles and a tolerance-tightness guard (a span just past a full turn must not snap).
- Drop the contrast and GitHub issue references from the Path.arc docstring; just state that a complete circle is drawn. - Remove issue references and reword the test_path.py comments for a reader unfamiliar with this PR's history. - Make test_arc_full_circle_snap compare all vertices against the reference circle, consistent with (and slightly stricter than) the neighbouring test. - Remove test_polar_transform_constant_r_arc (it passes against main and no longer guards the fix) and merge the two outer-spine tests into a single test_polar_outer_spine_not_collapsed using the spine bbox.
560f59f to
bd946aa
Compare
|
@rcomer , I am sorry if i am violating the rules of directly tagging you but , is there any changes that i have to make ? |
rcomer
left a comment
There was a problem hiding this comment.
Thanks @SharadhNaidu
I am still not sure about
I am wondering if we actually need the polar-specific tests. Obviously for the purpose of this work is it necessary to verify that the reported polar cases are fixed. However, the fix is entirely within path.py, and the underlying problem is now covered by the computationally cheaper tests in test_path.py.
But I will leave it for the second reviewer or other developer to weigh in on that. I note there are now fewer of these tests than when I wrote the comment.
For code changes, we require approvals from two core developers, so this will have to wait a bit longer before merge.
I am glad that your experience in #31674 has not put you off!
no worries , I will be waiting for their review and make the recommended changes , if any.
Yup , learnt a lot in that process. |
|
applied the recommended changes , is_full_circle reads much cleaner. will improve interms of writing comments. |
|
@timhoffm I am sorry if i am violating the rules of directly tagging you but , is there any changes that i have to make ? |
|
Thanks @SharadhNaidu, and congatulations on your first PR to Matplotlib! 🎉 We hope to see you back. |
|
@timhoffm thanks and looking to contribute as much as i can. |
PR summary
On polar plots, radial gridlines (#20388) and the outer spine (#26972) could collapse to a near-empty arc for certain
set_theta_zero_location/set_theta_offset/set_theta_directioncombinations.The root cause is in
Path.arc's angle-unwrap step. A span of360*nplus a tiny floating-point rounding error was reduced modulo 360 to a near-zero arc instead of a full circle:Fix
Detect spans that are within floating-point tolerance of a whole number of turns and draw a complete circle; otherwise unwrap
theta2to the shortest arc within 360 degrees exactly as before:The change is byte-identical for all non-degenerate inputs (e.g. 90°, 359.99°, 360°, 410°→50°, 540°→180°, 720°→full circle) and only affects the
360*n + εcollapse cases, so no call sites need to change.Closes #20388
Closes #26972
Tests
test_arc_full_circle_snap/test_arc_unwrap_partial_turnintest_path.pycover the snap-vs-unwrap behaviour at the unit level.test_path.pyand end-to-end polar gridline / outer-spine regression tests intest_polar.py.PR checklist
AI Disclosure
AI was used to help proofread the grammar of this PR description and to understand some parts of the existing codebase during development. The code changes and design decisions were developed independently.