8000 Enable set_{x|y|}label(loc={'left','right','center','top','bottom'}) · matplotlib/matplotlib@3cb10ee · GitHub
[go: up one dir, main page]

Skip to content

Commit 3cb10ee

Browse files
committed
Enable set_{x|y|}label(loc={'left','right','center','top','bottom'})
1 parent e5283e0 commit 3cb10ee

File tree

8 files changed

+153
-10
lines changed

8 files changed

+153
-10
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Align labels to axes edges
2+
--------------------------
3+
`~.axes.Axes.set_xlabel`, `~.axes.Axes.set_ylabel` and `ColorbarBase.set_label`
4+
support a parameter ``loc`` for simplified positioning. Supported values are
5+
'left', 'center', 'right' The default is controlled via :rc:`xaxis.labelposition`
6+
and :rc:`yaxis.labelposition`; the Colorbar label takes the rcParam based on its
7+
orientation.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
"""
2+
===================
3+
Axis Label Position
4+
===================
5+
6+
Choose axis label position when calling `~.Axes.set_xlabel` and
7+
`~.Axes.set_ylabel` as well as for colorbar.
8+
9+
"""
10+
import matplotlib.pyplot as plt
11+
12+
fig, ax = plt.subplots()
13+
14+
sc = ax.scatter([1, 2], [1, 2], c=[1, 2])
15+
ax.set_ylabel('YLabel', loc='top')
16+
ax.set_xlabel('XLabel', loc='left')
17+
cbar = fig.colorbar(sc)
18+
cbar.set_label("ZLabel", loc='top')
19+
20+
plt.show()

lib/matplotlib/axes/_axes.py

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,8 @@ def get_xlabel(self):
188188
label = self.xaxis.get_label()
189189
return label.get_text()
190190

191-
def set_xlabel(self, xlabel, fontdict=None, labelpad=None, **kwargs):
191+
def set_xlabel(self, xlabel, fontdict=None, labelpad=None, *,
192+
loc=None, **kwargs):
192193
"""
193194
Set the label for the x-axis.
194195
@@ -201,6 +202,10 @@ def set_xlabel(self, xlabel, fontdict=None, labelpad=None, **kwargs):
201202
Spacing in points from the axes bounding box including ticks
202203
and tick labels.
203204
205+
loc : {'left', 'center', 'right'}, default: :rc:`xaxis.labellocation`
206+
The label position. This is a high-level alternative for passing
207+
parameters *x* and *horizonatalalignment*.
208+
204209
Other Parameters
205210
----------------
206211
**kwargs : `.Text` properties
@@ -212,6 +217,22 @@ def set_xlabel(self, xlabel, fontdict=None, labelpad=None, **kwargs):
212217
"""
213218
if labelpad is not None:
214219
self.xaxis.labelpad = labelpad
220+
_protected_kw = ['x', 'horizontalalignment', 'ha']
221+
if any([k in kwargs for k in _protected_kw]):
222+
if loc is not None:
223+
raise KeyError('Specifying *loc* is disallowed when any of '
224+
'its corresponding low level kwargs {} '
225+
'are supplied as well.'.format(_protected_kw))
226+
loc = 'center'
227+
else:
228+
loc = 9E12 loc if loc is not None else rcParams['xaxis.labellocation']
229+
cbook._check_in_list(('left', 'center', 'right'), loc=loc)
230+
if loc == 'right':
231+
kwargs['x'] = 1.
232+
kwargs['horizontalalignment'] = 'right'
233+
elif loc == 'left':
234+
kwargs['x'] = 0.
235+
kwargs['horizontalalignment'] = 'left'
215236
return self.xaxis.set_label_text(xlabel, fontdict, **kwargs)
216237

217238
def get_ylabel(self):
@@ -221,7 +242,8 @@ def get_ylabel(self):
221242
label = self.yaxis.get_label()
222243
return label.get_text()
223244

