122 votes

Tracer une barre avec matplotlib en utilisant un dictionnaire

Existe-t-il un moyen de tracer un diagramme à barres en utilisant matplotlib en utilisant des données provenant directement d'un dict ?

Ma dictée ressemble à ça :

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

Je m'attendais

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)

pour fonctionner, mais ce n'est pas le cas.

Voici l'erreur :

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

194voto

David Zwicker Points 4319

Vous pouvez le faire en deux lignes en traçant d'abord le graphique à barres, puis en définissant les ticks appropriés :

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

Notez que l'avant-dernière ligne doit se lire plt.xticks(range(len(D)), list(D.keys())) dans python3, car D.keys() renvoie un générateur, que matplotlib ne peut pas utiliser directement.

88voto

C'est un peu plus simple que ce que suggèrent la plupart des réponses ici :

import matplotlib.pyplot as plt

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

enter image description here

40voto

Michael T Points 995

Pour référence future, le code ci-dessus ne fonctionne pas avec Python 3. Pour Python 3, l'option D.keys() doit être converti en liste.

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

10voto

Swaraj Kumar Points 313

La meilleure façon de le mettre en œuvre en utilisant matplotlib.pyplot.bar(range, height, tick_label) où la plage fournit des valeurs scalaires pour le positionnement de la barre correspondante dans le graphique. tick_label fait le même travail que xticks() . On peut aussi le remplacer par un nombre entier et utiliser de multiples plt.bar(integer, height, tick_label) . Pour des informations détaillées, veuillez vous référer au 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

En outre, le même tracé peut être généré sans utiliser range() . Mais le problème rencontré était que tick_label juste travaillé pour la dernière plt.bar() appel. D'où xticks() a été utilisé pour l'étiquetage :

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

9voto

Hong Z Points 94

Pourquoi ne pas simplement :

names, counts = zip(*D.items())
plt.bar(names, counts)

enter image description here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X