Chú thích các thanh với các giá trị trên các ô trên thanh Pandas


89

Tôi đang tìm cách chú thích các thanh của mình trong biểu đồ thanh Pandas với các giá trị số được làm tròn từ DataFrame của mình.

>>> 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

Tôi muốn nhận được một cái gì đó như thế này:

ví dụ chú thích âm mưu thanh

Tôi đã thử với mẫu mã này, nhưng các chú thích đều tập trung vào dấu 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')

Tom đóng đinh nó, nhưng tôi đã có một giải pháp phức tạp hơn ở đây: stackoverflow.com/questions/19917587/...
Paul H

Câu trả lời:


149

Bạn nhận được nó trực tiếp từ các bản vá của trục:

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

Bạn sẽ muốn điều chỉnh định dạng chuỗi và các hiệu số để lấy mọi thứ ở giữa, có thể sử dụng chiều rộng từ đó p.get_width(), nhưng điều đó sẽ giúp bạn bắt đầu. Nó có thể không hoạt động với các ô thanh xếp chồng lên nhau, trừ khi bạn theo dõi sự chênh lệch ở đâu đó.


29
Cảm ơn @TomAugsPurger, sau đây làm việc: for p in ax.patches: 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')
leroygr

2
Một câu hỏi khác: bạn sẽ xử lý các thanh có giá trị âm như thế nào? Với đoạn mã trên, các nhãn luôn có tọa độ dương, ngay cả khi giá trị vạch là âm.
leroygr

1
Có một giải pháp tương tự cho các thanh ngang: kind = barh?
Nickpick

4
Tôi thấy điều này làm việc cho barh:ax.annotate(str(p.get_width()), (p.get_x() + p.get_width(), p.get_y()), xytext=(5, 10), textcoords='offset points')
Kamil Sindi

2
Cảm ơn @capitalistpug. Tôi thấy rằng việc bổ sung căn chỉnh theo chiều ngang làm cho ảnh của bạn vẫn tốt hơn ax.annotate(str(int(p.get_width())), (p.get_x() + p.get_width(), p.get_y()), xytext=(-2, 4), textcoords='offset points', horizontalalignment='right') +1
DaveL17

31

Giải pháp cũng xử lý các giá trị âm với định dạng float mẫu.

Vẫn cần điều chỉnh hiệu số.

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))

biểu đồ thanh có nhãn giá trị


0

Cái rìu cho chúng ta kích thước của cái hộp.

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()

để rõ hơn ::
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)

đây là đầu ra của patch.get_bbox () trong chương trình của tôi.
chúng tôi có thể trích xuất chi tiết hộp giới hạn từ đây và thao tác theo yêu cầu của chúng tôi

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.