修改熊猫条形图的图例

当我和熊猫一起制作一个酒吧阴谋的时候,我总是很烦恼,我想改变图例中标签的名字。例如,考虑下面这段代码的输出:

import pandas as pd
from matplotlib.pyplot import *


df = pd.DataFrame({'A':26, 'B':20}, index=['N'])
df.plot(kind='bar')

enter image description here 现在,如果我想改变传说中的名字,我通常会这样做:

legend(['AAA', 'BBB'])

但最后我得到了这个:

enter image description here

事实上,第一个虚线似乎对应着另一个补丁。

因此,我想知道是否有一个改变标签的简单技巧,还是需要使用 matplotlib 独立绘制每个列并自己设置标签。谢谢。

200705 次浏览

To change the labels for Pandas df.plot() use ax.legend([...]):

import pandas as pd
import matplotlib.pyplot as plt


fig, ax = plt.subplots()
df = pd.DataFrame({'A':26, 'B':20}, index=['N'])
df.plot(kind='bar', ax=ax)
#ax = df.plot(kind='bar') # "same" as above
ax.legend(["AAA", "BBB"]);

enter image description here

Another approach is to do the same by plt.legend([...]):

import matplotlib.pyplot as plt
df.plot(kind='bar')
plt.legend(["AAA", "BBB"]);

enter image description here

If you need to call plot multiply times, you can also use the "label" argument:

ax = df1.plot(label='df1', y='y_var')
ax = df2.plot(label='df2', y='y_var')

While this is not the case in the OP question, this can be helpful if the DataFrame is in long format and you use groupby before plotting.

This is slightly an edge case but I think it can add some value to the other answers.

If you add more details to the graph (say an annotation or a line) you'll soon discover that it is relevant when you call legend on the axis: if you call it at the bottom of the script it will capture different handles for the legend elements, messing everything.

For instance the following script:

df = pd.DataFrame({'A':26, 'B':20}, index=['N'])
ax = df.plot(kind='bar')
ax.hlines(23, -.5,.5, linestyles='dashed')
ax.annotate('average',(-0.4,23.5))


ax.legend(["AAA", "BBB"]); #quickfix: move this at the third line

Will give you this figure, which is wrong: enter image description here

While this a toy example which can be easily fixed by changing the order of the commands, sometimes you'll need to modify the legend after several operations and hence the next method will give you more flexibility. Here for instance I've also changed the fontsize and position of the legend:

df = pd.DataFrame({'A':26, 'B':20}, index=['N'])
ax = df.plot(kind='bar')
ax.hlines(23, -.5,.5, linestyles='dashed')
ax.annotate('average',(-0.4,23.5))
ax.legend(["AAA", "BBB"]);


# do potentially more stuff here


h,l = ax.get_legend_handles_labels()
ax.legend(h[:2],["AAA", "BBB"], loc=3, fontsize=12)

This is what you'll get:

enter image description here