如何在matplotlib的pandas柱状图上添加线条?

5 投票
1 回答
12861 浏览
提问于 2025-04-18 07:48

你好,我已经在柱状图中添加了一条线,但位置不太对。我想把这些点放在每个柱子的正中间。有人能帮忙吗?

>>> df
   price       cost        net
0   22.5 -20.737486   1.364360
1   35.5 -19.285862  16.695847
2   13.5 -20.456378  -9.016052
3    5.0 -19.643776 -17.539636
4   13.5 -27.015138 -15.964597
5    5.0 -24.267836 -22.618819
6   18.0 -21.096404  -7.357684
7    5.0 -24.691966 -24.116106
8    5.0 -25.755958 -22.080329
9   25.0 -26.352161  -2.781588

fig = plt.figure()
df[['price','cost']].plot(kind = 'bar',stacked = True,color = ['grey','navy'])
df['net'].plot('o',color = 'orange',linewidth=2.0,use_index = True)

enter image description here

1 个回答

10

更新:这个问题将在即将发布的0.14版本中修复(到时候你上面的代码就能正常工作了),对于旧版的pandas,我下面的回答可以作为解决方法。


你遇到的问题是,柱状图上显示的x轴标签和matplotlib实际使用的坐标并不完全对应。
比如,在matplotlib的默认bar图中,第一个矩形(标签为0的第一个柱子)会在x坐标0到0.8之间绘制(柱子的宽度是0.8)。所以如果你想在这个柱子的中间绘制一个点或线,这个点的x坐标应该是0.4,而不是0!

为了解决你的问题,你可以这样做:

In [3]: ax = df[['price','cost']].plot(kind = 'bar',stacked = True,color = ['grey','navy'])

In [4]: ax.get_children()[3]
Out[4]: <matplotlib.patches.Rectangle at 0x16f2aba8>

In [5]: ax.get_children()[3].get_width()
Out[5]: 0.5

In [6]: ax.get_children()[3].get_bbox()
Out[6]: Bbox('array([[  0.25,   0.  ],\n       [  0.75,  22.5 ]])')

In [7]: plt.plot(df.index+0.5, df['net'],color = 'orange',linewidth=2.0)

我使用ax.get_children()[3].get_width().get_bbox()来检查你图中柱子的实际宽度和坐标,因为pandas似乎没有使用matplotlib的默认值(0.5这个值实际上是从0.25(y轴到第一个柱子的偏移量)加上0.5/2(宽度的一半)得来的)。

所以我实际做的是把df['net'].plot(use_index = True)改成了plt.plot(df.index + 0.5, df['net'])

这样我得到了:

在这里输入图片描述

撰写回答