224-
def set_ylabel(self, ylabel, fontdict=None, labelpad=None, **kwargs):
245+
def set_ylabel(self, ylabel, fontdict=None, labelpad=None, *,
246+
loc=None, **kwargs):
225247
"""
226248
Set the label for the y-axis.
227249
@@ -234,6 +256,10 @@ def set_ylabel(self, ylabel, fontdict=None, labelpad=None, **kwargs):
234256
Spacing in points from the axes bounding box including ticks
235257
and tick labels.
236258
259+
loc : {'bottom', 'center', 'top'}, default: :rc:`yaxis.labellocation`
260+
The label position. This is a high-level alternative for passing
261+
parameters *y* and *horizonatalalignment*.
262+
237263
Other Parameters
238264
----------------
239265
**kwargs : `.Text` properties
@@ -246,6 +272,22 @@ def set_ylabel(self, ylabel, fontdict=None, labelpad=None, **kwargs):
246272
"""
247273
if labelpad is not None:
248274
self.yaxis.labelpad = labelpad
275+
_protected_kw = ['y', 'horizontalalignment', 'ha']
276+
if any([k in kwargs for k in _protected_kw]):
277+
if loc is not None:
278+
raise KeyError('Specifying *loc* is disallowed when any of '
279+
'its corresponding low level kwargs {} '
280+
'are supplied as well.'.format(_protected_kw))
281+
loc = 'center'
282+
else:
283+
loc = loc if loc is not None else rcParams['yaxis.labellocation']
284+
cbook._check_in_list(('bottom', 'center', 'top'), loc=loc)
285+
if loc == 'top':
286+
kwargs['y'] = 1.
287+
kwargs['horizontalalignment'] = 'right'
288+
elif loc == 'bottom':
289+
kwargs['y'] = 0.
290+
kwargs['horizontalalignment'] = 'left'
249291
return self.yaxis.set_label_text(ylabel, fontdict, **kwargs)
250292

251293
def get_legend_handles_labels(self, legend_handler_map=None):

lib/matplotlib/colorbar.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -738,10 +738,31 @@ def _set_label(self):
738738
self.ax.set_xlabel(self._label, **self._labelkw)
739739
self.stale = True
740740

741-
def set_label(self, label, **kw):
741+
def set_label(self, label, *, loc=None, **kwargs):
742742
"""Add a label to the long axis of the colorbar."""
743+
_pos_xy = 'y' if self.orientation == 'vertical' else 'x'
744+
_protected_kw = [_pos_xy, 'horizontalalignment', 'ha']
745+
if any([k in kwargs for k in _protected_kw]):
746+
if loc is not None:
747+
raise KeyError('Specifying *loc* is disallowed when any of '
748+
'its corresponding low level kwargs {} '
749+
'are supplied as well.'.format(_protected_kw))
750+
loc = 'center'
751+
else:
752+
if loc is None:
753+
loc = mpl.rcParams['%saxis.labellocation' % _pos_xy]
754+
if self.orientation == 'vertical':
755+
cbook._check_in_list(('bottom', 'center', 'top'), loc=loc)
756+
else:
757+
cbook._check_in_list(('left', 'center', 'top'), loc=loc)
758+
if loc in ['right', 'top']:
759+
kwargs[_pos_xy] = 1.
760+
kwargs['horizontalalignment'] = 'right'
761+
elif loc in ['left', 'bottom']:
762+
kwargs[_pos_xy] = 0.
763+
kwargs['horizontalalignment'] = 'left'
743764
self._label = label
744-
self._labelkw = kw
765+
self._labelkw = kwargs
745766
self._set_label()
746767

747768
def _outline(self, X, Y):

lib/matplotlib/pyplot.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2842,16 +2842,18 @@ def title(label, fontdict=None, loc=None, pad=None, **kwargs):
28422842

28432843
# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
28442844
@docstring.copy(Axes.set_xlabel)
2845-
def xlabel(xlabel, fontdict=None, labelpad=None, **kwargs):
2845+
def xlabel(xlabel, fontdict=None, labelpad=None, *, loc=None, **kwargs):
28462846
return gca().set_xlabel(
2847-
xlabel, fontdict=fontdict, labelpad=labelpad, **kwargs)
2847+
xlabel, fontdict=fontdict, labelpad=labelpad, loc=loc,
2848+
**kwargs)
28482849

28492850

28502851
# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
28512852
@docstring.copy(Axes.set_ylabel)
2852-
def ylabel(ylabel, fontdict=None, labelpad=None, **kwargs):
2853+
def ylabel(ylabel, fontdict=None, labelpad=None, *, loc=None, **kwargs):
28532854
return gca().set_ylabel(
2854-
ylabel, fontdict=fontdict, labelpad=labelpad, **kwargs)
2855+
ylabel, fontdict=fontdict, labelpad=labelpad, loc=loc,
2856+
**kwargs)
28552857

28562858

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

lib/matplotlib/rcsetup.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -988,7 +988,12 @@ def validate_webagg_address(s):
988988
raise ValueError("'webagg.address' is not a valid IP address")
989989

990990

