作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试“稳健地”将堆叠条形图中的数据标签居中。下面给出了一个简单的代码示例和结果。如您所见,数据标签并非真正位于所有矩形的中心。我错过了什么?
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()
最佳答案
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< 中测试
import pandas as pd
import matplotlib.pyplot as plt
A = [45, 17, 47]
B = [91, 70, 72]
C = [68, 43, 13]
# pandas dataframe
df = pd.DataFrame(data={'A': A, 'B': B, 'C': C})
df.index = ['C1', 'C2', 'C3']
A B C
C1 45 91 68
C2 17 70 43
C3 47 72 13
matplotlib v3.4.2
进行了更新matplotlib.pyplot.bar_label
,这会自动将栏中的值居中。.bar_label
获取更多详细信息和示例。pandas v1.2.4
进行测试,它使用 matplotlib
作为绘图引擎。.bar_label()
自定义 labels
。ax.bar_label(c, fmt='%0.0f', label_type='center')
将根据需要更改数字格式以显示无小数位。ax = df.plot(kind='bar', stacked=True, figsize=(8, 6), rot=0, xlabel='Class', ylabel='Count')
for c in ax.containers:
# Optional: if the segment is small or 0, customize the labels
labels = [v.get_height() if v.get_height() > 0 else '' for v in c]
# remove the labels parameter if it's not needed for customized labels
ax.bar_label(c, labels=labels, label_type='center')
seaborn
是 matplotlib
seaborn.barplot
api 没有堆叠选项,但它“可以”用 sns.histplot
实现, 或 sns.displot
.# create the data frame
df = pd.DataFrame(data={'A': A, 'B': B, 'C': C, 'cat': ['C1', 'C2', 'C3']})
A B C cat
0 45 91 68 C1
1 17 70 43 C2
2 47 72 13 C3
# convert the dataframe to a long form
df = df.melt(id_vars='cat')
cat variable value
0 C1 A 45
1 C2 A 17
2 C3 A 47
3 C1 B 91
4 C2 B 70
5 C3 B 72
6 C1 C 68
7 C2 C 43
8 C3 C 13
# plot
ax = sns.histplot(data=df, x='cat', hue='variable', weights='value', discrete=True, multiple='stack')
# iterate through each container
for c in ax.containers:
# Optional: if the segment is small or 0, customize the labels
labels = [v.get_height() if v.get_height() > 0 else '' for v in c]
# remove the labels parameter if it's not needed for customized labels
ax.bar_label(c, labels=labels, label_type='center')
# plot
g = sns.displot(data=df, x='cat', hue='variable', weights='value', discrete=True, multiple='stack')
# iterate through each axes
for ax in g.axes.flat:
# iterate through each container
for c in ax.containers:
# Optional: if the segment is small or 0, customize the labels
labels = [v.get_height() if v.get_height() > 0 else '' for v in c]
# remove the labels parameter if it's not needed for customized labels
ax.bar_label(c, labels=labels, label_type='center')
.patches
方法解压 matplotlib.patches.Rectangle
的列表对象,一个用于堆叠条形图的每个部分。
.Rectangle
都有用于提取定义矩形的各种值的方法。.Rectangle
都是从左到右,从下到上的顺序,所以所有的 .Rectangle
对象,对于每个级别,在迭代时按顺序出现通过 .patches
.label_text = f'{height}'
,因此可以根据需要添加任何额外的文本,例如 label_text = f'{height}%'
label_text = f'{height:0.0f}'
将显示没有小数位的数字。plt.style.use('ggplot')
ax = df.plot(stacked=True, kind='bar', figsize=(12, 8), rot='horizontal')
# .patches is everything inside of the chart
for rect in ax.patches:
# Find where everything is located
height = rect.get_height()
width = rect.get_width()
x = rect.get_x()
y = rect.get_y()
# The height of the bar is the data value and can be used as the label
label_text = f'{height}' # f'{height:.2f}' to format decimal values
# ax.text(x, y, text)
label_x = x + width / 2
label_y = y + height / 2
# plot only when height is greater than specified value
if height > 0:
ax.text(label_x, label_y, label_text, ha='center', va='center', fontsize=8)
ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0.)
ax.set_ylabel("Count", fontsize=18)
ax.set_xlabel("Class", fontsize=18)
plt.show()
kind='barh'
label_text = f'{width}'
如果宽度 > 0:
关于python - 带有居中标签的堆积条形图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41296313/
我使用 Dojo fadeIn 和 fadeOut 以及一个计时器旋转了三个堆叠图像。只有最后一个的 href 可用。是否也可以旋转 href? 这是它的 CSS: #main-slides
给定一个 numpy 数组,我想总结统一的元素 block 以形成一个新的、更小的数组。它与分箱类似,但不是按频率分箱。除了通过示例(如下)之外,我不确定如何描述它。 问题:是否有用于此的函数或更清晰
我正在尝试实现某种按钮控制的幻灯片放映,其中包括用于页面顶部全 Angular 图片的 div,用于页面顶部的 div页面底部的另一张全 Angular 图片和中央内容的最终 div(包括控制“幻
嘿,我正在使用 D3JS 作为图表库,我真的很想利用气泡图中的超酷功能。上主D3JS chart站点下面的Bubble Chart用来比较两组数据: Bubble Chart . 我想知道是否有人真的
我是一名优秀的程序员,十分优秀!