所以,为了简单起见,我改变了一下构建数据的方式:
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()
这使:
我根据平均值绘制标签,并将其放在0行的另一侧,这样您就可以确定它永远不会与其他东西重叠,除非有时会出现错误.我在文本后面设置了一个框,以便它反映平均值.
根据您的图形大小,您需要调整一些值,以便标签适合,例如:
>宽度= 0.85
> r.get_height()/ 5. #y
>“垫”:1
> fontsize = 10
>“{:”“> 6.1f}%”.format(r.get_width()* 100):设置标签中char的总量(此处为6最小值,如果小于6则填充右侧的空白区域)字符).它需要family =“monospace”
如果有什么不清楚,请告诉我.
HTH