2015-03-08 25 views
38

Tôi bị kẹt trên thứ gì đó cảm thấy như tương đối dễ dàng. Mã tôi mang theo bên dưới là một mẫu dựa trên một dự án lớn hơn mà tôi đang làm việc. Tôi thấy không có lý do để đăng tất cả các chi tiết, vì vậy hãy chấp nhận các cấu trúc dữ liệu tôi mang theo.Thêm nhãn giá trị trên biểu đồ thanh matplotlib

Về cơ bản, tôi đang tạo biểu đồ thanh và tôi chỉ có thể tìm hiểu cách thêm nhãn giá trị trên các thanh (ở giữa thanh hoặc ngay phía trên thanh). Đã xem xét các mẫu trên web nhưng không thực hiện thành công trên mã của riêng tôi. Tôi tin rằng giải pháp là hoặc với 'văn bản' hoặc 'chú thích', nhưng tôi: a) không biết cái nào để sử dụng (và nói chung, đã không tìm ra khi nào nên sử dụng cái nào). b) không thể thấy để hiển thị nhãn giá trị. Sẽ đánh giá cao sự trợ giúp của bạn, mã của tôi bên dưới. Cảm ơn bạn trước!

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 
pd.set_option('display.mpl_style', 'default') 
%matplotlib inline 


frequencies = [6, 16, 75, 160, 244, 260, 145, 73, 16, 4, 1] # bring some raw data 

freq_series = pd.Series.from_array(frequencies) # in my original code I create a series and run on that, so for consistency I create a series from the list. 

x_labels = [108300.0, 110540.0, 112780.0, 115020.0, 117260.0, 119500.0, 121740.0, 123980.0, 126220.0, 128460.0, 130700.0] 

# now to plot the figure... 
plt.figure(figsize=(12, 8)) 
fig = freq_series.plot(kind='bar') 
fig.set_title("Amount Frequency") 
fig.set_xlabel("Amount ($)") 
fig.set_ylabel("Frequency") 
fig.set_xticklabels(x_labels) 
+1

Matplotlib có bản trình diễn: https://matplotlib.org/examples/api/barchart_demo.html – Dan

Trả lời

63

Thứ nhất freq_series.plot trả về một trục không một nhân vật như vậy để làm cho câu trả lời của tôi một chút rõ ràng hơn tôi đã thay đổi mã số của bạn để đề cập đến nó như ax hơn fig để phù hợp hơn với các ví dụ mã khác .

Bạn có thể nhận danh sách các thanh được tạo trong cốt truyện từ thành viên ax.patches. Sau đó, bạn có thể sử dụng kỹ thuật được minh họa trong this matplotlib gallery example để thêm nhãn bằng phương pháp ax.text.

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 

frequencies = [6, 16, 75, 160, 244, 260, 145, 73, 16, 4, 1] # bring some raw data 

freq_series = pd.Series.from_array(frequencies) # in my original code I create a series and run on that, so for consistency I create a series from the list. 

x_labels = [108300.0, 110540.0, 112780.0, 115020.0, 117260.0, 119500.0, 121740.0, 123980.0, 126220.0, 128460.0, 130700.0] 

# now to plot the figure... 
plt.figure(figsize=(12, 8)) 
ax = freq_series.plot(kind='bar') 
ax.set_title("Amount Frequency") 
ax.set_xlabel("Amount ($)") 
ax.set_ylabel("Frequency") 
ax.set_xticklabels(x_labels) 

rects = ax.patches 

# Now make some labels 
labels = ["label%d" % i for i in xrange(len(rects))] 

for rect, label in zip(rects, labels): 
    height = rect.get_height() 
    ax.text(rect.get_x() + rect.get_width()/2, height + 5, label, ha='center', va='bottom') 

plt.savefig("image.png") 

Điều này tạo ra một âm mưu dán nhãn trông giống như:

enter image description here

+0

Hi Si mon!Đầu tiên, cảm ơn rất nhiều vì đã trả lời! 2, tôi đoán tôi không rõ ràng - tôi muốn hiển thị giá trị y. Tôi chỉ thay thế các nhãn trong mã zip (,) với tần số. Bây giờ, bạn có thể vui lòng đổ một số ánh sáng hơn trên vần Vs rìu? Làm tôi bối rối. Cụm từ/tài nguyên tìm kiếm tốt sẽ rất tuyệt, vì nó là một chút chung chung cho tìm kiếm goog. Nhiều đánh giá cao! – Optimesh

