Add rcParams for figure.suptitle() kwargs (x, y, horizontalalignment, verticalalignment) by szzhoujiarui-sketch · Pull Request #31889 · matplotlib/matplotlib · GitHub
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
94ff8ca
feat(figure): add rcParams for suptitle/suplabel position and alignment
szzhoujiarui-sketch Jun 13, 2026
40972ef
feat(rcsetup): add validators for figure title/label position and ali…
szzhoujiarui-sketch Jun 13, 2026
a0f110c
feat(config): add default rcParams for figure title/label position an…
szzhoujiarui-sketch Jun 13, 2026
71e32f9
test(figure): add tests for suptitle/suplabel rcParams
szzhoujiarui-sketch Jun 13, 2026
04df524
fix(figure): add :rc: role to va default in _suplabels docstring
szzhoujiarui-sketch Jun 13, 2026
335681e
fix(figure): add :rc: role to va default in _suplabels docstring
szzhoujiarui-sketch Jun 13, 2026
0ac8e76
feat(rcsetup): add _Param entries for figure title/label position and…
szzhoujiarui-sketch Jun 13, 2026
d46b5d1
refactor(figure): only add rcParams for suptitle, keep supxlabel/supy…
szzhoujiarui-sketch Jun 13, 2026
8014361
refactor(rcsetup): only add rcParams validators for suptitle position…
szzhoujiarui-sketch Jun 13, 2026
d5a6a70
refactor(config): only add rcParams for suptitle position and alignment
szzhoujiarui-sketch Jun 13, 2026
4f00670
refactor(test): only test suptitle rcParams, remove supxlabel/supylab…
szzhoujiarui-sketch Jun 13, 2026
4a2d4d0
fix(rcsetup): restore from upstream, add only suptitle rcParams
szzhoujiarui-sketch Jun 13, 2026
228c4f5
feat(rcsetup): add _Param entries for figure.title_x/y/ha/va
szzhoujiarui-sketch Jun 13, 2026
a5a8d32
fix: add new figure.title_* rcParams to typing stubs
szzhoujiarui-sketch Jun 14, 2026
aacdb24
fix: add trailing newline to test_figure.py
szzhoujiarui-sketch Jun 14, 2026
4349727
refactor: simplify rcParams fallback logic for suptitle x/y
szzhoujiarui-sketch Jun 14, 2026
aac8c42
Fix: revert invalid :rc: references in shared _suplabels docstring
szzhoujiarui-sketch Jun 16, 2026
8f58fa0
Fix: pytest 10 compatibility in TestSpectral class-scoped fixture
szzhoujiarui-sketch Jun 16, 2026
9cc07f6
revert: remove unnecessary test_mlab.py changes (pytest pinned on main)
szzhoujiarui-sketch Jun 17, 2026
1c14c7d
revert test_mlab.py to match upstream main (pytest 10 fix already mer…
szzhoujiarui-sketch Jun 26, 2026
721a66b
Merge branch 'main' into fix/24090-suptitle-rcparams
szzhoujiarui-sketch Jun 26, 2026
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
27 changes: 19 additions & 8 deletions lib/matplotlib/figure.py
4 changes: 4 additions & 0 deletions lib/matplotlib/mpl-data/matplotlibrc
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,10 @@
## 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.title_x: 0.5 # x location of the figure title in figure coordinates
#figure.title_y: 0.98 # y location of the figure title in figure coordinates
#figure.title_horizontalalignment: center # horizontal alignment of the figure title
#figure.title_verticalalignment: 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
28 changes: 28 additions & 0 deletions lib/matplotlib/rcsetup.py
Original file line number Diff line number Diff line change
Expand Up @@ -1349,6 +1349,10 @@ def _convert_validator_spec(key, conv):
# figure title
"figure.titlesize": validate_fontsize,
"figure.titleweight": validate_fontweight,
"figure.title_x": validate_float,
"figure.title_y": validate_float,
"figure.title_horizontalalignment": ["center", "left", "right"],
"figure.title_verticalalignment": ["top", "center", "bottom", "baseline"],

# figure labels
"figure.labelsize": validate_fontsize,
Expand Down Expand Up @@ -2769,6 +2773,30 @@ class _Subsection:
validator=validate_fontweight,
description="weight of the figure title"
),
_Param(
"figure.title_x",
default=0.5,
validator=validate_float,
description="x location of the figure title in figure coordinates"
),
_Param(
"figure.title_y",
default=0.98,
validator=validate_float,
description="y location of the figure title in figure coordinates"
),
_Param(
"figure.title_horizontalalignment",
default="center",
validator=["center", "left", "right"],
description="horizontal alignment of the figure title"
),
_Param(
"figure.title_verticalalignment",
default="top",
validator=["top", "center", "bottom", "baseline"],
description="vertical alignment of the figure title"
),
_Param(
"figure.labelsize",
default="large",
Expand Down
72 changes: 72 additions & 0 deletions lib/matplotlib/tests/test_figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -1900,3 +1900,75 @@ def test_figsize_both_none():
def test_figsize_invalid_unit():
with pytest.raises(ValueError, match="Invalid unit 'um'"):
plt.figure(figsize=(6, 4, "um"))



def test_suptitle_rcparams():
"""Test that suptitle respects figure.title_* rcParams."""
rc = {
'figure.title_x': 0.3,
'figure.title_y': 0.9,
'figure.title_horizontalalignment': 'left',
'figure.title_verticalalignment': 'bottom',
}
with plt.rc_context(rc=rc):
fig = plt.figure()
t = fig.suptitle("test")
assert t.get_position() == (0.3, 0.9)
assert t.get_horizontalalignment() == 'left'
assert t.get_verticalalignment() == 'bottom'


def test_suptitle_rcparams_override():
"""Test that explicit kwargs override rcParams for suptitle."""
rc = {
'figure.title_x': 0.3,
'figure.title_y': 0.9,
'figure.title_horizontalalignment': 'left',
'figure.title_verticalalignment': 'bottom',
}
with plt.rc_context(rc=rc):
fig = plt.figure()
t = fig.suptitle("test", x=0.7, y=0.5,
horizontalalignment='right',
verticalalignment='top')
assert t.get_position() == (0.7, 0.5)
assert t.get_horizontalalignment() == 'right'
assert t.get_verticalalignment() == 'top'


def test_supxlabel_defaults_unchanged():
"""Test that supxlabel defaults are unchanged (regression test)."""
fig = plt.figure()
t = fig.supxlabel("test xlabel")
assert t.get_position() == (0.5, 0.01)
assert t.get_horizontalalignment() == 'center'
assert t.get_verticalalignment() == 'bottom'


def test_supylabel_defaults_unchanged():
"""Test that supylabel defaults are unchanged (regression test)."""
fig = plt.figure()
t = fig.supylabel("test ylabel")
assert t.get_position() == (0.02, 0.5)
assert t.get_horizontalalignment() == 'left'
assert t.get_verticalalignment() == 'center'


def test_suptitle_rcparams_all_alignments():
"""Test all valid alignment values for suptitle rcParams."""
import itertools
haligns = ['center', 'left', 'right']
valigns = ['top', 'center', 'bottom', 'baseline']
for ha, va in itertools.product(haligns, valigns):
rc = {
'figure.title_x': 0.5,
'figure.title_y': 0.98,
'figure.title_horizontalalignment': ha,
'figure.title_verticalalignment': va,
}
with plt.rc_context(rc=rc):
fig = plt.figure()
t = fig.suptitle("test")
assert t.get_horizontalalignment() == ha
assert t.get_verticalalignment() == va
4 changes: 4 additions & 0 deletions lib/matplotlib/typing.py
Loading