Python 在条形图上用值注释条形图

Python 在条形图上用值注释条形图,python,matplotlib,plot,pandas,dataframe,Python,Matplotlib,Plot,Pandas,Dataframe,我正在寻找一种方法,用数据框中的四舍五入数值在熊猫条形图中注释我的条形图 >>> df=pd.DataFrame({'A':np.random.rand(2),'B':np.random.rand(2)},index=['value1','value2'] ) >>> df A B value1 0.440922 0.911800 value2 0.588242 0.79736

我正在寻找一种方法,用数据框中的四舍五入数值在熊猫条形图中注释我的条形图

>>> df=pd.DataFrame({'A':np.random.rand(2),'B':np.random.rand(2)},index=['value1','value2'] )         
>>> df
                 A         B
  value1  0.440922  0.911800
  value2  0.588242  0.797366
我想得到这样的东西:

我尝试使用此代码示例,但注释都以x记号为中心:

>>> ax = df.plot(kind='bar') 
>>> for idx, label in enumerate(list(df.index)): 
        for acc in df.columns:
            value = np.round(df.ix[idx][acc],decimals=2)
            ax.annotate(value,
                        (idx, value),
                         xytext=(0, 15), 
                         textcoords='offset points')

您可以直接从轴的面片获得它:

for p in ax.patches:
    ax.annotate(str(p.get_height()), (p.get_x() * 1.005, p.get_height() * 1.005))

您需要调整字符串格式和偏移量以使内容居中,可以使用
p.get_width()
中的宽度,但这应该可以让您开始。除非您跟踪某个位置的偏移,否则它可能不适用于堆叠条形图。

解决方案,该解决方案还使用采样浮点格式处理负值

仍然需要调整偏移量

df=pd.DataFrame({'A':np.random.rand(2)-1,'B':np.random.rand(2)},index=['val1','val2'] )
ax = df.plot(kind='bar', color=['r','b']) 
x_offset = -0.03
y_offset = 0.02
for p in ax.patches:
    b = p.get_bbox()
    val = "{:+.2f}".format(b.y1 + b.y0)        
    ax.annotate(val, ((b.x0 + b.x1)/2 + x_offset, b.y1 + y_offset))

斧头告诉我们盒子的大小

x_position=##define a value
y_position=##define a value
for patch in ax.patches:
    b= patch.get_bbox()
    y_value=b.y1-b.y0
    ax.annotate(y_value, "x_position" , "y_position"))
plt.show()
为了更清楚::
Bbox(x0=3.75,y0=0.0,x1=4.25,y1=868.0)
Bbox(x0=4.75,y0=0.0,x1=5.25,y1=868.0)
Bbox(x0=5.75,y0=0.0,x1=6.25,y1=1092.0)
Bbox(x0=6.75,y0=0.0,x1=7.25,y1=756.0)
Bbox(x0=7.75,y0=0.0,x1=8.25,y1=756.0)
Bbox(x0=8.75,y0=0.0,x1=9.25,y1=588.0)
Bbox(x0=3.75,y0=868.0,x1=4.25,y1=3724.0)
Bbox(x0=4.75,y0=868.0,x1=5.25,y1=3528.0)
Bbox(x0=5.75,y0=1092.0,x1=6.25,y1=3948.0)
Bbox(x0=6.75,y0=756.0,x1=7.25,y1=2884.0)
Bbox(x0=7.75,y0=756.0,x1=8.25,y1=3024.0)
Bbox(x0=0.75,y0=4004.0,x1=1.25,y1=4396.0)
Bbox(x0=1.75,y0=3668.0,x1=2.25,y1=4060.0)
Bbox(x0=2.75,y0=3864.0,x1=3.25,y1=4060.0)

这是程序中patch.get_bbox()的输出

我们可以从这里提取边界框细节,并根据我们的要求进行操作

我使用了Tom的解决方案,将要显示的值舍入到两个有效数字

for p in ax.patches:
  ax.annotate(str(round(p.get_height(),2)), (p.get_x() * 1.005, p.get_height() * 1.005))

Tom搞定了,但我这里有一个更复杂的解决方案:谢谢@TomAugsPurger,下面的方法奏效了:
对于ax.patches中的p:ax.annotate(np.round(p.get_height(),decimals=2),(p.get_x()+p.get_width()/2.,p.get_height()),ha='center',va='center',xytext=(0,10),textcoords='offset points')
另一个问题:如何处理带有负值的条形图?在上面的代码中,标签总是带有正坐标,即使条值是负的。水平条有类似的解决方案吗:kind=barh?我发现这对barh有效:
ax.annotate(str(p.get_width()),(p.get_x()+p.get_width(),p.get_y()),xytext=(5,10),textcoords='offset points')
谢谢@capitalitpug。我发现添加水平对齐会使您的效果更好<代码>ax.注释(str(int(p.get_width()),(p.get_x()+p.get_width(),p.get_y()),xytext=(-2,4),textcoords='offset points',horizontalalignment='right')+1