gpt4 book ai didi

python - Pandas 条形图,如何注释分组的水平条形图

转载 作者:太空狗 更新时间:2023-10-29 21:54:46 26 4
gpt4 key购买 nike

我问这个问题是因为我还没有找到关于如何注释分组水平 Pandas 条形图 的工作示例。我知道以下两个:

但它们都是关于垂直条形图的。即,要么没有水平条形图的解决方案,要么它不能完全工作。

在处理这个问题几周后,我终于可以用示例代码提出问题,这几乎是我想要的,只是不是 100% 有效。需要您的帮助才能达到 100%。

我们开始吧,full code is uploaded here .结果如下所示:

Pandas chart

你可以看到它几乎可以工作,只是标签没有放在我想要的位置,我无法自己将它们移动到更好的位置。另外,因为图表栏的顶部是用来显示错误栏的,所以我真正想要的是将注释文本向y轴移动,很好地排列在图表的左侧或右侧y 轴,取决于 X 值。例如,这是我的同事可以用 MS Excel 做的:

MS Excel chart

Python 可以用 Pandas 图表做到这一点吗?

我将上面 url 中的代码包含在注释中,一个是我所能做的,另一个是引用(来自 In [23] ):

# my all-that-I-can-do
def autolabel(rects):
#if height constant: hbars, vbars otherwise
if (np.diff([plt.getp(item, 'width') for item in rects])==0).all():
x_pos = [rect.get_x() + rect.get_width()/2. for rect in rects]
y_pos = [rect.get_y() + 1.05*rect.get_height() for rect in rects]
scores = [plt.getp(item, 'height') for item in rects]
else:
x_pos = [rect.get_width()+.3 for rect in rects]
y_pos = [rect.get_y()+.3*rect.get_height() for rect in rects]
scores = [plt.getp(item, 'width') for item in rects]
# attach some text labels
for rect, x, y, s in zip(rects, x_pos, y_pos, scores):
ax.text(x,
y,
#'%s'%s,
str(round(s, 2)*100)+'%',
ha='center', va='bottom')

# for the reference
ax.bar(1. + np.arange(len(xv)), xv, align='center')
# Annotate with text
ax.set_xticks(1. + np.arange(len(xv)))
for i, val in enumerate(xv):
ax.text(i+1, val/2, str(round(val, 2)*100)+'%', va='center',
ha='center', color='black')

请帮忙。谢谢。

最佳答案

因此,为了简单起见,我稍微更改了您构建数据的方式:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
sns.set_style("white") #for aesthetic purpose only

# fake data
df = pd.DataFrame({'A': np.random.choice(['foo', 'bar'], 100),
'B': np.random.choice(['one', 'two', 'three'], 100),
'C': np.random.choice(['I1', 'I2', 'I3', 'I4'], 100),
'D': np.random.randint(-10,11,100),
'E': np.random.randn(100)})

p = pd.pivot_table(df, index=['A','B'], columns='C', values='D')
e = pd.pivot_table(df, index=['A','B'], columns='C', values='E')

ax = p.plot(kind='barh', xerr=e, width=0.85)

for r in ax.patches:
if r.get_x() < 0: # it it's a negative bar
ax.text(0.25, # set label on the opposite side
r.get_y() + r.get_height()/5., # y
"{:" ">7.1f}%".format(r.get_x()*100), # text
bbox={"facecolor":"red",
"alpha":0.5,
"pad":1},
fontsize=10, family="monospace", zorder=10)
else:
ax.text(-1.5, # set label on the opposite side
r.get_y() + r.get_height()/5., # y
"{:" ">6.1f}%".format(r.get_width()*100),
bbox={"facecolor":"green",
"alpha":0.5,
"pad":1},
fontsize=10, family="monospace", zorder=10)
plt.tight_layout()

给出:

barh plot error bar annotated

我根据平均值绘制标签并将其放在 0 线的另一侧,这样您就可以确定它永远不会与其他东西重叠,除了有时会出现误差条。我在文本后面设置了一个方框,以便它反射(reflect)均值。您需要根据图形大小调整一些值,以便标签适合,例如:

  • width=0.85
  • +r.get_height()/5. # y
  • "pad":1
  • fontsize=10
  • "{:"">6.1f}%".format(r.get_width()*100) : 设置标签中的字符总量(这里,最少6个,用白色填充如果少于 6 个字符,则在右侧留空间)。它需要 family="monospace"

如果有什么不清楚的地方告诉我。

HTH

关于python - Pandas 条形图,如何注释分组的水平条形图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34292076/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com