使用 Matplotlib 标记堆积条形图
Stacked Bar Chart Labeling using Matplotlib
各位程序员大家好,
对于一个项目,我想生成一个堆积条形图。我在这方面很成功。但是,我想为每个条形图添加一个标签以指示每个条形图的大小。我阅读了有关 matplotlib 的相当新添加的功能的演示,称为条形标签:Bar Label Demo.
我尝试想出的解决方案如下:
# hard-coded data
dist_lst = [
[0, 0, 0, 1, 1, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0],
[0, 0, 0, 4, 1, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0],
[0, 0, 0, 14, 0, 1], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0]
]
# defined colors
colors = [
"#e6194b", "#3cb44b", "#ffe119", "#4363d8", "#f58231",
"#911eb4", "#46f0f0", "#f032e6", "#bcf60c", "#fabebe",
"#008080", "#e6beff", "#9a6324", "#fffac8", "#800000",
"#aaffc3", "#808000", "#ffd8b1", "#000075", "#808080",
"#ffffff", "#000000", "#eb5b01", "#db8c62", "#f58b7a",
"#288C00",
]
i = 0
lst = np.array(dist_lst)
fig, ax = plt.subplots()
ax.bar(range(6), lst[0], edgecolor="black", color=colors[0])
sum_arr = lst[0]
for data in lst[1:]:
i += 1
ax.bar(range(6), data, bottom=sum_arr, edgecolor="black", color=colors[i])
sum_arr += data
ax.legend(list(range(1, len(lst))), title="families", ncol=2, bbox_to_anchor=(1, 1))
# Adding size labels
for c in ax.containers:
ax.bar_label(c, label_type="center")
如果它的可读性很差,我深表歉意,但现在它可以工作了……算了。问题是它生成的图也包含导致混乱的零值。
如何解决绘制这些零值的问题?
另外,如果有人有关于调色板的提示,我会洗耳恭听,因为我想让它尽可能地易于阅读。
感谢您的宝贵时间!
当您迭代以在末尾添加标签时,c
中保存的对象是带有参数 labels
.
的 matplotlib.container.BarContainer
. These have an attribute datavalues
which are used for labelling unless you provide other labels to matplotlib.axes.Axes.bar_label
的实例
因此,为 0
值设置空字符串允许您控制添加的内容:
# Adding size labels
for c in ax.containers:
# Create a new list of labels
labels = [a if a else "" for a in c.datavalues]
ax.bar_label(c, labels=labels, label_type="center")
结合您的代码,生成:
各位程序员大家好,
对于一个项目,我想生成一个堆积条形图。我在这方面很成功。但是,我想为每个条形图添加一个标签以指示每个条形图的大小。我阅读了有关 matplotlib 的相当新添加的功能的演示,称为条形标签:Bar Label Demo.
我尝试想出的解决方案如下:
# hard-coded data
dist_lst = [
[0, 0, 0, 1, 1, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0],
[0, 0, 0, 4, 1, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0],
[0, 0, 0, 14, 0, 1], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0]
]
# defined colors
colors = [
"#e6194b", "#3cb44b", "#ffe119", "#4363d8", "#f58231",
"#911eb4", "#46f0f0", "#f032e6", "#bcf60c", "#fabebe",
"#008080", "#e6beff", "#9a6324", "#fffac8", "#800000",
"#aaffc3", "#808000", "#ffd8b1", "#000075", "#808080",
"#ffffff", "#000000", "#eb5b01", "#db8c62", "#f58b7a",
"#288C00",
]
i = 0
lst = np.array(dist_lst)
fig, ax = plt.subplots()
ax.bar(range(6), lst[0], edgecolor="black", color=colors[0])
sum_arr = lst[0]
for data in lst[1:]:
i += 1
ax.bar(range(6), data, bottom=sum_arr, edgecolor="black", color=colors[i])
sum_arr += data
ax.legend(list(range(1, len(lst))), title="families", ncol=2, bbox_to_anchor=(1, 1))
# Adding size labels
for c in ax.containers:
ax.bar_label(c, label_type="center")
如果它的可读性很差,我深表歉意,但现在它可以工作了……算了。问题是它生成的图也包含导致混乱的零值。
如何解决绘制这些零值的问题? 另外,如果有人有关于调色板的提示,我会洗耳恭听,因为我想让它尽可能地易于阅读。
感谢您的宝贵时间!
当您迭代以在末尾添加标签时,c
中保存的对象是带有参数 labels
.
matplotlib.container.BarContainer
. These have an attribute datavalues
which are used for labelling unless you provide other labels to matplotlib.axes.Axes.bar_label
的实例
因此,为 0
值设置空字符串允许您控制添加的内容:
# Adding size labels
for c in ax.containers:
# Create a new list of labels
labels = [a if a else "" for a in c.datavalues]
ax.bar_label(c, labels=labels, label_type="center")
结合您的代码,生成: