在pandas中为分组柱状图绘制误差条
我可以像这样在单个系列的条形图上绘制误差条:
import pandas as pd
df = pd.DataFrame([[4,6,1,3], [5,7,5,2]], columns = ['mean1', 'mean2', 'std1', 'std2'], index=['A', 'B'])
print(df)
mean1 mean2 std1 std2
A 4 6 1 3
B 5 7 5 2
df['mean1'].plot(kind='bar', yerr=df['std1'], alpha = 0.5,error_kw=dict(ecolor='k'))
正如预期的那样,索引A的平均值和同一索引的标准差是配对的,误差条显示了这个值的正负范围。
但是,当我尝试在同一个图中绘制'平均值1'和'平均值2'时,我无法以相同的方式使用标准差:
df[['mean1', 'mean2']].plot(kind='bar', yerr=df[['std1', 'std2']], alpha = 0.5,error_kw=dict(ecolor='k'))
Traceback (most recent call last):
File "<ipython-input-587-23614d88a3c5>", line 1, in <module>
df[['mean1', 'mean2']].plot(kind='bar', yerr=df[['std1', 'std2']], alpha = 0.5,error_kw=dict(ecolor='k'))
File "C:\Users\name\Dropbox\Tools\WinPython-64bit-2.7.6.2\python-2.7.6.amd64\lib\site-packages\pandas\tools\plotting.py", line 1705, in plot_frame
plot_obj.generate()
File "C:\Users\name\Dropbox\Tools\WinPython-64bit-2.7.6.2\python-2.7.6.amd64\lib\site-packages\pandas\tools\plotting.py", line 878, in generate
self._make_plot()
File "C:\Users\name\Dropbox\Tools\WinPython-64bit-2.7.6.2\python-2.7.6.amd64\lib\site-packages\pandas\tools\plotting.py", line 1534, in _make_plot
start=start, label=label, **kwds)
File "C:\Users\name\Dropbox\Tools\WinPython-64bit-2.7.6.2\python-2.7.6.amd64\lib\site-packages\pandas\tools\plotting.py", line 1481, in f
return ax.bar(x, y, w, bottom=start,log=self.log, **kwds)
File "C:\Users\nameDropbox\Tools\WinPython-64bit-2.7.6.2\python-2.7.6.amd64\lib\site-packages\matplotlib\axes.py", line 5075, in bar
fmt=None, **error_kw)
File "C:\Users\name\Dropbox\Tools\WinPython-64bit-2.7.6.2\python-2.7.6.amd64\lib\site-packages\matplotlib\axes.py", line 5749, in errorbar
iterable(yerr[0]) and iterable(yerr[1])):
File "C:\Users\name\Dropbox\Tools\WinPython-64bit-2.7.6.2\python-2.7.6.amd64\lib\site-packages\pandas\core\frame.py", line 1635, in __getitem__
return self._getitem_column(key)
File "C:\Users\name\Dropbox\Tools\WinPython-64bit-2.7.6.2\python-2.7.6.amd64\lib\site-packages\pandas\core\frame.py", line 1642, in _getitem_column
return self._get_item_cache(key)
File "C:\Users\name\Dropbox\Tools\WinPython-64bit-2.7.6.2\python-2.7.6.amd64\lib\site-packages\pandas\core\generic.py", line 983, in _get_item_cache
values = self._data.get(item)
File "C:\Users\name\Dropbox\Tools\WinPython-64bit-2.7.6.2\python-2.7.6.amd64\lib\site-packages\pandas\core\internals.py", line 2754, in get
_, block = self._find_block(item)
File "C:\Users\name\Dropbox\Tools\WinPython-64bit-2.7.6.2\python-2.7.6.amd64\lib\site-packages\pandas\core\internals.py", line 3065, in _find_block
self._check_have(item)
File "C:\Users\name\Dropbox\Tools\WinPython-64bit-2.7.6.2\python-2.7.6.amd64\lib\site-packages\pandas\core\internals.py", line 3072, in _check_have
raise KeyError('no item named %s' % com.pprint_thing(item))
KeyError: u'no item named 0'
我得到的最接近我想要的结果是这个:
df[['mean1', 'mean2']].plot(kind='bar', yerr=df[['std1', 'std2']].values.T, alpha = 0.5,error_kw=dict(ecolor='k'))
但现在误差条并没有对称绘制。相反,每个系列中的绿色和蓝色条形图使用了相同的正负误差,这让我卡住了。我该如何让我的多系列条形图的误差条看起来和只有一个系列时一样呢?
更新: 看起来在 pandas 0.14 中这个问题已经解决了,我之前在看0.13的文档。不过我现在不能升级我的pandas,稍后会再试试,看看效果如何。
1 个回答
15
yerr=df[['std1', 'std2']]
这个写法不行,因为列名和df[['mean1', 'mean2']]
的列名不一样。- 当你把值传给
yerr
时,如果用的是数据框(dataframe),那么列名必须和数据列(比如mean1
和mean2
)一致。 - 可以参考这个链接:在pandas中给分组柱状图添加误差条
- 当你把值传给
- 使用
df[['std1', 'std2']].to_numpy().T
可以绕过这个问题,因为它传递的是没有列名的误差数组。 - 在
python 3.8.11
、pandas 1.3.3
和matplotlib 3.4.3
中测试过
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame([[4,6,1,3], [5,7,5,2]], columns = ['mean1', 'mean2', 'std1', 'std2'], index=['A', 'B'])
mean1 mean2 std1 std2
A 4 6 1 3
B 5 7 5 2
# convert the std columns to an array
yerr = df[['std1', 'std2']].to_numpy().T
# print(yerr)
array([[1, 5],
[3, 2]], dtype=int64)
df[['mean1', 'mean2']].plot(kind='bar', yerr=yerr, alpha=0.5, error_kw=dict(ecolor='k'))
plt.show()