Skip to content

Add polar-aware rlabel and thetalabel support#714

Open
kinyatoride wants to merge 4 commits into
Ultraplot:mainfrom
kinyatoride:feat-polar-thetalabel-rlabel
Open

Add polar-aware rlabel and thetalabel support#714
kinyatoride wants to merge 4 commits into
Ultraplot:mainfrom
kinyatoride:feat-polar-thetalabel-rlabel

Conversation

@kinyatoride
Copy link
Copy Markdown
Contributor

Add polar-aware rlabel and thetalabel support

Hi! I think having rlabel and thetalabel for polar plots is useful for many
cases — Taylor diagrams being one example. I've added this support along with
tests. Let me know what you think!

Summary

This PR adds polar-aware axis label support to PolarAxes.format() with new
thetalabel and rlabel arguments rendered via CurvedText.

Key Features

  • Add thetalabel for labels that follow the outer polar arc.
  • Add rlabel for labels that follow a radial spoke.
  • Add thetalabelloc to control the center angle of the theta label.
  • Add rlabelloc to control which side or spoke the radial label uses.
  • Support explicit rlabelpos placement for radial labels.
  • Support styling through thetalabel_kw and rlabel_kw.
  • Keep label placement correct for:
    • full-circle plots
    • sector plots
    • wrapped theta intervals
    • transformed theta orientation (theta0, thetadir)
    • annular polar axes
  • Refresh label geometry during draw and tight-bbox updates.

Implementation

  • Add polar-label geometry and state handling in ultraplot/axes/polar.py
  • Update CurvedText in ultraplot/text.py so transformed and styled curved labels
    behave correctly on polar axes
  • Split pseudo label props in ultraplot/internals/labels.py so border and bbox
    styling can be applied safely to curved labels

Validation

Focused polar regression tests pass:

python -m pytest ultraplot/tests/test_projections.py -k "polar and not mpl_image_compare"

This also adds regression coverage for:

  • transformed thetalabel outward placement
  • annular polar label positioning with finite glyph positions

Examples

Examples of full-circle, sector, annular, and rotated-axis polar labels:

import ultraplot as uplt

fig, axs = uplt.subplots(
    proj='polar', ncols=2, nrows=3, share=0,
)

axs[0, 0].format(
    thetalabel='Full circle',
    rlabel='Radius',
    title='Full circle, default locs',
    labelsize=10,
)

axs[0, 1].format(
    thetalim=(0, 360),
    rlim=(5, 10),
    thetalabel='Label at 250°',
    thetalabelloc=250,
    rlabel='left label',
    rlabelloc='left',
    title='Full circle, custom locs',
    labelsize=10,
)

axs[1, 0].format(
    thetalim=(0, 90),
    rlim=(0, 1),
    thetalabel='Quarter arc',
    rlabel='r [0-1]',
    title='Section, default locs',
    labelsize=10,
)

axs[1, 1].format(
    thetalim=(0, 180),
    rlim=(0, 10),
    thetalabel='Label at 135°',
    thetalabelloc=135,
    rlabel='Left spoke',
    rlabelloc='left',
    title='Section, custom locs',
    labelsize=10,
)

axs[2, 0].format(
    thetalim=(50, 70),
    r0=0, rlim=(1, 5),
    thetalabel='Narrow section',
    thetalabel_kw={'color': 'steelblue', 'style': 'italic'},
    rlabel='labelpad=50',
    rlabel_kw={'labelpad': 50, 'weight': 'bold', 'size': 13},
    title='Section, labelpad',
    labelsize=10,
)

axs[2, 1].format(
    thetalim=(0, 180),
    rlim=(2, 10),
    theta0='N',
    thetadir=-1,
    thetalabel='Reversed theta direction',
    rlabel='Radius',
    rlabelloc='right',
    title="theta0='N', thetadir=-1",
)
axs.format(
    suptitle='Polar labels demo',
    titlepad=30,
)
polar_labels_demo

@codecov
Copy link
Copy Markdown

codecov Bot commented May 6, 2026

Codecov Report

❌ Patch coverage is 95.74468% with 18 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
ultraplot/axes/polar.py 93.33% 5 Missing and 7 partials ⚠️
ultraplot/text.py 80.00% 4 Missing and 2 partials ⚠️

📢 Thoughts on this report? Let us know!

@cvanelteren
Copy link
Copy Markdown
Collaborator

Isn't this already implemented? I have some time tomorrow to look at this but then will be mia for a while (cc @beckermr)

@kinyatoride
Copy link
Copy Markdown
Contributor Author

Not really, as far as I’m aware.

@cvanelteren
Copy link
Copy Markdown
Collaborator

Never seen a Taylor diagram. That looks pretty handy for my work. Will review this today.

@cvanelteren
Copy link
Copy Markdown
Collaborator

This is moving in the right direction overall, and I like the thetalabel/rlabel API since it matches the existing polar theta/r vocabulary much better than Cartesian x/y labels. My main concern is that this PR currently also includes the earlier xlabel/ylabel support for PolarAxes.format() from #713, including the figure.py dispatch change and the regression test for ax.format(xlabel=..., ylabel=...). Given that Ultraplot’s current polar docs and API are framed in terms of theta/r formatters and locators rather than x/y axis labels, I do not think we should merge the Cartesian label behavior as part of this feature. I would be much more comfortable with this PR if it focused just on the polar-native label additions (thetalabel, rlabel, and related placement/styling options), dropped the xlabel/ylabel support, and added user-facing docs/examples for the new API.

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