2013-04-15 33 views
42

Có cách nào để vẽ đồ thị thanh sử dụng matplotlib sử dụng dữ liệu trực tiếp từ dict không?python: vẽ một thanh bằng cách sử dụng matplotlib sử dụng từ điển

dict của tôi trông như thế này:

D = {u'Label1':26, u'Label2': 17, u'Label3':30} 

tôi đã mong

fig = plt.figure(figsize=(5.5,3),dpi=300) 
ax = fig.add_subplot(111) 
bar = ax.bar(D,range(1,len(D)+1,1),0.5) 

để làm việc, nhưng nó không.

Dưới đây là lỗi:

>>> ax.bar(D,range(1,len(D)+1,1),0.5) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/local/lib/python2.7/site-packages/matplotlib/axes.py", line 4904, in bar 
    self.add_patch(r) 
    File "/usr/local/lib/python2.7/site-packages/matplotlib/axes.py", line 1570, in add_patch 
    self._update_patch_limits(p) 
    File "/usr/local/lib/python2.7/site-packages/matplotlib/axes.py", line 1588, in _update_patch_limits 
    xys = patch.get_patch_transform().transform(vertices) 
    File "/usr/local/lib/python2.7/site-packages/matplotlib/patches.py", line 580, in get_patch_transform 
    self._update_patch_transform() 
    File "/usr/local/lib/python2.7/site-packages/matplotlib/patches.py", line 576, in _update_patch_transform 
    bbox = transforms.Bbox.from_bounds(x, y, width, height) 
    File "/usr/local/lib/python2.7/site-packages/matplotlib/transforms.py", line 786, in from_bounds 
    return Bbox.from_extents(x0, y0, x0 + width, y0 + height) 
TypeError: coercing to Unicode: need string or buffer, float found 
+0

bạn có thể chia sẻ cụ thể những gì không hoạt động? Bạn có ngoại lệ không? Ngoại lệ là gì? Chia sẻ càng nhiều thông tin càng tốt. –

+0

@InbarRose xin lỗi, tôi đã cập nhật các câu hỏi với lỗi nó cho thấy ... một cái gì đó liên quan đến chuỗi hoặc bộ đệm ... Tôi không hiểu thông báo lỗi này. – otmezger

+2

Nó không rõ ràng những gì bạn muốn đạt được, nhưng trong 'ax.bar (D, phạm vi (1, len (D) +1,1), 0,5)' đối số đầu tiên phải là một danh sách các số, trong trường hợp của bạn ' D.values ​​() '. – adrianp

Trả lời

81

Bạn có thể làm điều đó trong hai dòng bằng cách đầu tiên vẽ biểu đồ thanh và sau đó thiết lập các ve thích hợp:

import matplotlib.pyplot as plt 

D = {u'Label1':26, u'Label2': 17, u'Label3':30} 

plt.bar(range(len(D)), list(D.values()), align='center') 
plt.xticks(range(len(D)), list(D.keys())) 
# # for python 2.x: 
# plt.bar(range(len(D)), D.values(), align='center') # python 2.x 
# plt.xticks(range(len(D)), D.keys()) # in python 2.x 

plt.show() 

Lưu ý rằng dòng áp chót nên đọc plt.xticks (phạm vi (len (D)), danh sách (D.keys())) trong python3, vì D.keys() trả về một trình tạo, mà matplotlib không thể sử dụng trực tiếp.

+2

bạn có thể bao bọc hai dòng đó trong một hàm và sau đó nó trở thành một lớp lót;) – tacaswell

+2

Nếu bạn sử dụng các đối tượng hình và trục, đó là 'ax.set_xticklabels ' – Mark

+1

cảm ơn! Nhưng tôi có một số vấn đề về estetic với plt.xticks, bạn có thể vui lòng cho chúng tôi biết cách di chuyển chúng theo chiều dọc từ chiều ngang. – moldovean

21

Để tham khảo trong tương lai, mã trên không hoạt động với Python 3. Đối với Python 3, D.keys() cần được chuyển đổi thành danh sách.

import matplotlib.pyplot as plt 

D = {u'Label1':26, u'Label2': 17, u'Label3':30} 

plt.bar(range(len(D)), D.values(), align='center') 
plt.xticks(range(len(D)), list(D.keys())) 

plt.show() 
0

Cách tốt nhất để triển khai bằng cách sử dụng matplotlib.pyplot.bar(range, height, tick_label) trong đó phạm vi cung cấp giá trị vô hướng cho vị trí của thanh tương ứng trong biểu đồ. tick_label thực hiện công việc giống như xticks(). Người ta cũng có thể thay thế nó bằng một số nguyên và sử dụng nhiều số plt.bar(integer, height, tick_label). Để biết thông tin chi tiết, vui lòng tham khảo documentation.

import matplotlib.pyplot as plt 

data = {'apple': 67, 'mango': 60, 'lichi': 58} 
names = list(data.keys()) 
values = list(data.values()) 

#tick_label does the some work as plt.xticks() 
plt.bar(range(len(data)),values,tick_label=names) 
plt.savefig('bar.png') 
plt.show() 

enter image description here

Ngoài cốt truyện tương tự có thể được tạo ra mà không sử dụng range(). Nhưng vấn đề gặp phải là tick_label chỉ hoạt động cho cuộc gọi plt.bar() cuối cùng. Do đó xticks() đã được sử dụng để đánh dấu:

data = {'apple': 67, 'mango': 60, 'lichi': 58} 
names = list(data.keys()) 
values = list(data.values()) 
plt.bar(0,values[0],tick_label=names[0]) 
plt.bar(1,values[1],tick_label=names[1]) 
plt.bar(2,values[2],tick_label=names[2]) 
plt.xticks(range(0,3),names) 
plt.savefig('fruit.png') 
plt.show() 

enter image description here

0

Tôi thường tải các dict vào một DataFrame gấu trúc sau đó sử dụng chức năng cốt truyện của DataFrame.
Đây là một trong những-liner:

pandas.DataFrame(D, index=['quantity']).plot(kind='bar') 

resulting plot

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