Visitar URL original
Honor set_rlabel_position on partial-wedge polar axes by mertkayacs · Pull Request #32539 · matplotlib/matplotlib · GitHub
Skip to content

Honor set_rlabel_position on partial-wedge polar axes - #32539

Open
mertkayacs wants to merge 3 commits into
matplotlib:mainfrom
mertkayacs:fix-rlabel-position-wedge-15835
Open

mertkayacs wants to merge 3 commits into
matplotlib:mainfrom
mertkayacs:fix-rlabel-position-wedge-15835

Conversation

@mertkayacs

@mertkayacs mertkayacs commented Oct 25, 2026 •

Copy link
Copy Markdown

PR summary

Closes #15835.

PolarAxes.draw replaces the r-axis label transform with _yaxis_transform whenever the axes shows a partial wedge, and that transform drops _r_label_position entirely, so set_rlabel_position silently does nothing on wedge plots.

The only rlabel state is now the angle, None until set_rlabel_position is called. PolarAxes._get_rlabel_theta decides which radial line the labels use: the set angle, else the default angle on a full circle and thetamin on a wedge. A small lazy transform, _RLabelTransform, builds the label translation from it, and the label position, its tick mark, the pad shift (_ThetaShift mode 'rlabel') and RadialTick.update_position all read that one value. A set position is honored even outside the wedge, as suggested in the issue. Without one, the labels still go along the wedge edges, so existing plots do not change, except wedges with inverted theta limits, whose labels now follow thetamin as their alignment already assumed. The labels on the other edge (label2On) stay on that edge. set_rgrids no longer calls set_rlabel_position when no angle is passed, which would otherwise pin the labels on a wedge to the default angle.

AI Disclosure

I used AI agents to help trace the transform chain and to draft the fix and the test. I reviewed, understood and ran all of it myself before opening this PR.

PR quality check

  • Use an expressive title
  • New and changed code is tested
  • Plotting related features are demonstrated in an example (N/A: bug fix, no new feature)
  • New features and API changes have release notes (N/A: no API change)
  • Documentation complies with guidelines

@github-actions

Copy link
Copy Markdown

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.
Please let us know if (and how) you use AI, it will help us give you better feedback on your PR.

We strive to be a welcoming and open project. Please follow our Code of Conduct.

@agammann agammann left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new manual-label branch in get_yaxis_text1_transform() chooses horizontal alignment from get_theta_direction(), but test_polar_rlabel_position_wedge only exercises the default counterclockwise direction and checks anchor positions. Could you also run it with set_theta_direction(-1) and assert the alignment or rendered label placement? That would cover the clockwise branch introduced here, including the new rlabel padding path.

Review prepared by Codex on behalf of agammann.

With set_theta_direction(-1) and an explicit rlabel position on a wedge,
the rlabel pad shift pointed to the clockwise side of the radial line
while RadialTick.update_position aligns the text on the counterclockwise
side, so the labels straddled the gridline. Shift toward the side the
text is on.

Extend test_polar_rlabel_position_wedge to both theta directions and
assert the anchor, the pad shift and that the whole label stays on the
padded side of the radial line.
Comment thread lib/matplotlib/projections/polar.py Outdated
full = _is_full_circle_deg(thetamin, thetamax)

if full:
if full or axes._r_label_position_manual:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slight logic concern: "full or manually set" seems a strange condition.

I feel there should be a cleaner way of expressing this. The point is that "full or manual" takes the _rlabel_position_transform whereas "non-manual wedge" must decide on a suitable angle based on thetamin. It's likely not possible to push that decision up so that we don't have if/else distinction here, because we evalutate on the current thetamin. So the reverse question: Could we only store the r_label angular value and create the transform here?

Keep only the rlabel angle, None until set_rlabel_position is called,
in place of the Affine2D and the flag that recorded whether the position
was set. PolarAxes._get_rlabel_theta decides in one place where the
labels go: the set angle, else the default angle on a full circle and
thetamin on a partial wedge. The lazily evaluated _RLabelTransform
builds the label translation from it, and label1, tick1, the 'rlabel'
pad and RadialTick.update_position all use it, so the "full or manual"
special cases are gone from draw(), get_yaxis_text1_transform and
update_position.

With a set position on a wedge, this also fixes the padding when the
position changes after a draw or when the ticks existed before it was
set, keeps the end-edge labels and tick marks (label2, tick2) on their
edge where they used to jump to the set angle plus one radian, and
turns the start tick marks perpendicular to the label line as on the
default edge. With inverted theta limits, the default labels now follow
thetamin, which their alignment and padding already assumed.

Add tests for setting the position over existing ticks and for a
position at thetamin giving the default wedge layout.
@mertkayacs

Copy link
Copy Markdown
Author

That works: the only rlabel state is now the angle (None until set_rlabel_position is called), and one helper picks the radial line for the labels, so the "full or manual" branches are gone. A small lazy transform builds the label translation from that angle and the current thetamin. It also fixed three problems with a set position on a wedge: stale padding when the position changed after a draw, wrong padding when the ticks already existed, and label2 jumping to the set angle plus one radian. Two visible changes: tick marks at a set position are now perpendicular to the radial line, as at the default edge, and wedges with inverted theta limits now put their labels beside the thetamin edge instead of across it; I updated the description to match. @agammann, running the wedge test clockwise showed the pad shift on the wrong side for theta_direction=-1, so it now follows the text side and the test covers both directions.

@agammann

Copy link
Copy Markdown

Thanks for checking the clockwise case. I rechecked head fd8a010: the wedge test now covers both theta directions and checks the label’s rendered side as well as the padding position. That addresses the coverage I requested. I reviewed the diff but did not run the tests locally. AI-assisted review.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"set_rlabel_position" don't work when "set_thetamin"

3 participants