Vẽ một thanh bằng matplotlib bằng từ điển


92

Có cách nào để vẽ một biểu đồ thanh bằng matplotlibcách sử dụng dữ liệu trực tiếp từ một chính tả không?

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

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

Tôi đã mong đợi

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.

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

Bạn có thể chia sẻ cụ thể những gì không hoạt động? Bạn có nhận được một ngoại lệ? Ngoại lệ nào? Chia sẻ càng nhiều thông tin càng tốt.
Inbar Rose,

@InbarRose xin lỗi, tôi đã cập nhật câu hỏi với lỗi mà nó hiển thị ... điều 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
Không rõ bạn muốn đạt được điều gì, nhưng ax.bar(D,range(1,len(D)+1,1),0.5)đối số đầu tiên phải là danh sách các con số, trong trường hợp của bạn D.values().
adrianp

2
Điều này là không thể một lớp lót, ít nhất là theo hiểu biết của tôi.
adrianp

1
Bạn có thể muốn gửi một yêu cầu tính năng tới trang github cho việc này, vì nó có vẻ hữu ích.
tacaswell

Câu trả lời:


154

Bạn có thể làm điều đó trong hai dòng bằng cách vẽ biểu đồ thanh trước tiên và sau đó đặt các dấu tích 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(range(len(D)), list(D.keys()))bằng python3, vì D.keys()trả về trình tạo, matplotlib không thể sử dụng trực tiếp.


2
bạn có thể tất nhiên quấn hai dòng lên 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
Đánh dấu

2
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

2
các cặp khóa-giá trị có được căn chỉnh khi dict không được sắp xếp không?
ssm

2
Không thể phân loại Python. Do đó, thứ tự luôn luôn là tùy ý. Tuy nhiên, các khóa và giá trị luôn được căn chỉnh với mã trên.
David Zwicker

36

Nó đơn giản hơn một chút so với hầu hết các câu trả lời ở đây đề xuất:

import matplotlib.pyplot as plt

D = {u'Label1':26, u'Label2': 17, u'Label3':30}
plt.bar(*zip(*D.items()))
plt.show()

nhập mô tả hình ảnh ở đây


34

Để tham khảo trong tương lai, đoạn mã trên không hoạt động với Python 3. Đối với Python 3, D.keys()cần 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()

8

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

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

nhập mô tả hình ảnh ở đây

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

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

nhập mô tả hình ảnh ở đây


4

Tôi thường tải dict vào một DataFrame gấu trúc, sau đó sử dụng hàm âm mưu của DataFrame.
Đây là một lớp lót:

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

âm mưu kết quả


3

Tại sao không chỉ:

import seaborn as sns

sns.barplot(list(D.keys()), list(D.values()))
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.