Skip to content

Commit 9bb232b

Browse files
committed
ENH: allow title autopositioning to be turned off
1 parent 47a15d9 commit 9bb232b

File tree

7 files changed

+35
-21
lines changed

7 files changed

+35
-21
lines changed

lib/matplotlib/axes/_axes.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ def get_title(self, loc="center"):
114114
title = cbook._check_getitem(titles, loc=loc.lower())
115115
return title.get_text()
116116

117-
def set_title(self, label, fontdict=None, loc=None, pad=None, **kwargs):
117+
def set_title(self, label, fontdict=None, loc=None, y=None, pad=None,
118+
**kwargs):
118119
"""
119120
Set a title for the axes.
120121
@@ -140,6 +141,11 @@ def set_title(self, label, fontdict=None, loc=None, pad=None, **kwargs):
140141
loc : {'center', 'left', 'right'}, default: :rc:`axes.titlelocation`
141142
Which title to set.
142143
144+
y : float, default: :rc:`axes.titley`
145+
Vertical axes loation for the title (1.0 is the top). If
146+
None (the default), y is determined automatically to avoid
147+
decorators on the axes.
148+
143149
pad : float, default: :rc:`axes.titlepad`
144150
The offset of the title from the top of the axes, in points.
145151
@@ -157,6 +163,14 @@ def set_title(self, label, fontdict=None, loc=None, pad=None, **kwargs):
157163
if loc is None:
158164
loc = rcParams['axes.titlelocation']
159165

166+
if y is None:
167+
y = rcParams['axes.titley']
168+
if y is None:
169+
y = 1.0
170+
else:
171+
self._autotitlepos = False
172+
kwargs['y'] = y
173+
160174
titles = {'left': self._left_title,
161175
'center': self.title,
162176
'right': self._right_title}

lib/matplotlib/axes/_base.py

+10-15
Original file line numberDiff line numberDiff line change
@@ -1122,19 +1122,26 @@ def cla(self):
11221122
size=mpl.rcParams['axes.titlesize'],
11231123
weight=mpl.rcParams['axes.titleweight'])
11241124

1125+
y = mpl.rcParams['axes.titley']
1126+
if y is None:
1127+
y = 1.0
1128+
self._autotitlepos = True
1129+
else:
1130+
self._autotitlepos = False
1131+
11251132
self.title = mtext.Text(
1126-
x=0.5, y=1.0, text='',
1133+
x=0.5, y=y, text='',
11271134
fontproperties=props,
11281135
verticalalignment='baseline',
11291136
horizontalalignment='center',
11301137
)
11311138
self._left_title = mtext.Text(
1132-
x=0.0, y=1.0, text='',
1139+
x=0.0, y=y, text='',
11331140
fontproperties=props.copy(),
11341141
verticalalignment='baseline',
11351142
horizontalalignment='left', )
11361143
self._right_title = mtext.Text(
1137-
x=1.0, y=1.0, text='',
1144+
x=1.0, y=y, text='',
11381145
fontproperties=props.copy(),
11391146
verticalalignment='baseline',
11401147
horizontalalignment='right',
@@ -1143,8 +1150,6 @@ def cla(self):
11431150
# refactor this out so it can be called in ax.set_title if
11441151
# pad argument used...
11451152
self._set_title_offset_trans(title_offset_points)
1146-
# determine if the title position has been set manually:
1147-
self._autotitlepos = None
11481153

11491154
for _title in (self.title, self._left_title, self._right_title):
11501155
self._set_artist_props(_title)
@@ -2622,16 +2627,6 @@ def _update_title_position(self, renderer):
26222627

26232628
titles = (self.title, self._left_title, self._right_title)
26242629

2625-
if self._autotitlepos is None:
2626-
for title in titles:
2627-
x, y = title.get_position()
2628-
if not np.isclose(y, 1.0):
2629-
self._autotitlepos = False
2630-
_log.debug('not adjusting title pos because a title was '
2631-
'already placed manually: %f', y)
2632-
return
2633-
self._autotitlepos = True
2634-
26352630
for title in titles:
26362631
x, _ = title.get_position()
26372632
# need to start again in case of window resizing

lib/matplotlib/mpl-data/stylelib/classic.mplstyle

+2-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ mathtext.sf : sans\-serif
155155
mathtext.fontset : cm # Should be 'cm' (Computer Modern), 'stix',
156156
# 'stixsans' or 'custom'
157157
mathtext.fallback: cm # Select fallback font from ['cm' (Computer Modern), 'stix'
158-
# 'stixsans'] when a symbol can not be found in one of the
158+
# 'stixsans'] when a symbol can not be found in one of the
159159
# custom math fonts. Select 'None' to not perform fallback
160160
# and replace the missing character by a dummy.
161161

@@ -175,6 +175,7 @@ axes.grid : False # display grid or not
175175
axes.grid.which : major
176176
axes.grid.axis : both
177177
axes.titlesize : large # fontsize of the axes title
178+
axes.titley : 1.0 # at the top, no autopositioning.
178179
axes.titlepad : 5.0 # pad between axes and title in points
179180
axes.titleweight : normal # font weight for axes title
180181
axes.labelsize : medium # fontsize of the x any y labels

lib/matplotlib/pyplot.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -2931,9 +2931,9 @@ def sci(im):
29312931

29322932
# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
29332933
@_copy_docstring_and_deprecators(Axes.set_title)
2934-
def title(label, fontdict=None, loc=None, pad=None, **kwargs):
2934+
def title(label, fontdict=None, loc=None, y=None, pad=None, **kwargs):
29352935
return gca().set_title(
2936-
label, fontdict=fontdict, loc=loc, pad=pad, **kwargs)
2936+
label, fontdict=fontdict, loc=loc, y=y, pad=pad, **kwargs)
29372937

29382938

29392939
# Autogenerated by boilerplate.py. Do not edit as changes will be lost.

lib/matplotlib/rcsetup.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1219,7 +1219,8 @@ def _convert_validator_spec(key, conv):
12191219
'axes.titlelocation': ['center', ['left', 'center', 'right']], # alignment of axes title
12201220
'axes.titleweight': ['normal', validate_fontweight], # font weight of axes title
12211221
'axes.titlecolor': ['auto', validate_color_or_auto], # font color of axes title
1222-
'axes.titlepad': [6.0, validate_float], # pad from axes top to title in points
1222+
'axes.titley': [None, validate_float_or_None], # title location, axes units, None means auto
1223+
'axes.titlepad': [6.0, validate_float], # pad from axes top decoration to title in points
12231224
'axes.grid': [False, validate_bool], # display grid or not
12241225
'axes.grid.which': ['major', ['minor', 'both', 'major']], # set whether the grid is drawn on
12251226
# 'major' 'minor' or 'both' ticks

lib/matplotlib/tests/test_axes.py

+2
Original file line numberDiff line numberDiff line change
@@ -5522,6 +5522,7 @@ def test_titlesetpos():
55225522

55235523
def test_title_xticks_top():
55245524
# Test that title moves if xticks on top of axes.
5525+
mpl.rcParams['axes.titley'] = None
55255526
fig, ax = plt.subplots()
55265527
ax.xaxis.set_ticks_position('top')
55275528
ax.set_title('xlabel top')
@@ -5531,6 +5532,7 @@ def test_title_xticks_top():
55315532

55325533
def test_title_xticks_top_both():
55335534
# Test that title moves if xticks on top of axes.
5535+
mpl.rcParams['axes.titley'] = None
55345536
fig, ax = plt.subplots()
55355537
ax.tick_params(axis="x",
55365538
bottom=True, top=True, labelbottom=True, labeltop=True)

matplotlibrc.template

+2-1
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@
326326
#mathtext.sf: sans
327327
#mathtext.tt: monospace
328328
#mathtext.fallback: cm # Select fallback font from ['cm' (Computer Modern), 'stix'
329-
# 'stixsans'] when a symbol can not be found in one of the
329+
# 'stixsans'] when a symbol can not be found in one of the
330330
# custom math fonts. Select 'None' to not perform fallback
331331
# and replace the missing character by a dummy symbol.
332332
#mathtext.default: it # The default font to use for math.
@@ -352,6 +352,7 @@
352352
#axes.titleweight: normal # font weight of title
353353
#axes.titlecolor: auto # color of the axes title, auto falls back to
354354
# text.color as default value
355+
#axes.titley: None # position title (axes relative units). None implies auto
355356
#axes.titlepad: 6.0 # pad between axes and title in points
356357
#axes.labelsize: medium # fontsize of the x any y labels
357358
#axes.labelpad: 4.0 # space between label and axis

0 commit comments

Comments
 (0)