Skip to content

Commit f5e2559

Browse files
committed
Permit passing mixed projection keywords to fig/grid.format
1 parent 82aa3d8 commit f5e2559

8 files changed

Lines changed: 111 additions & 71 deletions

File tree

WHATSNEW.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ Features
3636

3737
* Permit passing arbitrary ``format`` arguments to multi-axes creation commands
3838
like `~proplot.ui.subplots` (:commit:`0b801442`).
39+
* Permit passing ``format`` arguments for different projections to the same
40+
`proplot.gridspec.SubplotGrid.format`
3941
* Add `[xy]labelsize`, `[xy]labelweight`, `[xy]ticklabelsize`, `[xy]ticklabelweight`
4042
keywords to `proplot.axes.CartesianAxes.format` (:commit:`975025df`).
4143
* Add `labelsize` and `labelweight` keywords to `proplot.axes.PolarAxes.format`,

proplot/axes/base.py

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -391,23 +391,26 @@
391391
with the "¤" dummy character. For details see this `mathtext tutorial \
392392
<https://matplotlib.org/stable/tutorials/text/mathtext.html#custom-fonts>`__.
393393
"""
394+
_rc_init_docstring = """
395+
Remaining keyword arguments are passed to `matplotlib.axes.Axes`.
396+
"""
394397
_rc_format_docstring = """
395398
rc_mode : int, optional
396399
The context mode passed to `~proplot.config.Configurator.context`.
397400
rc_kw : dict-like, optional
398401
An alternative to passing extra keyword arguments. See below.
399402
**kwargs
400-
Unknown keyword arguments are passed to `matplotlib.axes.Axes`. Other keyword
401-
arguments that match the name of an `~proplot.config.rc` setting are passed to
402-
`proplot.config.Configurator.context` and used to update the axes. If the setting
403-
name has "dots" you can simply omit the dots. For example, ``abc='A.'`` modifies
404-
the :rcraw:`abc` setting, ``titleloc='left'`` modifies the :rcraw:`title.loc`
405-
setting, ``gridminor=True`` modifies the :rcraw:`gridminor` setting, and
406-
``gridbelow=True`` modifies the :rcraw:`grid.below` setting. Many of the keyword
407-
arguments documented above are internally applied by retrieving settings passed
408-
to `~proplot.config.Configurator.context`.
403+
{}Keyword arguments that match the name of an `~proplot.config.rc` setting are
404+
passed to `proplot.config.Configurator.context` and used to update the axes.
405+
If the setting name has "dots" you can simply omit the dots. For example,
406+
``abc='A.'`` modifies the :rcraw:`abc` setting, ``titleloc='left'`` modifies the
407+
:rcraw:`title.loc` setting, ``gridminor=True`` modifies the :rcraw:`gridminor`
408+
setting, and ``gridbelow=True`` modifies the :rcraw:`grid.below` setting. Many
409+
of the keyword arguments documented above are internally applied by retrieving
410+
settings passed to `~proplot.config.Configurator.context`.
409411
"""
410-
docstring._snippet_manager['axes.rc'] = _rc_format_docstring
412+
docstring._snippet_manager['rc.init'] = _rc_format_docstring.format(_rc_init_docstring.strip()) # noqa: E501
413+
docstring._snippet_manager['rc.format'] = _rc_format_docstring.format('')
411414
docstring._snippet_manager['axes.format'] = _axes_format_docstring
412415
docstring._snippet_manager['figure.format'] = _figure_format_docstring
413416

@@ -678,7 +681,7 @@ def __init__(self, *args, **kwargs):
678681
679682
Other parameters
680683
----------------
681-
%(axes.rc)s
684+
%(rc.init)s
682685
683686
See also
684687
--------
@@ -691,18 +694,20 @@ def __init__(self, *args, **kwargs):
691694
proplot.figure.Figure.subplot
692695
proplot.figure.Figure.add_subplot
693696
"""
694-
# Initialize parent after removing args
695-
# NOTE: These are really "subplot" features so documented on add_subplot().
697+
# Remove subplot-related args
698+
# NOTE: These are documented on add_subplot()
696699
ss = kwargs.pop('_subplot_spec', None) # see below
697700
number = kwargs.pop('number', None)
698701
autoshare = kwargs.pop('autoshare', None)
699702
autoshare = _not_none(autoshare, True)
703+
704+
# Remove format-related args and initialize
700705
rc_kw, rc_mode = _pop_rc(kwargs)
701706
kw_format = _pop_props(kwargs, 'patch') # background properties
702-
if 'zorder' in kw_format: # special case: refers to entire axes
707+
if 'zorder' in kw_format: # special case: refers to the entire axes
703708
kwargs['zorder'] = kw_format.pop('zorder')
704-
kw_format.update(_pop_params(kwargs, self._format_signature_proj))
705-
kw_format.update(_pop_params(kwargs, self._format_signature_base))
709+
for name in {None, self._name}: # base method and class method (if it exists)
710+
kw_format.update(_pop_params(kwargs, self._format_signatures.get(name)))
706711
super().__init__(*args, **kwargs)
707712

