Побудуйте смугу за допомогою matplotlib за допомогою словника


92

Чи є спосіб побудувати графік штанги, matplotlibвикористовуючи дані безпосередньо з дикту?

Мій дикт виглядає так:

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

Я очікував

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)

працювати, але це не так.

Ось помилка:

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

Чи можете ви поділитися конкретно тим, що не працює? Ви отримуєте виняток? Який виняток? Поділіться якомога більше інформації.
Інбар Роуз

@InbarRose вибачте, я оновив запитання помилкою, яку він показує ... щось, що стосується рядка або буфера ... Я не розумію це повідомлення про помилку.
otmezger

2
Незрозуміло, чого ви хочете досягти, але у ax.bar(D,range(1,len(D)+1,1),0.5)першому аргументі має бути список цифр, у вашому випадку D.values().
adrianp

2
Однокласник для цього неможливий, принаймні, наскільки мені відомо.
adrianp

1
Можливо, ви захочете надіслати запит на функцію на сайт github для цього, оскільки це видається корисним.
tacaswell

Відповіді:


154

Ви можете зробити це у два рядки, спочатку побудувавши гістограму, а потім встановивши відповідні галочки:

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

Зверніть увагу, що передостанній рядок повинен читатися plt.xticks(range(len(D)), list(D.keys()))на python3, оскільки D.keys()повертає генератор, який matplotlib не може використовувати безпосередньо.


2
Ви можете, звичайно, обернути ці два рядки у функцію, і тоді вона стане
однолінійною

2
Якщо ви використовуєте фігури та осі, цеax.set_xticklabels
Марк

2
Дякую! Але у мене є деякі естетичні проблеми з plt.xticks, не могли б ви сказати нам, як перемістити їх вертикально з горизонталі.
moldovean

2
чи вирівнюються пари ключ-значення, коли дикт не сортується?
ssm

2
Диктовки Python не можна сортувати. Отже, порядок завжди довільний. Однак ключі та значення завжди узгоджуються з вищевказаним кодом.
Девід Цвікер

36

Це трохи простіше, ніж пропонують більшість відповідей:

import matplotlib.pyplot as plt

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

введіть тут опис зображення


34

Для подальшої довідки наведений вище код не працює з Python 3. Для Python 3 D.keys()потреби потрібно перетворити на список.

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

Найкращий спосіб реалізувати це, використовуючи matplotlib.pyplot.bar(range, height, tick_label)де діапазон забезпечує скалярні значення для позиціонування відповідної смуги на графіку. tick_labelвиконує ту ж роботу, що і xticks(). Можна також замінити його цілим числом і використовувати множинне plt.bar(integer, height, tick_label). Для отримання детальної інформації, будь ласка, зверніться до документації .

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

введіть тут опис зображення

Крім того, той самий сюжет може бути сформований без використання range(). Але виникла проблема в тому, що tick_labelякраз спрацював на останній plt.bar()дзвінок. Отже, xticks()використовували для маркування:

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

введіть тут опис зображення


4

Я часто завантажую дикт у pandas DataFrame, а потім використовую графічну функцію DataFrame.
Ось однокласний:

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

отриманий сюжет


3

Чому не просто:

import seaborn as sns

sns.barplot(list(D.keys()), list(D.values()))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.