+0

Một hình là tập hợp một hoặc nhiều trục, ví dụ: trong ví dụ này http://matplotlib.org/examples/statistics/histogram_demo_multihist.html nó là một hình được tạo thành từ 4 trục khác nhau. –

+0

Cảm ơn bạn lần nữa. Bạn có thể vui lòng giúp tôi hiểu sự khác biệt giữa chú thích và văn bản không? Cảm ơn! – Optimesh

5

Dựa trên một tính năng đề cập trong this answer to another question Tôi đã tìm thấy một giải pháp rất thường được áp dụng cho đặt nhãn trên một biểu đồ thanh.

Các giải pháp khác không may không hoạt động trong nhiều trường hợp, vì khoảng cách giữa nhãn và thanh là given in absolute units of the bars hoặc là scaled by the height of the bar. Trước đây chỉ hoạt động cho một phạm vi hẹp các giá trị và sau đó cho khoảng cách không nhất quán trong một âm mưu. Không hoạt động tốt với các trục logarit. Giải pháp mà tôi đề xuất các công trình độc lập với quy mô (ví dụ như đối với số lượng lớn và nhỏ) và thậm chí là các nhãn địa điểm chính xác cho các giá trị âm và với thang logarit vì nó sử dụng đơn vị trực quan points để bù.

Tôi đã thêm số âm để hiển thị vị trí chính xác của nhãn trong trường hợp này.

Giá trị của chiều cao của mỗi thanh được sử dụng làm nhãn cho nó. Các nhãn khác có thể dễ dàng được sử dụng với Simon's for rect, label in zip(rects, labels) snippet.

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 

frequencies = [6, -16, 75, 160, 244, 260, 145, 73, 16, 4, 1] # bring some raw data 

freq_series = pd.Series.from_array(frequencies) # in my original code I create a series and run on that, so for consistency I create a series from the list. 

x_labels = [108300.0, 110540.0, 112780.0, 115020.0, 117260.0, 119500.0, 121740.0, 123980.0, 126220.0, 128460.0, 130700.0] 

# now to plot the figure... 
plt.figure(figsize=(12, 8)) 
ax = freq_series.plot(kind='bar') 
ax.set_title("Amount Frequency") 
ax.set_xlabel("Amount ($)") 
ax.set_ylabel("Frequency") 
ax.set_xticklabels(x_labels) 

rects = ax.patches 

# For each bar: Place a label 
for rect in rects: 
    # Get X and Y placement of label from rect 
    y_value = rect.get_height() 
    x_value = rect.get_x() + rect.get_width()/2 

    # Number of points between bar and label. Change to your liking. 
    space = 5 
    # Vertical alignment for positive values 
    va = 'bottom' 

    # If value of bar is negative: Place label below bar 
    if y_value < 0: 
     # Invert space to place label below 
     space *= -1 
     # Vertically align label at top 
     va = 'top' 

    # Use Y value as label and format number with one decimal place 
    label = "{:.1f}".format(y_value) 

    # Create annotation 
    plt.annotate(
     label,      # Use `label` as label 
     (x_value, y_value),   # Place label at end of the bar 
     xytext=(0, space),   # Vertically shift label by `space` 
     textcoords="offset points", # Interpret `xytext` as offset in points 
     ha='center',    # Horizontally center label 
     va=va)      # Vertically align label differently for 
            # positive and negative values. 

plt.savefig("image.png") 

này tạo ra kết quả như sau:

Bar chart with automatically placed labels on each bar

Và với quy mô lôgarít (và một số điều chỉnh để các dữ liệu đầu vào để giới thiệu rộng logarit), đây là kết quả:

Bar chart with logarithmic scale with automatically placed labels on each bar

+1

Câu trả lời tuyệt vời! Cảm ơn. Điều này làm việc hoàn hảo với gấu trúc trong âm mưu xây dựng thanh. – ashgetstazered

Các vấn đề liên quan