708713
# Varous scalar properties
@@ -760,20 +765,18 @@ def __init__(self, *args, **kwargs):
760765
# set_subplotspec. Tried to defer to setter but really messes up both format()
761766
# and _auto_share(). Instead use workaround: Have Figure.add_subplot pass
762767
# subplotspec as a hidden keyword arg. Non-subplots don't need this arg.
763-
# See https://github.com/matplotlib/matplotlib/pull/18564
768+
# See: https://github.com/matplotlib/matplotlib/pull/18564
764769
self._number = None
765770
if number: # not None or False
766-
self.number = number # documented in add_subplot
767-
if ss is not None:
771+
self.number = number
772+
if ss is not None: # always passed from add_subplot
768773
self.set_subplotspec(ss)
769774
if autoshare:
770775
self._auto_share()
771776

772777
# Default formatting
773778
# NOTE: This ignores user-input rc_mode. Mode '1' applies proplot
774779
# features which is necessary on first run. Default otherwise is mode '2'
775-
if 'color' in rc_kw:
776-
kw_format['color'] = rc_kw.pop('color') # special case (argument clash)
777780
self.format(rc_kw=rc_kw, rc_mode=1, skip_figure=True, **kw_format)
778781

779782
@staticmethod
@@ -1431,11 +1434,6 @@ def format(
14311434
----------
14321435
%(axes.format)s
14331436
1434-
Other parameters
1435-
----------------
1436-
%(figure.format)s
1437-
%(axes.rc)s
1438-
14391437
Important
14401438
---------
14411439
`abc`, `abcloc`, `titleloc`, `titleabove`, `titlepad`, and
@@ -1444,6 +1442,11 @@ def format(
14441442
change them for specific axes. But many :ref:`other configuration
14451443
settings <ug_format>` can be passed to ``format`` too.
14461444
1445+
Other parameters
1446+
----------------
1447+
%(figure.format)s
1448+
%(rc.format)s
1449+
14471450
See also
14481451
--------
14491452
proplot.axes.CartesianAxes.format
@@ -3042,8 +3045,8 @@ def number(self, num):
30423045
else:
30433046
raise ValueError(f'Invalid number {num!r}. Must be integer >=1.')
30443047

3045-
# Apply signature obfuscation after getting keys
3046-
# NOTE: This is needed for __init__
3047-
_format_signature_proj = None
3048-
_format_signature_base = inspect.signature(format)
3049-
format = docstring._obfuscate_kwargs(format)
3048+
3049+
# Apply signature obfuscation after storing previous signature
3050+
# NOTE: This is needed for __init__
3051+
Axes._format_signatures = {None: inspect.signature(Axes.format)}
3052+
Axes.format = docstring._obfuscate_kwargs(Axes.format)

proplot/axes/cartesian.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ def __init__(self, *args, **kwargs):
320320
Other parameters
321321
----------------
322322
%(axes.format)s
323-
%(axes.rc)s
323+
%(rc.init)s
324324
325325
See also
326326
--------
@@ -945,7 +945,7 @@ def format(
945945
----------------
946946
%(axes.format)s
947947
%(figure.format)s
948-
%(axes.rc)s
948+
%(rc.format)s
949949
950950
See also
951951
--------
@@ -1347,7 +1347,8 @@ def get_tightbbox(self, renderer, *args, **kwargs):
13471347
self._update_rotation('x')
13481348
return super().get_tightbbox(renderer, *args, **kwargs)
13491349

1350-
# Apply signature obfuscation after getting keys
1351-
# NOTE: This is needed for __init__, altx, and alty
1352-
_format_signature_proj = inspect.signature(format)
1353-
format = docstring._obfuscate_kwargs(format)
1350+
1351+
# Apply signature obfuscation after storing previous signature
1352+
# NOTE: This is needed for __init__, altx, and alty
1353+
CartesianAxes._format_signatures[CartesianAxes._name] = inspect.signature(CartesianAxes.format) # noqa: E501
1354+
CartesianAxes.format = docstring._obfuscate_kwargs(CartesianAxes.format)

proplot/axes/geo.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ def __init__(self, *args, **kwargs):
425425
Other parameters
426426
----------------
427427
%(axes.format)s
428-
%(axes.rc)s
428+
%(rc.init)s
429429
430430
Note
431431
----
@@ -555,7 +555,7 @@ def format(
555555
----------------
556556
%(axes.format)s
557557
%(figure.format)s
558-
%(axes.rc)s
558+
%(rc.format)s
559559
560560
See also
561561
--------
@@ -690,11 +690,6 @@ def projection(self, map_projection):
690690
raise ValueError(f'Projection must be a {cls} instance.')
691691
self._map_projection = map_projection
692692

693-
# Apply signature obfuscation after getting keys
694-
# NOTE: This is needed for __init__
695-
_format_signature_proj = inspect.signature(format)
696-
format = docstring._obfuscate_kwargs(format)
697-
698693

699694
class _CartopyAxes(GeoAxes, _GeoAxes):
700695
"""
@@ -1416,3 +1411,9 @@ def _update_minor_gridlines(self, longrid=None, latgrid=None, nsteps=None):
14161411
axis.isDefault_majfmt = True
14171412
axis.isDefault_majloc = True
14181413
axis.isDefault_minloc = True
1414+
1415+
1416+
# Apply signature obfuscation after storing previous signature
1417+
GeoAxes._format_signatures[_CartopyAxes._name] = inspect.signature(GeoAxes.format)
1418+
GeoAxes._format_signatures[_BasemapAxes._name] = inspect.signature(GeoAxes.format)
1419+
GeoAxes.format = docstring._obfuscate_kwargs(GeoAxes.format)

proplot/axes/polar.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def __init__(self, *args, **kwargs):
119119
Other parameters
120120
----------------
121121
%(axes.format)s
122-
%(axes.rc)s
122+
%(rc.init)s
123123
124124
See also
125125
--------
@@ -232,7 +232,7 @@ def format(
232232
----------------
233233
%(axes.format)s
234234
%(figure.format)s
235-
%(axes.rc)s
235+
%(rc.format)s
236236
237237
See also
238238
--------
@@ -332,7 +332,8 @@ def format(
332332
# Parent format method
333333
super().format(rc_kw=rc_kw, rc_mode=rc_mode, **kwargs)
334334

335-
# Apply signature obfuscation after getting keys
336-
# NOTE: This is needed for __init__
337-
_format_signature_proj = inspect.signature(format)
338-
format = docstring._obfuscate_kwargs(format)
335+
336+
# Apply signature obfuscation after storing previous signature
337+
# NOTE: This is needed for __init__
338+
PolarAxes._format_signatures[PolarAxes._name] = inspect.signature(PolarAxes.format)
339+
PolarAxes.format = docstring._obfuscate_kwargs(PolarAxes.format)

proplot/figure.py

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,7 +1435,7 @@ def _align_content(): # noqa: E306
14351435

14361436
@docstring._snippet_manager
14371437
def format(
1438-
self, axs=None,
1438+
self, axs=None, *,
14391439
figtitle=None, suptitle=None, suptitle_kw=None,
14401440
llabels=None, leftlabels=None, leftlabels_kw=None,
14411441
rlabels=None, rightlabels=None, rightlabels_kw=None,
@@ -1451,15 +1451,8 @@ def format(
14511451
Parameters
14521452
----------
14531453
axs : sequence of `~proplot.axes.Axes`, optional
1454-
The axes to format.
1454+
The axes to format. Default is the numbered subplots.
14551455
%(figure.format)s
1456-
**kwargs
1457-
Passed to the projection-specific ``format`` command for each axes.
1458-
1459-
Other parameters
1460-
----------------
1461-
%(axes.format)s
1462-
%(axes.rc)s
14631456
14641457
Important
14651458
---------
@@ -1469,6 +1462,14 @@ def format(
14691462
change them for specific figures. But many :ref:`other configuration
14701463
settings <ug_format>` can be passed to ``format`` too.
14711464
1465+
Other parameters
1466+
----------------
1467+
%(axes.format)s
1468+
%(cartesian.format)s
1469+
%(polar.format)s
1470+
%(geo.format)s
1471+
%(rc.format)s
1472+
14721473
See also
14731474
--------
14741475
proplot.axes.Axes.format
@@ -1479,6 +1480,7 @@ def format(
14791480
proplot.config.Configurator.context
14801481
"""
14811482
# Initiate context block
1483+
axs = axs or self._subplot_dict.values()
14821484
skip_axes = kwargs.pop('skip_axes', False) # internal keyword arg
14831485
rc_kw, rc_mode = _pop_rc(kwargs)
14841486
with rc.context(rc_kw, mode=rc_mode):
@@ -1539,9 +1541,30 @@ def format(
15391541
# Update the main axes
15401542
if skip_axes: # avoid recursion
15411543
return
1542-
axs = axs or self._subplot_dict.values()
1544+
names = set() # track used dictionaries
1545+
dicts = {
1546+
name: _pop_params(kwargs, signature)
1547+
for name, signature in paxes.Axes._format_signatures.items()
1548+
}
15431549
for ax in axs:
1544-
ax.format(rc_kw=rc_kw, rc_mode=rc_mode, skip_figure=True, **kwargs)
1550+
dict_ = {}
1551+
for name in {None, ax._name}:
1552+
names.add(name)
1553+
dict_.update(dicts.get(name, {}))
1554+
ax.format(rc_kw=rc_kw, rc_mode=rc_mode, skip_figure=True, **dict_)
1555+
1556+
# Warn unused keyword argument(s)
1557+
kwargs.update(
1558+
{
1559+
key: value
1560+
for name in dicts.keys() - names
1561+
for key, value in dicts[name].items()
1562+
}
1563+
)
1564+
if kwargs:
1565+
warnings._warn_proplot(
1566+
f'Ignoring unrecognized format keyword argument(s): {kwargs}'
1567+
)
15451568

15461569
@docstring._concatenate_inherited
15471570
@docstring._snippet_manager

proplot/gridspec.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,7 +1109,7 @@ def update(self, **kwargs):
11091109
@property
11101110
def figure(self):
11111111
"""
1112-
The `proplot.figure.Figure` instance uniquely associated with this `GridSpec`.
1112+
The `proplot.figure.Figure` uniquely associated with this `GridSpec`.
11131113
On assignment the gridspec parameters and figure size are updated.
11141114
"""
11151115
return self._figure
@@ -1383,7 +1383,7 @@ def _validate_item(self, items, scalar=False):
13831383
return items
13841384

13851385
@docstring._snippet_manager
1386-
def format(self, *args, **kwargs):
1386+
def format(self, **kwargs):
13871387
"""
13881388
Call the ``format`` command for every axes in the grid.
13891389
@@ -1397,7 +1397,10 @@ def format(self, *args, **kwargs):
13971397
Other parameters
13981398
----------------
13991399
%(figure.format)s
1400-
%(axes.rc)s
1400+
%(cartesian.format)s
1401+
%(polar.format)s
1402+
%(geo.format)s
1403+
%(rc.format)s
14011404
14021405
See also
14031406
--------
@@ -1408,14 +1411,21 @@ def format(self, *args, **kwargs):
14081411
proplot.figure.Figure.format
14091412
proplot.config.Configurator.context
14101413
"""
1411-
for ax in self:
1412-
ax.format(*args, **kwargs)
1414+
self.figure.format(axs=self, **kwargs)
1415+
1416+
@property
1417+
def figure(self):
1418+
"""
1419+
The `proplot.figure.Figure` uniquely associated with this `SubplotGrid`.
1420+
This is used for the `SubplotGrid.format` command.
1421+
"""
1422+
return self.gridspec.figure
14131423

14141424
@property
14151425
def gridspec(self):
14161426
"""
1417-
The `~proplot.gridspec.GridSpec` associated with the grid. This is used
1418-
to resolve 2D indexing. See `~SubplotGrid.__getitem__` for details.
1427+
The `~proplot.gridspec.GridSpec` uniquely associated with this `SubplotGrid`.
1428+
This is used to resolve 2D indexing. See `~SubplotGrid.__getitem__` for details.
14191429
"""
14201430
# Return the gridspec associatd with the grid
14211431
if not self:

proplot/ui.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,8 @@ def subplots(*args, **kwargs):
185185
# Format keywords
186186
rc_kw, rc_mode = _pop_rc(kwargs)
187187
kwformat = _pop_params(kwargs, pfigure.Figure._format_signature)
188-
kwformat.update(_pop_params(kwargs, paxes.Axes._format_signature_base))
189-
for cls in (paxes.CartesianAxes, paxes.PolarAxes, paxes.GeoAxes):
190-
kwformat.update(_pop_params(kwargs, cls._format_signature_proj))
188+
for name, signature in paxes.Axes._format_signatures.items():
189+
kwformat.update(_pop_params(kwargs, signature))
191190
# Initialize
192191
fig = figure(rc_kw=rc_kw, **kwargs)
193192
axs = fig.add_subplots(*args, **kwsubs)

0 commit comments

Comments
 (0)