我正试图“稳健地”将数据标签集中在堆叠条形图中。下面给出了一个简单的代码示例和结果。正如您所看到的,数据标签并没有真正在所有矩形中居中。我错过了什么?
import numpy as np
import matplotlib.pyplot as plt
A = [45, 17, 47]
B = [91, 70, 72]
fig = plt.figure(facecolor="white")
ax = fig.add_subplot(1, 1, 1)
bar_width = 0.5
bar_l = np.arange(1, 4)
tick_pos = [i + (bar_width / 2) for i in bar_l]
ax1 = ax.bar(bar_l, A, width=bar_width, label="A", color="green")
ax2 = ax.bar(bar_l, B, bottom=A, width=bar_width, label="B", color="blue")
ax.set_ylabel("Count", fontsize=18)
ax.set_xlabel("Class", fontsize=18)
ax.legend(loc="best")
plt.xticks(tick_pos, ["C1", "C2", "C3"], fontsize=16)
plt.yticks(fontsize=16)
for r1, r2 in zip(ax1, ax2):
h1 = r1.get_height()
h2 = r2.get_height()
plt.text(r1.get_x() + r1.get_width() / 2., h1 / 2., "%d" % h1, ha="center", va="bottom", color="white", fontsize=16, fontweight="bold")
plt.text(r2.get_x() + r2.get_width() / 2., h1 + h2 / 2., "%d" % h2, ha="center", va="bottom", color="white", fontsize=16, fontweight="bold")
plt.show()
2条答案
按热度按时间oogrdqng1#
pandas.DataFrame
是绘制堆叠条形图的最简单方法。pandas.DataFrame.plot.bar(stacked=True)
或pandas.DataFrame.plot(kind='bar', stacked=True)
是绘制堆叠条形图的最简单方法。matplotlib.axes.Axes
或numpy.ndarray
。seaborn
只是matplotlib
的高级API,因此这些解决方案也适用于seaborn
图,如How to annotate a seaborn barplot with the aggregated value所示。*在
python 3.10
、pandas 1.4.2
、matplotlib 3.5.1
、seaborn 0.11.2
中测试导入测试DataFrame
matplotlib v3.4.2
更新matplotlib.pyplot.bar_label
,它会自动将值居中。.bar_label
的其他详细信息和示例,请参见How to add value labels on a bar chart。pandas v1.2.4
进行测试,它使用matplotlib
作为绘图引擎。.bar_label()
定制labels
。ax.bar_label(c, fmt='%0.0f', label_type='center')
将更改数字格式以不显示小数位。其他小段标签移除选项可以使用
fmt
bar_label
的fmt
参数现在接受{}样式的格式字符串。fmt=lambda x: f'{x:.0f}' if x > 0 else ''
fmt=lambda x: np.where(x > 0, f'{x:.0f}', '')
与np.where
海运选项
seaborn
是matplotlib
的高级APIseaborn.barplot
API没有堆叠选项,但它“可以”用sns.histplot
或sns.displot
实现。Seaborn DataFrame格式
轴级图
图级图
原始应答
.patches
方法解包matplotlib.patches.Rectangle
对象的列表,堆叠条形图的每个部分对应一个对象。.Rectangle
都有用于提取定义矩形的各种值的方法。.Rectangle
都是从左到右,从下到上的顺序,因此当迭代.patches
时,每个级别的所有.Rectangle
对象都按顺序出现。label_text = f'{height}'
制作的,因此可以根据需要添加任何其他文本,例如label_text = f'{height}%'
label_text = f'{height:0.0f}'
将显示无小数位的数字。Plot
kind='barh'
label_text = f'{width}'
if width > 0:
k3fezbri2#
为什么要写
va="bottom"
?必须使用va="center"
。