Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions ultraplot/axes/polar.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@
thetaformatter_kw, rformatter_kw : dict-like, optional
The azimuthal and radial label formatter settings. Passed to
`~ultraplot.constructor.Formatter`.
xlabel, ylabel : str, optional
The x and y axis labels. Applied with `~matplotlib.axes.Axes.set_xlabel`
and `~matplotlib.axes.Axes.set_ylabel`.
xlabel_kw, ylabel_kw : dict-like, optional
Additional axis label settings applied with `~matplotlib.axes.Axes.set_xlabel`
and `~matplotlib.axes.Axes.set_ylabel`. See also `labelpad`, `labelcolor`,
`labelsize`, and `labelweight`.
color : color-spec, default: :rc:`meta.color`
Color for the axes edge. Propagates to `labelcolor` unless specified
otherwise (similar to :func:`~ultraplot.axes.CartesianAxes.format`).
Expand Down Expand Up @@ -212,6 +219,23 @@ def _update_locators(
else:
axis.set_minor_locator(loc)

def _update_labels(self, x, *args, **kwargs):
"""
Apply axis labels via `set_xlabel` / `set_ylabel`.
"""
# NOTE: Critical to test whether arguments are None or else this
# will set isDefault_label to False every time format() is called.
kwargs = rc._get_label_props(**kwargs)
no_args = all(a is None for a in args)
no_kwargs = all(v is None for v in kwargs.values())
if no_args and no_kwargs:
return
setter = getattr(self, f"set_{x}label")
getter = getattr(self, f"get_{x}label")
if no_args: # otherwise label text is reset!
args = (getter(),)
setter(*args, **kwargs)

@docstring._snippet_manager
def format(
self,
Expand Down Expand Up @@ -256,6 +280,10 @@ def format(
labelsize=None,
labelcolor=None,
labelweight=None,
xlabel=None,
ylabel=None,
xlabel_kw=None,
ylabel_kw=None,
**kwargs,
):
"""
Expand Down Expand Up @@ -335,6 +363,8 @@ def format(
formatter_kw,
minorlocator,
minorlocator_kw,
label,
label_kw,
) in zip(
("x", "y"),
(thetamin, rmin),
Expand All @@ -349,6 +379,8 @@ def format(
(thetaformatter_kw, rformatter_kw),
(thetaminorlocator, rminorlocator),
(thetaminorlocator_kw, rminorlocator_kw),
(xlabel, ylabel),
(xlabel_kw, ylabel_kw),
):
# Axis limits
self._update_limits(x, min_=min_, max_=max_, lim=lim)
Expand Down Expand Up @@ -382,6 +414,16 @@ def format(
x, formatter=formatter, formatter_kw=formatter_kw
)

# Axis label
kw = dict(
labelpad=labelpad,
color=labelcolor,
size=labelsize,
weight=labelweight,
)
kw.update(label_kw or {})
self._update_labels(x, label, **kw)

# Parent format method
super().format(rc_kw=rc_kw, rc_mode=rc_mode, **kwargs)

Expand Down
13 changes: 10 additions & 3 deletions ultraplot/figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -3277,11 +3277,15 @@ def format(
if skip_axes: # avoid recursion
return

# Remove all keywords that are not in the allowed signature parameters
# Collect each class's matching kwargs without popping, then drop the union —
# shared params (e.g. xlabel/ylabel, accepted by both CartesianAxes and
# PolarAxes) need to reach every matching class.
kws = {
cls: _pop_params(kwargs, sig)
cls: {k: kwargs[k] for k in sig.parameters if kwargs.get(k) is not None}
for cls, sig in paxes.Axes._format_signatures.items()
}
for k in {k for cls_kw in kws.values() for k in cls_kw}:
kwargs.pop(k, None)
classes = set() # track used dictionaries

def _axis_has_share_label_text(ax, axis):
Expand Down Expand Up @@ -3314,11 +3318,14 @@ def _axis_has_label_text(ax, axis):
kw.pop("ylabel", None)
ax.format(rc_kw=rc_kw, rc_mode=rc_mode, skip_figure=True, **kw, **kwargs)
ax.number = store_old_number
# Warn unused keyword argument(s)
# Warn unused keyword argument(s). Shared params (those in multiple
# signatures) are considered "used" if any matched class consumed them.
used_keys = {k for cls in classes for k in kws[cls]}
kw = {
key: value
for name in kws.keys() - classes
for key, value in kws[name].items()
if key not in used_keys
}
if kw:
warnings._warn_ultraplot(
Expand Down
10 changes: 10 additions & 0 deletions ultraplot/tests/test_projections.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,16 @@ def test_polar_projections():
return fig


def test_polar_format_labels():
"""
ax.format(xlabel=..., ylabel=...) must forward to set_xlabel/set_ylabel.
"""
fig, ax = uplt.subplots(proj="polar")
ax.format(xlabel="xlabel", ylabel="ylabel")
assert ax.get_xlabel() == "xlabel"
assert ax.get_ylabel() == "ylabel"


def test_sharing_axes():
"""
Test sharing axes for GeoAxes
Expand Down
Loading