Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 33b3015

Browse filesBrowse files
Improve bar_label annotation (#22447)
Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com>
1 parent c9614de commit 33b3015
Copy full SHA for 33b3015

File tree

Expand file treeCollapse file tree

2 files changed

+93
-6
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+93
-6
lines changed

‎lib/matplotlib/axes/_axes.py

Copy file name to clipboardExpand all lines: lib/matplotlib/axes/_axes.py
+26-6Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2597,13 +2597,25 @@ def bar_label(self, container, labels=None, *, fmt="%g", label_type="edge",
25972597
25982598
**kwargs
25992599
Any remaining keyword arguments are passed through to
2600-
`.Axes.annotate`.
2600+
`.Axes.annotate`. The alignment parameters (
2601+
*horizontalalignment* / *ha*, *verticalalignment* / *va*) are
2602+
not supported because the labels are automatically aligned to
2603+
the bars.
26012604
26022605
Returns
26032606
-------
26042607
list of `.Text`
26052608
A list of `.Text` instances for the labels.
26062609
"""
2610+
for key in ['horizontalalignment', 'ha', 'verticalalignment', 'va']:
2611+
if key in kwargs:
2612+
raise ValueError(
2613+
f"Passing {key!r} to bar_label() is not supported.")
2614+
2615+
a, b = self.yaxis.get_view_interval()
2616+
y_inverted = a > b
2617+
c, d = self.xaxis.get_view_interval()
2618+
x_inverted = c > d
26072619

26082620
# want to know whether to put label on positive or negative direction
26092621
# cannot use np.sign here because it will return 0 if x == 0
@@ -2632,7 +2644,7 @@ def sign(x):
26322644
annotations = []
26332645

26342646
for bar, err, dat, lbl in itertools.zip_longest(
2635-
bars, errs, datavalues, labels
2647+
bars, errs, datavalues, labels
26362648
):
26372649
(x0, y0), (x1, y1) = bar.get_bbox().get_points()
26382650
xc, yc = (x0 + x1) / 2, (y0 + y1) / 2
@@ -2664,18 +2676,26 @@ def sign(x):
26642676
xy = endpt, yc
26652677

26662678
if orientation == "vertical":
2667-
xytext = 0, sign(dat) * padding
2679+
y_direction = -1 if y_inverted else 1
2680+
xytext = 0, y_direction * sign(dat) * padding
26682681
else:
2669-
xytext = sign(dat) * padding, 0
2682+
x_direction = -1 if x_inverted else 1
2683+
xytext = x_direction * sign(dat) * padding, 0
26702684

26712685
if label_type == "center":
26722686
ha, va = "center", "center"
26732687
elif label_type == "edge":
26742688
if orientation == "vertical":
26752689
ha = 'center'
2676-
va = 'top' if dat < 0 else 'bottom' # also handles NaN
2690+
if y_inverted:
2691+
va = 'top' if dat > 0 else 'bottom' # also handles NaN
2692+
else:
2693+
va = 'top' if dat < 0 else 'bottom' # also handles NaN
26772694
elif orientation == "horizontal":
2678-
ha = 'right' if dat < 0 else 'left' # also handles NaN
2695+
if x_inverted:
2696+
ha = 'right' if dat > 0 else 'left' # also handles NaN
2697+
else:
2698+
ha = 'right' if dat < 0 else 'left' # also handles NaN
26792699
va = 'center'
26802700

26812701
if np.isnan(dat):

‎lib/matplotlib/tests/test_axes.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_axes.py
+67Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7386,6 +7386,20 @@ def test_bar_label_location_vertical():
73867386
assert labels[1].get_va() == 'top'
73877387

73887388

7389+
def test_bar_label_location_vertical_yinverted():
7390+
ax = plt.gca()
7391+
ax.invert_yaxis()
7392+
xs, heights = [1, 2], [3, -4]
7393+
rects = ax.bar(xs, heights)
7394+
labels = ax.bar_label(rects)
7395+
assert labels[0].xy == (xs[0], heights[0])
7396+
assert labels[0].get_ha() == 'center'
7397+
assert labels[0].get_va() == 'top'
7398+
assert labels[1].xy == (xs[1], heights[1])
7399+
assert labels[1].get_ha() == 'center'
7400+
assert labels[1].get_va() == 'bottom'
7401+
7402+
73897403
def test_bar_label_location_horizontal():
73907404
ax = plt.gca()
73917405
ys, widths = [1, 2], [3, -4]
@@ -7399,6 +7413,49 @@ def test_bar_label_location_horizontal():
73997413
assert labels[1].get_va() == 'center'
74007414

74017415

7416+
def test_bar_label_location_horizontal_yinverted():
7417+
ax = plt.gca()
7418+
ax.invert_yaxis()
7419+
ys, widths = [1, 2], [3, -4]
7420+
rects = ax.barh(ys, widths)
7421+
labels = ax.bar_label(rects)
7422+
assert labels[0].xy == (widths[0], ys[0])
7423+
assert labels[0].get_ha() == 'left'
7424+
assert labels[0].get_va() == 'center'
7425+
assert labels[1].xy == (widths[1], ys[1])
7426+
assert labels[1].get_ha() == 'right'
7427+
assert labels[1].get_va() == 'center'
7428+
7429+
7430+
def test_bar_label_location_horizontal_xinverted():
7431+
ax = plt.gca()
7432+
ax.invert_xaxis()
7433+
ys, widths = [1, 2], [3, -4]
7434+
rects = ax.barh(ys, widths)
7435+
labels = ax.bar_label(rects)
7436+
assert labels[0].xy == (widths[0], ys[0])
7437+
assert labels[0].get_ha() == 'right'
7438+
assert labels[0].get_va() == 'center'
7439+
assert labels[1].xy == (widths[1], ys[1])
7440+
assert labels[1].get_ha() == 'left'
7441+
assert labels[1].get_va() == 'center'
7442+
7443+
7444+
def test_bar_label_location_horizontal_xyinverted():
7445+
ax = plt.gca()
7446+
ax.invert_xaxis()
7447+
ax.invert_yaxis()
7448+
ys, widths = [1, 2], [3, -4]
7449+
rects = ax.barh(ys, widths)
7450+
labels = ax.bar_label(rects)
7451+
assert labels[0].xy == (widths[0], ys[0])
7452+
assert labels[0].get_ha() == 'right'
7453+
assert labels[0].get_va() == 'center'
7454+
assert labels[1].xy == (widths[1], ys[1])
7455+
assert labels[1].get_ha() == 'left'
7456+
assert labels[1].get_va() == 'center'
7457+
7458+
74027459
def test_bar_label_location_center():
74037460
ax = plt.gca()
74047461
ys, widths = [1, 2], [3, -4]
@@ -7450,6 +7507,16 @@ def test_bar_label_nan_ydata():
74507507
assert labels[0].get_va() == 'bottom'
74517508

74527509

7510+
def test_bar_label_nan_ydata_inverted():
7511+
ax = plt.gca()
7512+
ax.yaxis_inverted()
7513+
bars = ax.bar([2, 3], [np.nan, 1])
7514+
labels = ax.bar_label(bars)
7515+
assert [l.get_text() for l in labels] == ['', '1']
7516+
assert labels[0].xy == (2, 0)
7517+
assert labels[0].get_va() == 'bottom'
7518+
7519+
74537520
def test_patch_bounds(): # PR 19078
74547521
fig, ax = plt.subplots()
74557522
ax.add_patch(mpatches.Wedge((0, -1), 1.05, 60, 120, 0.1))

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.