991-
validate_axes_titlelocation = ValidateInStrings('axes.titlelocation', ['left', 'center', 'right'])
991+
_validate_axes_titlelocation = ValidateInStrings('axes.titlelocation',
992+
['left', 'center', 'right'])
993+
_validate_xaxis_labellocation = ValidateInStrings('xaxis.labellocation',
994+
['left', 'center', 'right'])
995+
_validate_yaxis_labellocation = ValidateInStrings('yaxis.labellocation',
996+
['bottom', 'center', 'top'])
992997

993998
# a map from key -> value, converter
994999
defaultParams = {
@@ -1172,7 +1177,7 @@ def validate_webagg_address(s):
11721177

11731178
'axes.titlesize': ['large', validate_fontsize], # fontsize of the
11741179
# axes title
1175-
'axes.titlelocation': ['center', validate_axes_titlelocation], # alignment of axes title
1180+
'axes.titlelocation': ['center', _validate_axes_titlelocation], # alignment of axes title
11761181
'axes.titleweight': ['normal', validate_fontweight], # font weight of axes title
11771182
'axes.titlecolor': ['auto', validate_color_or_auto], # font color of axes title
11781183
'axes.titlepad': [6.0, validate_float], # pad from axes top to title in points
@@ -1219,6 +1224,10 @@ def validate_webagg_address(s):
12191224
'polaraxes.grid': [True, validate_bool], # display polar grid or not
12201225
'axes3d.grid': [True, validate_bool], # display 3d grid
12211226

1227+
# axis props
1228+
'xaxis.labellocation': ['center', _validate_xaxis_labellocation], # alignment of axis title
1229+
'yaxis.labellocation': ['center', _validate_yaxis_labellocation], # alignment of axis title
1230+
12221231
# scatter props
12231232
'scatter.marker': ['o', validate_string],
12241233
'scatter.edgecolors': ['face', validate_string],

lib/matplotlib/tests/test_axes.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,42 @@ def test_get_labels():
4545
assert ax.get_ylabel() == 'y label'
4646

4747

48+
@check_figures_equal()
49+
def test_labels_pos(fig_test, fig_ref):
50+
ax = fig_test.subplots()
51+
sc = ax.scatter([1, 2], [1, 2], c=[1, 2])
52+
ax.set_ylabel('YLabel', loc='top')
53+
ax.set_xlabel('XLabel', loc='left')
54+
cbar = fig_test.colorbar(sc)
55+
cbar.set_label("ZLabel", loc='top')
56+
57+
ax = fig_ref.subplots()
58+
sc = ax.scatter([1, 2], [1, 2], c=[1, 2])
59+
ax.set_ylabel('YLabel', ha='right', y=1.)
60+
ax.set_xlabel('XLabel', ha='left', x=0.)
61+
cbar = fig_ref.colorbar(sc)
62+
cbar.set_label("ZLabel", ha='right', y=1.)
63+
64+
65+
@check_figures_equal()
66+
def test_labels_pos_rc(fig_test, fig_ref):
67+
ax = fig_test.subplots()
68+
with plt.style.context({'xaxis.labellocation': 'left',
69+
'yaxis.labellocation': 'top'}):
70+
sc = ax.scatter([1, 2], [1, 2], c=[1, 2])
71+
ax.set_ylabel('YLabel')
72+
ax.set_xlabel('XLabel')
73+
cbar = fig_test.colorbar(sc)
74+
cbar.set_label("ZLabel")
75+
76+
ax = fig_ref.subplots()
77+
sc = ax.scatter([1, 2], [1, 2], c=[1, 2])
78+
ax.set_ylabel('YLabel', ha='right', y=1.)
79+
ax.set_xlabel('XLabel', ha='left', x=0.)
80+
cbar = fig_ref.colorbar(sc)
81+
cbar.set_label("ZLabel", ha='right', y=1.)
82+
83+
4884
@image_comparison(['acorr.png'], style='mpl20')
4985
def test_acorr():
5086
# Remove this line when this test image is regenerated.

matplotlibrc.template

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,12 @@
416416
#polaraxes.grid : True ## display grid on polar axes
417417
#axes3d.grid : True ## display grid on 3d axes
418418

419+
## ***************************************************************************
420+
## * AXIS *
421+
## ***************************************************************************
422+
#xaxis.labellocation : center ## alignment of the xaxis label: {left, right, center}
423+
#yaxis.labellocation : center ## alignment of the yaxis label: {bottom, top, center}
424+
419425

420426
## ***************************************************************************
421427
## * DATES *

0 commit comments

Comments
 (0)
0