使用字典使用 matplotlib 绘制条形图
Posted
技术标签:
【中文标题】使用字典使用 matplotlib 绘制条形图【英文标题】:Plot a bar using matplotlib using a dictionary 【发布时间】:2013-04-15 08:34:47 【问题描述】:有什么方法可以使用直接来自字典的数据使用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 抱歉,我已经用它显示的错误更新了这个问题......关于字符串或缓冲区的一些东西......我不明白这个错误消息。 不清楚你想要实现什么,但在ax.bar(D,range(1,len(D)+1,1),0.5)
中,第一个参数应该是一个数字列表,在你的情况下是D.values()
。
单行是不可能的,至少据我所知。
您可能需要为此向 github 站点提交功能请求,因为它看起来确实很有用。
【参考方案1】:
您可以通过首先绘制条形图然后设置适当的刻度来分两行完成:
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()
注意python3中倒数第二行应该是plt.xticks(range(len(D)), list(D.keys()))
,因为D.keys()
返回一个生成器,matplotlib不能直接使用。
【讨论】:
你当然可以将这两行包装在一个函数中,然后它变成一个单行;) 如果你使用图形和轴对象,它是ax.set_xticklabels
谢谢!但是我对 plt.xticks 有一些审美问题,请告诉我们如何从水平方向垂直移动它们。
dict未排序时键值对是否对齐?
Python dicts 无法排序。因此,顺序总是任意的。但是,键和值始终与上述代码对齐。【参考方案2】:
这比这里的大多数答案建议的要简单一些:
import matplotlib.pyplot as plt
D = u'Label1':26, u'Label2': 17, u'Label3':30
plt.bar(*zip(*D.items()))
plt.show()
【讨论】:
这应该是答案。 tnx【参考方案3】:为了将来参考,上述代码不适用于 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()
【讨论】:
【参考方案4】:使用matplotlib.pyplot.bar(range, height, tick_label)
实现它的最佳方式@ 范围为图中相应条形的位置提供标量值。 tick_label
与 xticks()
做同样的工作。也可以用整数替换它并使用多个plt.bar(integer, height, tick_label)
。详细信息请参考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()
此外,不使用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()
【讨论】:
【参考方案5】:为什么不只是:
names, counts = zip(*D.items())
plt.bar(names, counts)
【讨论】:
【参考方案6】:为什么不只是:
import seaborn as sns
sns.barplot(list(D.keys()), list(D.values()))
【讨论】:
【参考方案7】:我经常将 dict 加载到 pandas DataFrame 中,然后使用 DataFrame 的绘图功能。 这是单行:
pandas.DataFrame(D, index=['quantity']).plot(kind='bar')
【讨论】:
以上是关于使用字典使用 matplotlib 绘制条形图的主要内容,如果未能解决你的问题,请参考以下文章
使用 ax.bar() 使用 matplotlib 绘制多个条形图