Skip to content
Closed
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
24 changes: 21 additions & 3 deletions lib/matplotlib/figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,12 @@ def _suplabels(self, t, info, **kwargs):
fontweight, weight : default: :rc:`figure.%(rc)sweight`
The font weight of the text. See `.Text.set_weight` for possible
values.
horizontalalignment, ha : {'center', 'left', 'right'}, \
default: :rc:`figure.titlehorizontalalign`
The horizontal alignment of the text relative to (*x*, *y*).
verticalalignment, va : {'top', 'center', 'bottom', 'baseline'}, \
default: :rc:`figure.titleverticalalign`
The vertical alignment of the text relative to (*x*, *y*).

Returns
-------
Expand Down Expand Up @@ -360,8 +366,18 @@ def _suplabels(self, t, info, **kwargs):
y = info['y0']

kwargs = cbook.normalize_kwargs(kwargs, Text)
kwargs.setdefault('horizontalalignment', info['ha'])
kwargs.setdefault('verticalalignment', info['va'])

# Resolve defaults: rcParam key if present, else hardcoded fallback
ha_key = info.get('horizontalalign')
va_key = info.get('verticalalign')
kwargs.setdefault(
'horizontalalignment',
mpl.rcParams[ha_key] if ha_key else info['ha'],
)
kwargs.setdefault(
'verticalalignment',
mpl.rcParams[va_key] if va_key else info['va'],
)
kwargs.setdefault('rotation', info['rotation'])

if 'fontproperties' not in kwargs:
Expand Down Expand Up @@ -394,7 +410,9 @@ def suptitle(self, t, **kwargs):
# docstring from _suplabels...
info = {'name': '_suptitle', 'x0': 0.5, 'y0': 0.98,
'ha': 'center', 'va': 'top', 'rotation': 0,
'size': 'figure.titlesize', 'weight': 'figure.titleweight'}
'size': 'figure.titlesize', 'weight': 'figure.titleweight',
'horizontalalign': 'figure.titlehorizontalalign',
'verticalalign': 'figure.titleverticalalign'}
return self._suplabels(t, info, **kwargs)

def get_suptitle(self):
Expand Down
6 changes: 4 additions & 2 deletions lib/matplotlib/mpl-data/matplotlibrc
Original file line number Diff line number Diff line change
Expand Up @@ -599,8 +599,10 @@
## * FIGURE *
## ***************************************************************************
## See https://matplotlib.org/stable/api/figure_api.html#matplotlib.figure.Figure
#figure.titlesize: large # size of the figure title (``Figure.suptitle()``)
#figure.titleweight: normal # weight of the figure title
#figure.titlesize: large # size of the figure title (``Figure.suptitle()``)
#figure.titleweight: normal # weight of the figure title
#figure.titlehorizontalalign: center # horizontal alignment of the figure title
#figure.titleverticalalign: top # vertical alignment of the figure title
#figure.labelsize: large # size of the figure label (``Figure.sup[x|y]label()``)
#figure.labelweight: normal # weight of the figure label
#figure.figsize: 6.4, 4.8 # figure size in inches
Expand Down
29 changes: 27 additions & 2 deletions lib/matplotlib/rcsetup.py
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,15 @@ def validate_fontsize(s):
validate_fontsizelist = _listify_validator(validate_fontsize)


def validate_suptitle_ha(s):
"""
Validate horizontal alignment for suptitle rcParams.
"""
return _str_to_one_of(
['center', 'left', 'right', 'center_left', 'center_right'],
)(s)


def validate_fontweight(s):
weights = [
'ultralight', 'light', 'normal', 'regular', 'book', 'medium', 'roman',
Expand Down Expand Up @@ -1347,8 +1356,12 @@ def _convert_validator_spec(key, conv):

## figure props
# figure title
"figure.titlesize": validate_fontsize,
"figure.titleweight": validate_fontweight,
"figure.titlesize": validate_fontsize,
"figure.titleweight": validate_fontweight,
"figure.titlehorizontalalign": validate_suptitle_ha,
# Validate that suptitle rcParams are set together to avoid inconsistent defaults
# if someone sets ha but not va (or vice versa) — the pair should change together.
"figure.titleverticalalign": validate_verticalalignment,

# figure labels
"figure.labelsize": validate_fontsize,
Expand Down Expand Up @@ -2769,6 +2782,18 @@ class _Subsection:
validator=validate_fontweight,
description="weight of the figure title"
),
_Param(
"figure.titlehorizontalalign",
default="center",
validator=validate_suptitle_ha,
description="horizontal alignment of the figure title (``Figure.suptitle()``)"
),
_Param(
"figure.titleverticalalign",
default="top",
validator=validate_verticalalignment,
description="vertical alignment of the figure title (``Figure.suptitle()``)"
),
_Param(
"figure.labelsize",
default="large",
Expand Down
24 changes: 24 additions & 0 deletions lib/matplotlib/tests/test_figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -1685,6 +1685,30 @@ def test_rcparams(fig_test, fig_ref):
fig_test.suptitle("Title")


def test_suptitle_rcparams_alignment():
"""Test that suptitle respects figure.titlehorizontalalign and titleverticalalign."""
fig, ax = plt.subplots()
with mpl.rc_context({
'figure.titlehorizontalalign': 'left',
'figure.titleverticalalign': 'center',
}):
txt = fig.suptitle("Title")
assert txt.get_horizontalalignment() == 'left'
assert txt.get_verticalalignment() == 'center'


def test_suptitle_rcparams_alignment_override():
"""Test that explicit kwargs override suptitle rcParams defaults."""
fig, ax = plt.subplots()
with mpl.rc_context({
'figure.titlehorizontalalign': 'left',
'figure.titleverticalalign': 'center',
}):
txt = fig.suptitle("Title", ha='right', va='bottom')
assert txt.get_horizontalalignment() == 'right'
assert txt.get_verticalalignment() == 'bottom'


def test_deepcopy():
fig1, ax = plt.subplots()
ax.plot([0, 1], [2, 3])
Expand Down
2 changes: 2 additions & 0 deletions lib/matplotlib/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,8 @@
"figure.subplot.wspace",
"figure.titlesize",
"figure.titleweight",
"figure.titlehorizontalalign",
"figure.titleverticalalign",
"font.cursive",
"font.enable_last_resort",
"font.family",
Expand Down
Loading