120

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
4

7 回答 7

192

您可以通过首先绘制条形图然后设置适当的刻度来分两行执行此操作:

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 不能直接使用。

于 2013-04-15T12:13:32.413 回答
85

它比这里的大多数答案建议的要简单一些:

import matplotlib.pyplot as plt

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

在此处输入图像描述

于 2018-11-22T13:35:52.927 回答
41

为了将来参考,上述代码不适用于 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()
于 2015-03-18T05:25:27.543 回答
10

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

在此处输入图像描述

于 2018-01-26T03:56:22.967 回答
9

为什么不只是:

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

在此处输入图像描述

于 2021-01-16T23:00:51.857 回答
7

为什么不只是:

import seaborn as sns

sns.barplot(list(D.keys()), list(D.values()))
于 2019-08-14T18:02:35.347 回答
6

我经常将 dict 加载到 pandas DataFrame 中,然后使用 DataFrame 的绘图功能。
这是单线:

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

结果图

于 2018-03-01T17:07:10.143 回答