堆叠的条形图意外地用条形图高度的总和注释
Stacked bars are unexpectedly annotated with the sum of bar heights
我的数据:
names_col = ['Count','Freq']
dat = [['Matching', 56935],['Mismatching', 100587]]
plot_df = pd.DataFrame(data=dat,columns=names_col)
我正在尝试显示值的 plot stacked catplot,这是我的代码:
plt.figure(figsize=(16,9))
p=plot_df.set_index('Count').T.plot(kind='bar', stacked=True)
p.bar_label(p.containers[0])
p.bar_label(p.containers[1])
plt.show();
首先,输出的图形大小不是(16,9),有什么问题吗?
第二个情节显示价值为:
而不是 matching
的值 - 56935(这里没问题)和 mismatching
- 100587,绘图显示总计(157522)。
我如何访问和显示 Mismatching
值?
您可以将figsize
设置为绘图参数。然后为每个容器添加条形标签和您自己的文本:
p=plot_df.set_index('Count').T.plot(kind='bar', stacked=True, figsize=(16,9))
for x in p.containers:
p.bar_label(x)
p.text(0, x[0].get_y() + x[0].get_height()*0.5, x.datavalues[0], ha='center', color='w', weight='bold')
plt.show()
输出:
- 使用
matplotlib.pyplot.bar_label
两次
- 根据标签是在条形的中心还是在条形的边缘来确定注释值。
- 另一个答案使用
x[0].
,因为只有一组堆积条,但如果 x 轴上有不止一组,那将不起作用。
- 有关
.bar_label
的更多详细信息和示例,请参阅此 answer。
- 重塑数据框应该是独立于绘图的步骤
pandas.DataFrame.plot
使用 matplotlib
作为默认绘图后端,并且有许多参数,如 rot
、xlabel
、ylabel
和 figsize
,用于自定义绘图。
- 在
python 3.10
、pandas 1.3.4
、matplotlib 3.5.0
中测试
df = pd.DataFrame(data=dat, columns=names_col)
dft = df.set_index('Count').T
axe = dft.plot(kind='bar', stacked=True, figsize=(16,9), rot=0)
for x in axe.containers:
axe.bar_label(x, label_type='edge', weight='bold')
axe.bar_label(x, label_type='center', weight='bold', color='white')
- 这是一个包含多个组的更详尽的示例
- 另一个答案没有为第二组条放置中间注释。
# test data
data = {'Matching': [56935, 17610], 'Mismatching': [100587, 13794], 'Test': [33139, 23567]}
df = pd.DataFrame(data=data, index=['Freq', 'Freq2'])
axe = df.plot(kind='bar', stacked=True, figsize=(16,9), rot=0)
for x in axe.containers:
axe.bar_label(x, label_type='edge', weight='bold')
axe.bar_label(x, label_type='center', weight='bold', color='white')
仅将总数添加到条形图的顶部
- 为行的总和添加一个新的冒号,用于注释
df['tot'] = df.sum(axis=1)
display(df)
Matching Mismatching Test tot
Freq 56935 100587 33139 190661
Freq2 17610 13794 23567 54971
# plot
axe = df.iloc[:, :3].plot(kind='bar', stacked=True, figsize=(16,9), rot=0)
# annotate
for x in axe.containers:
axe.bar_label(x, label_type='center', weight='bold', color='white')
# resuse x from the for loop, the last x is the top set of bar patches
axe.bar_label(x, labels=df['tot'], label_type='edge', weight='bold')
我的数据:
names_col = ['Count','Freq']
dat = [['Matching', 56935],['Mismatching', 100587]]
plot_df = pd.DataFrame(data=dat,columns=names_col)
我正在尝试显示值的 plot stacked catplot,这是我的代码:
plt.figure(figsize=(16,9))
p=plot_df.set_index('Count').T.plot(kind='bar', stacked=True)
p.bar_label(p.containers[0])
p.bar_label(p.containers[1])
plt.show();
首先,输出的图形大小不是(16,9),有什么问题吗?
第二个情节显示价值为:
而不是 matching
的值 - 56935(这里没问题)和 mismatching
- 100587,绘图显示总计(157522)。
我如何访问和显示 Mismatching
值?
您可以将figsize
设置为绘图参数。然后为每个容器添加条形标签和您自己的文本:
p=plot_df.set_index('Count').T.plot(kind='bar', stacked=True, figsize=(16,9))
for x in p.containers:
p.bar_label(x)
p.text(0, x[0].get_y() + x[0].get_height()*0.5, x.datavalues[0], ha='center', color='w', weight='bold')
plt.show()
输出:
- 使用
matplotlib.pyplot.bar_label
两次- 根据标签是在条形的中心还是在条形的边缘来确定注释值。
- 另一个答案使用
x[0].
,因为只有一组堆积条,但如果 x 轴上有不止一组,那将不起作用。 - 有关
.bar_label
的更多详细信息和示例,请参阅此 answer。
- 重塑数据框应该是独立于绘图的步骤
pandas.DataFrame.plot
使用matplotlib
作为默认绘图后端,并且有许多参数,如rot
、xlabel
、ylabel
和figsize
,用于自定义绘图。- 在
python 3.10
、pandas 1.3.4
、matplotlib 3.5.0
中测试
df = pd.DataFrame(data=dat, columns=names_col)
dft = df.set_index('Count').T
axe = dft.plot(kind='bar', stacked=True, figsize=(16,9), rot=0)
for x in axe.containers:
axe.bar_label(x, label_type='edge', weight='bold')
axe.bar_label(x, label_type='center', weight='bold', color='white')
- 这是一个包含多个组的更详尽的示例
- 另一个答案没有为第二组条放置中间注释。
# test data
data = {'Matching': [56935, 17610], 'Mismatching': [100587, 13794], 'Test': [33139, 23567]}
df = pd.DataFrame(data=data, index=['Freq', 'Freq2'])
axe = df.plot(kind='bar', stacked=True, figsize=(16,9), rot=0)
for x in axe.containers:
axe.bar_label(x, label_type='edge', weight='bold')
axe.bar_label(x, label_type='center', weight='bold', color='white')
仅将总数添加到条形图的顶部
- 为行的总和添加一个新的冒号,用于注释
df['tot'] = df.sum(axis=1)
display(df)
Matching Mismatching Test tot
Freq 56935 100587 33139 190661
Freq2 17610 13794 23567 54971
# plot
axe = df.iloc[:, :3].plot(kind='bar', stacked=True, figsize=(16,9), rot=0)
# annotate
for x in axe.containers:
axe.bar_label(x, label_type='center', weight='bold', color='white')
# resuse x from the for loop, the last x is the top set of bar patches
axe.bar_label(x, labels=df['tot'], label_type='edge', weight='bold')