Skip to content

Commit 263afe3

Browse files
committed
This fixes a long-standing issue where geographic grid label styling options like labelsize worked when formatting a single GeoAxes directly, but were silently ignored when the same axes was formatted through SubplotGrid.format() or Figure.format(). The higher-level formatting paths were treating names like labelsize as rc-style aliases and removing them before dispatching to the projection-specific GeoAxes.format() method.
The underlying behavior goes back to the ProPlot inheritance chain. GeoAxes.format(labelsize=..., labelweight=...) was introduced there in October 2021, while the figure-level formatting dispatch was already using _pop_rc(kwargs). That meant the collision between explicit geo formatting keywords and rc aliases had been latent for a long time. This change preserves explicit projection-specific formatting arguments during figure and subplot-grid dispatch so that geographic label styling behaves the same whether users call ax.format(...) or axs.format(...).
1 parent 1d06962 commit 263afe3

4 files changed

Lines changed: 61 additions & 4 deletions

File tree

ultraplot/config.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,15 +1314,19 @@ def _get_ticklabel_props(self, axis=None, native=True, rebuild=False):
13141314
Return the tick label properties, optionally filtering the output dictionary
13151315
based on the context.
13161316
"""
1317-
# NOTE: 'tick.label' properties are now synonyms of 'grid.label' properties
1317+
# Geographic gridline labels use the ultraplot-only grid.label* settings,
1318+
# while native matplotlib tick labels use x/y tick rcParams.
13181319
sprefix = axis or ""
13191320
cprefix = sprefix if _version_mpl >= "3.4" else "" # new settings
13201321
context = not rebuild and (native or self._context_mode == 2)
1322+
color_key = f"{cprefix}tick.labelcolor" if native else "grid.labelcolor"
1323+
size_key = f"{sprefix}tick.labelsize" if native else "grid.labelsize"
1324+
weight_key = "tick.labelweight" if native else "grid.labelweight"
13211325
kwtext = self.fill(
13221326
{
1323-
"color": f"{cprefix}tick.labelcolor", # native setting sometimes avail
1324-
"size": f"{sprefix}tick.labelsize", # native setting always avail
1325-
"weight": "tick.labelweight", # native setting never avail
1327+
"color": color_key, # native setting sometimes avail
1328+
"size": size_key,
1329+
"weight": weight_key, # native setting never avail
13261330
"family": "font.family", # apply manually
13271331
},
13281332
context=context,

ultraplot/figure.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3623,7 +3623,19 @@ def format(
36233623
# Initiate context block
36243624
axs = axs or self._subplot_dict.values()
36253625
skip_axes = kwargs.pop("skip_axes", False) # internal keyword arg
3626+
# Preserve explicit projection-specific format keywords that also happen to
3627+
# be valid rc aliases (e.g. GeoAxes/PolarAxes `labelsize`). Otherwise
3628+
# `_pop_rc()` removes them before the per-axes format dispatch below.
3629+
original_kwargs = kwargs.copy()
3630+
axis_param_names = set()
3631+
for ax in axs:
3632+
for cls, sig in paxes.Axes._format_signatures.items():
3633+
if isinstance(ax, cls):
3634+
axis_param_names.update(sig.parameters)
3635+
axis_param_names.discard("self")
36263636
rc_kw, rc_mode = _pop_rc(kwargs)
3637+
for key in axis_param_names & original_kwargs.keys():
3638+
kwargs.setdefault(key, original_kwargs[key])
36273639
with rc.context(rc_kw, mode=rc_mode):
36283640
# Update background patch
36293641
kw = rc.fill({"facecolor": "figure.facecolor"}, context=True)

ultraplot/gridspec.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2114,7 +2114,19 @@ def _supports_implicit_label_share(target):
21142114
else:
21152115
shared_title_loc = None
21162116
shared_title_pad = None
2117+
# Preserve explicit projection-specific format keywords that also happen to
2118+
# be valid rc aliases (e.g. GeoAxes/PloarAxes `labelsize`). Otherwise
2119+
# `_pop_rc()` removes them before Figure.format() can delegate to axes.
2120+
original_kwargs = kwargs.copy()
2121+
axis_param_names = set()
2122+
for ax in axes:
2123+
for cls, sig in paxes.Axes._format_signatures.items():
2124+
if isinstance(ax, cls):
2125+
axis_param_names.update(sig.parameters)
2126+
axis_param_names.discard("self")
21172127
rc_kw, rc_mode = _pop_rc(kwargs)
2128+
for key in axis_param_names & original_kwargs.keys():
2129+
kwargs.setdefault(key, original_kwargs[key])
21182130
with rc.context(rc_kw, mode=rc_mode):
21192131
implicit_share_xlabels = (
21202132
is_subset

ultraplot/tests/test_geographic.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,35 @@ def test_geoticks_label_shorthand_lb_no_warning(recwarn):
188188
uplt.close(fig)
189189

190190

191+
def test_geo_labelsize_updates_gridliner_labels():
192+
fig, ax = uplt.subplots(proj="cyl")
193+
ax = ax[0]
194+
ax.format(labels=True, lonlines=30, latlines=30, labelsize=30)
195+
fig.canvas.draw()
196+
197+
labels = (
198+
ax.gridlines_major.bottom_label_artists + ax.gridlines_major.left_label_artists
199+
)
200+
assert labels
201+
assert {label.get_fontsize() for label in labels} == {30}
202+
uplt.close(fig)
203+
204+
205+
def test_subplotgrid_geo_labelsize_updates_gridliner_labels():
206+
fig, ax = uplt.subplots(proj="cyl")
207+
ax.format(labels=True, lonlines=30, latlines=30, labelsize=30)
208+
fig.canvas.draw()
209+
210+
geo = ax[0]
211+
labels = (
212+
geo.gridlines_major.bottom_label_artists
213+
+ geo.gridlines_major.left_label_artists
214+
)
215+
assert labels
216+
assert {label.get_fontsize() for label in labels} == {30}
217+
uplt.close(fig)
218+
219+
191220
def test_toggle_ticks_supports_bool_and_sequence_specs():
192221
fig, ax = uplt.subplots(proj="cyl")
193222
geo = ax[0]

0 commit comments

Comments
 (0)