@@ -1759,6 +1759,25 @@ def get_tightbbox(self, renderer=None, bbox_extra_artists=None):
17591759
17601760 return _bbox
17611761
1762+ @staticmethod
1763+ def _norm_per_subplot_kw (per_subplot_kw ):
1764+ expanded = {}
1765+ for k , v in per_subplot_kw .items ():
1766+ if isinstance (k , tuple ):
1767+ for sub_key in k :
1768+ if sub_key in expanded :
1769+ raise ValueError (
1770+ f'The key { sub_key !r} appears multiple times.'
1771+ )
1772+ expanded [sub_key ] = v
1773+ else :
1774+ if k in expanded :
1775+ raise ValueError (
1776+ f'The key { k !r} appears multiple times.'
1777+ )
1778+ expanded [k ] = v
1779+ return expanded
1780+
17621781 @staticmethod
17631782 def _normalize_grid_string (layout ):
17641783 if '\n ' not in layout :
@@ -1771,7 +1790,8 @@ def _normalize_grid_string(layout):
17711790
17721791 def subplot_mosaic (self , mosaic , * , sharex = False , sharey = False ,
17731792 width_ratios = None , height_ratios = None ,
1774- empty_sentinel = '.' , subplot_kw = None , gridspec_kw = None ):
1793+ empty_sentinel = '.' ,
1794+ subplot_kw = None , per_subplot_kw = None , gridspec_kw = None ):
17751795 """
17761796 Build a layout of Axes based on ASCII art or nested lists.
17771797
@@ -1821,6 +1841,9 @@ def subplot_mosaic(self, mosaic, *, sharex=False, sharey=False,
18211841 The string notation allows only single character Axes labels and
18221842 does not support nesting but is very terse.
18231843
1844+ The Axes identifiers may be `str` or a non-iterable hashable
1845+ object (e.g. `tuple` s may not be used).
1846+
18241847 sharex, sharey : bool, default: False
18251848 If True, the x-axis (*sharex*) or y-axis (*sharey*) will be shared
18261849 among all subplots. In that case, tick label visibility and axis
@@ -1843,7 +1866,21 @@ def subplot_mosaic(self, mosaic, *, sharex=False, sharey=False,
18431866
18441867 subplot_kw : dict, optional
18451868 Dictionary with keywords passed to the `.Figure.add_subplot` call
1846- used to create each subplot.
1869+ used to create each subplot. These values may be overridden by
1870+ values in *per_subplot_kw*.
1871+
1872+ per_subplot_kw : dict, optional
1873+ A dictionary mapping the Axes identifiers or tuples of identifiers
1874+ to a dictionary of keyword arguments to be passed to the
1875+ `.Figure.add_subplot` call used to create each subplot. The values
1876+ in these dictionaries have precedence over the values in
1877+ *subplot_kw*.
1878+
1879+ If *mosaic* is a string, and thus all keys are single characters,
1880+ it is possible to use a single string instead of a tuple as keys;
1881+ i.e. ``"AB"`` is equivalent to ``("A", "B")``.
1882+
1883+ .. versionadded:: 3.7
18471884
18481885 gridspec_kw : dict, optional
18491886 Dictionary with keywords passed to the `.GridSpec` constructor used
@@ -1868,6 +1905,8 @@ def subplot_mosaic(self, mosaic, *, sharex=False, sharey=False,
18681905 """
18691906 subplot_kw = subplot_kw or {}
18701907 gridspec_kw = dict (gridspec_kw or {})
1908+ per_subplot_kw = per_subplot_kw or {}
1909+
18711910 if height_ratios is not None :
18721911 if 'height_ratios' in gridspec_kw :
18731912 raise ValueError ("'height_ratios' must not be defined both as "
@@ -1882,6 +1921,12 @@ def subplot_mosaic(self, mosaic, *, sharex=False, sharey=False,
18821921 # special-case string input
18831922 if isinstance (mosaic , str ):
18841923 mosaic = self ._normalize_grid_string (mosaic )
1924+ per_subplot_kw = {
1925+ tuple (k ): v for k , v in per_subplot_kw .items ()
1926+ }
1927+
1928+ per_subplot_kw = self ._norm_per_subplot_kw (per_subplot_kw )
1929+
18851930 # Only accept strict bools to allow a possible future API expansion.
18861931 _api .check_isinstance (bool , sharex = sharex , sharey = sharey )
18871932
@@ -2011,7 +2056,11 @@ def _do_layout(gs, mosaic, unique_ids, nested):
20112056 raise ValueError (f"There are duplicate keys { name } "
20122057 f"in the layout\n { mosaic !r} " )
20132058 ax = self .add_subplot (
2014- gs [slc ], ** {'label' : str (name ), ** subplot_kw }
2059+ gs [slc ], ** {
2060+ 'label' : str (name ),
2061+ ** subplot_kw ,
2062+ ** per_subplot_kw .get (name , {})
2063+ }
20152064 )
20162065 output [name ] = ax
20172066 elif method == 'nested' :
@@ -2048,9 +2097,11 @@ def _do_layout(gs, mosaic, unique_ids, nested):
20482097 if sharey :
20492098 ax .sharey (ax0 )
20502099 ax ._label_outer_yaxis (check_patch = True )
2051- for k , ax in ret .items ():
2052- if isinstance (k , str ):
2053- ax .set_label (k )
2100+ if extra := set (per_subplot_kw ) - set (ret ):
2101+ raise ValueError (
2102+ f"The keys { extra } are in *per_subplot_kw* "
2103+ "but not in the mosaic."
2104+ )
20542105 return ret
20552106
20562107 def _set_artist_props (self , a ):
0 commit comments