|
296 | 296 |
|
297 | 297 | # Format docstrings
|
298 | 298 | _axes_format_docstring = """
|
299 |
| -title : str, optional |
300 |
| - The axes title. |
301 |
| -abc : bool or str or tuple, default: :rc:`abc` |
| 299 | +title : str or sequence, optional |
| 300 | + The axes title. Can optionally be a sequence strings, in which case |
| 301 | + the title will be selected from the sequence according to `~Axes.number`. |
| 302 | +abc : bool or str or sequence, default: :rc:`abc` |
302 | 303 | The "a-b-c" subplot label style. Must contain the character ``a`` or ``A``,
|
303 | 304 | for example ``'a.'``, or ``'A'``. If ``True`` then the default style of
|
304 | 305 | ``'a'`` is used. The ``a`` or ``A`` is replaced with the alphabetic character
|
305 | 306 | matching the `~Axes.number`. If `~Axes.number` is greater than 26, the
|
306 | 307 | characters loop around to a, ..., z, aa, ..., zz, aaa, ..., zzz, etc.
|
| 308 | + Can also be a sequence of strings, in which case the "a-b-c" label |
| 309 | + will simply be selected from the sequence according to `~Axes.number`. |
307 | 310 | abcloc, titleloc : str, default: :rc:`abc.loc`, :rc:`title.loc`
|
308 | 311 | Strings indicating the location for the a-b-c label and main title.
|
309 | 312 | The following locations are valid:
|
|
345 | 348 | The horizontal padding between a-b-c labels and titles in the same location.
|
346 | 349 | %(units.pt)s
|
347 | 350 | ltitle, ctitle, rtitle, ultitle, uctitle, urtitle, lltitle, lctitle, lrtitle \
|
348 |
| -: str, tuple, optional |
| 351 | +: str or sequence, optional |
349 | 352 | Shorthands for the below keywords.
|
350 | 353 | lefttitle, centertitle, righttitle, upperlefttitle, uppercentertitle, upperrighttitle, \
|
351 |
| -lowerlefttitle, lowercentertitle, lowerrighttitle : str, tuple, optional |
352 |
| - Additional titles in specific positions. This works as an alternative |
353 |
| - to the ``ax.format(title='Title', titleloc=loc)`` workflow and permits |
354 |
| - adding more than one title-like label for a single axes. |
| 354 | +lowerlefttitle, lowercentertitle, lowerrighttitle : str or sequence, optional |
| 355 | + Additional titles in specific positions (see `title` for details). This works as |
| 356 | + an alternative to the ``ax.format(title='Title', titleloc=loc)`` workflow and |
| 357 | + permits adding more than one title-like label for a single axes. |
355 | 358 | a, alpha, fc, facecolor, ec, edgecolor, lw, linewidth, ls, linestyle : default: \
|
356 | 359 | :rc:`axes.alpha`, :rc:`axes.facecolor`, :rc:`axes.edgecolor`, :rc:`axes.linewidth`, '-'
|
357 | 360 | Additional settings applied to the background patch, and their
|
358 |
| - shorthands. Defaults are the ``'axes'`` properties. |
| 361 | + shorthands. Their defaults values are the ``'axes'`` properties. |
359 | 362 | """
|
360 | 363 | _figure_format_docstring = """
|
361 | 364 | rowlabels, collabels, llabels, tlabels, rlabels, blabels
|
@@ -2285,20 +2288,30 @@ def _update_abc(self, **kwargs):
|
2285 | 2288 | self._abc_border_kwargs.update(kwb)
|
2286 | 2289 |
|
2287 | 2290 | # A-b-c labels. Build as a...z...aa...zz...aaa...zzz
|
| 2291 | + # NOTE: The abc string should already be validated here |
2288 | 2292 | abc = rc.find('abc', context=True) # 1st run, or changed
|
2289 | 2293 | if abc is True:
|
2290 | 2294 | abc = 'a'
|
2291 |
| - if isinstance(abc, tuple): |
2292 |
| - kw['text'] = abc[self.number - 1] |
2293 |
| - elif abc and (not isinstance(abc, str) or 'a' not in abc and 'A' not in abc): |
2294 |
| - raise ValueError(f'Invalid style {abc!r}. Must include letter "a" or "A"') |
2295 |
| - if isinstance(abc, str) and self.number is not None: |
| 2295 | + if abc is False: |
| 2296 | + abc = '' |
| 2297 | + if abc is None or self.number is None: |
| 2298 | + pass |
| 2299 | + elif isinstance(abc, str): |
2296 | 2300 | nabc, iabc = divmod(self.number - 1, 26)
|
2297 |
| - old = re.search('[aA]', abc).group() # return the *first* 'a' or 'A' |
2298 |
| - new = (nabc + 1) * ABC_STRING[iabc] |
2299 |
| - new = new.upper() if old == 'A' else new |
2300 |
| - abc = abc.replace(old, new, 1) |
2301 |
| - kw['text'] = abc or '' |
| 2301 | + if abc: # should have been validated to contain 'a' or 'A' |
| 2302 | + old = re.search('[aA]', abc).group() # return first occurrence |
| 2303 | + new = (nabc + 1) * ABC_STRING[iabc] |
| 2304 | + new = new.upper() if old == 'A' else new |
| 2305 | + abc = abc.replace(old, new, 1) # replace first occurrence |
| 2306 | + kw['text'] = abc |
| 2307 | + else: |
| 2308 | + if self.number > len(abc): |
| 2309 | + raise ValueError( |
| 2310 | + f'Invalid abc list length {len(abc)} ' |
| 2311 | + f'for axes with number {self.number}.' |
| 2312 | + ) |
| 2313 | + else: |
| 2314 | + kw['text'] = abc[self._number - 1] |
2302 | 2315 |
|
2303 | 2316 | # Update a-b-c label
|
2304 | 2317 | loc = rc.find('abc.loc', context=True)
|
@@ -2371,10 +2384,22 @@ def _update_title(self, loc, title=None, **kwargs):
|
2371 | 2384 | # necesssary. For inner panels, use the border and bbox settings.
|
2372 | 2385 | if loc not in ('left', 'right', 'center'):
|
2373 | 2386 | kw.update(self._title_border_kwargs)
|
2374 |
| - if isinstance(title, tuple): |
2375 |
| - kw['text'] = title[self.number - 1] |
2376 |
| - elif title is not None: |
| 2387 | + if title is None: |
| 2388 | + pass |
| 2389 | + elif isinstance(title, str): |
2377 | 2390 | kw['text'] = title
|
| 2391 | + elif np.iterable(title) and all(isinstance(_, str) for _ in title): |
| 2392 | + if self.number is None: |
| 2393 | + pass |
| 2394 | + elif self.number > len(title): |
| 2395 | + raise ValueError( |
| 2396 | + f'Invalid title list length {len(title)} ' |
| 2397 | + f'for axes with number {self.number}.' |
| 2398 | + ) |
| 2399 | + else: |
| 2400 | + kw['text'] = title[self.number - 1] |
| 2401 | + else: |
| 2402 | + raise ValueError(f'Invalid title {title!r}. Must be string(s).') |
2378 | 2403 | kw.update(kwargs)
|
2379 | 2404 | self._title_dict[loc].update(kw)
|
2380 | 2405 |
|
|
0 commit comments