Plot batang menggunakan matplotlib menggunakan kamus

95

Apakah ada cara untuk memplot plot batang matplotlibmenggunakan data langsung dari dict?

Dtk saya terlihat seperti ini:

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

Saya mengharapkan

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)

bekerja, tetapi tidak.

Inilah kesalahannya:

>>> 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
otmezger
sumber
Dapatkah Anda membagikan secara spesifik apa yang tidak berhasil? Apakah Anda mendapat pengecualian? Pengecualian apa? Bagikan informasi sebanyak mungkin.
Inbar Rose
@InbarRose maaf, saya telah memperbarui pertanyaan dengan kesalahan yang ditunjukkannya ... sesuatu tentang string atau buffer ... Saya tidak mengerti pesan kesalahan ini.
otmezger
2
Tidak jelas apa yang ingin Anda capai, tetapi dalam ax.bar(D,range(1,len(D)+1,1),0.5)argumen pertama harus berupa daftar angka, dalam kasus Anda D.values().
adrianp
2
Satu baris tidak mungkin untuk ini, setidaknya menurut pengetahuan saya.
adrianp
1
Anda mungkin ingin mengirimkan permintaan fitur ke situs github untuk ini, karena tampaknya berguna.
tacaswell

Jawaban:

161

Anda dapat melakukannya dalam dua baris dengan memplot diagram batang terlebih dahulu, kemudian menetapkan tanda centang yang sesuai:

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

Perhatikan bahwa baris kedua dari belakang harus dibaca plt.xticks(range(len(D)), list(D.keys()))dalam python3, karena D.keys()mengembalikan generator, yang tidak dapat digunakan matplotlib secara langsung.

David Zwicker
sumber
2
Anda tentu saja dapat
menggabungkan
2
Jika Anda menggunakan objek gambar dan sumbu, ituax.set_xticklabels
Markus
2
Terima kasih! Tetapi saya memiliki beberapa masalah estetika dengan plt.xticks, dapatkah Anda memberi tahu kami cara memindahkannya secara vertikal dari horizontal.
moldovean
2
apakah key-value pair sejajar ketika dict tidak diurutkan?
ssm
2
Dicts Python tidak dapat diurutkan. Akibatnya, urutannya selalu sewenang-wenang. Namun, kunci dan nilai selalu selaras dengan kode di atas.
David Zwicker
41

Ini sedikit lebih sederhana daripada yang disarankan oleh kebanyakan jawaban di sini:

import matplotlib.pyplot as plt

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

masukkan deskripsi gambar di sini

ImportanceOfBeingErnest
sumber
35

Untuk referensi di masa mendatang, kode di atas tidak berfungsi dengan Python 3. Untuk Python 3, D.keys()perlu diubah ke daftar.

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()
Michael T
sumber
8

Cara terbaik untuk menerapkannya dengan menggunakan matplotlib.pyplot.bar(range, height, tick_label)rentang yang memberikan nilai skalar untuk posisi batang yang sesuai dalam grafik. tick_labelmelakukan pekerjaan yang sama seperti xticks(). Seseorang dapat menggantinya dengan integer juga dan menggunakan beberapa plt.bar(integer, height, tick_label). Untuk informasi rinci, silakan lihat dokumentasi .

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

masukkan deskripsi gambar di sini

Selain itu, plot yang sama dapat dibuat tanpa menggunakan range(). Tetapi masalah yang dihadapi adalah itu tick_labelhanya berfungsi untuk plt.bar()panggilan terakhir . Karenanya xticks()digunakan untuk pelabelan:

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

masukkan deskripsi gambar di sini

Swaraj Kumar
sumber
4

Saya sering memuat dict ke dalam DataFrame pandas kemudian menggunakan fungsi plot dari DataFrame.
Ini satu baris:

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

plot yang dihasilkan

anilbey
sumber
4

Mengapa tidak hanya:

import seaborn as sns

sns.barplot(list(D.keys()), list(D.values()))
rwilsker.dll
sumber