调整绘图中的右侧文本

Adjust right-side text within plot

我想在每个堆叠条的右侧打印一些文本。我找到了一种方法,通过注释来做到这一点,但是存在一些问题: autolabel 函数在我看来是一种非常多余的注释方式,有没有更简单、更容易实现相同视觉效果的方法?更重要的是,我怎样才能修复这个超出图右侧的文本,如下图所示?我试过 subplots_adjust,但不太奏效...

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
labels = ['G1', 'G2', 'G3', 'G4', 'G5']
men_means = [20, 34, 30, 35, 27]
women_means = [25, 32, 34, 20, 25]

x = np.arange(len(labels))  # the x-axis label locations
width = 0.35  # the width of the bars

fig, ax = plt.subplots()#(figsize=(6, 4), dpi=200)
# FOR SIDE-BY-SIDE plotting:
# rects1 = ax.bar(x - width/2, men_means, width, label='Men')
# rects2 = ax.bar(x + width/2, women_means, width, label='Women')
rects1 = ax.bar(x, men_means, width, label='Men')
rects2 = ax.bar(x, women_means, width, bottom=men_means, label='Women')

# Add some text for labels, title and custom x-axis tick labels, etc.
ax.set_ylabel('Scores')
ax.set_title('Scores by group and gender')
ax.set_xticks(x)
ax.set_xticklabels(labels)
ax.legend()

def autolabel(rects):
    for rect in rects:
        height = rect.get_height()
        ax.annotate('{}'.format(height),
                    xy=(rect.get_x() + 3 * rect.get_width() / 2, rect.get_y() + height / 2),
                    xytext=(0, -5),
                    textcoords="offset points",
                    ha='center', va='center')

autolabel(rects1)
autolabel(rects2)
fig.subplots_adjust(left=0.9, right=1.9, top=0.9, bottom=0.1)
plt.show()

如果您不介意最右边的栏稍微偏离刻度标签的中心,您可以将它稍微向左移动一点,以便您的标签适合。

如果打印调用 bar() 返回的内容,您会看到它是一个包含 5 位艺术家的 BarContainer 对象:

<BarContainer object of 5 artists>

...您可以对其进行迭代:

Rectangle(xy=(-0.175, 0), width=0.35, height=20, angle=0)
Rectangle(xy=(0.825, 0), width=0.35, height=34, angle=0)
Rectangle(xy=(1.825, 0), width=0.35, height=30, angle=0)
Rectangle(xy=(2.825, 0), width=0.35, height=35, angle=0)
Rectangle(xy=(3.825, 0), width=0.35, height=27, angle=0)

每个 Rectangle 对象都有一个 set_xy() 方法。所以你可以通过以下方式移动最终的上下柱:

bar, bar2 = rects1[4], rects2[4]
bar.set_xy((bar.get_x()-0.05,bar.get_y()))
bar2.set_xy((bar2.get_x()-0.05,bar2.get_y()))

将上面的代码放在

的正下方
rects1 = ax.bar(x, men_means, width, label='Men')
rects2 = ax.bar(x, women_means, width, bottom=men_means, label='Women')

并且通过删除对 subplots_adjust() 的调用并改用 tight_layout(),我能够实现此目的:

或者,如果您不介意标签和栏之间的间距减少,您可以在 autolabel() 函数中将 rect.get_x() + 3 更改为 rect.get_x() + 2.5,这样就可以了: