xpt*_*xpt 7 python plot bar-chart pandas
我问这个问题,因为我还没有找到一个关于如何注释分组水平Pandas条形图的工作示例.我知道以下两点:
但它们都是关于垂直条形图.即,要么没有水平条形图的解决方案,要么它没有完全工作.
在这个问题上工作了几个星期之后,我终于能够用一个示例代码提出问题,这几乎就是我想要的,而不是100%工作.需要你的帮助才能实现100%的目标.
我们走了,完整的代码在这里上传.结果如下:
你可以看到它几乎正常工作,只是标签没有放在我想要的地方,我不能把它们移到一个更好的地方.此外,由于图表栏的顶部用于显示错误吧,这样我真正想要的是移向y轴的注释文字,很好地排队在y轴的左边或右边,这取决于X -值.例如,这是我的同事可以用MS Excel做的事情:
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')
Run Code Online (Sandbox Code Playgroud)
请帮忙.谢谢.
因此,为了简单起见,我稍微改变了构建数据的方式:
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()
Run Code Online (Sandbox Code Playgroud)
这使:
我根据平均值绘制标签,并将其放在 0 线的另一侧,这样您就可以非常确定它永远不会与其他内容重叠,有时会出现错误栏。我在文本后面设置了一个框,以便它反映平均值。您需要根据您的身材尺寸调整一些值,以使标签正确贴合,例如:
width=0.85+r.get_height()/5. # y"pad":1fontsize=10"{:" ">6.1f}%".format(r.get_width()*100):设置标签的总字符数(这里最少6个,不足6个字符则在右侧补空)。它需要family="monospace"如果有不清楚的地方请告诉我。
华泰
| 归档时间: |
|
| 查看次数: |
2460 次 |
| 最近记录: |