绘制数据帧然后添加垂直线;如何为所有人获得自定义图例文字?

时间:2018-03-15 14:28:31

标签: python pandas matplotlib

我可以绘制一个数据帧(2“Y”值)并将垂直线(2)添加到绘图中,我可以为Y值或垂直线指定自定义图例文本,但不能同时指定两者

import pandas as pd
import matplotlib.pyplot as plt

d = {'x' : [1., 2., 3., 4.], 'y1' : [8., 6., 4., 2.], 'y2' : [-4., 13., 2.2, -1.1]}
df = pd.DataFrame(d)
ax = df.plot(x='x', y=['y1'], linestyle='-', color='b')
df.plot(x='x', y=['y2'], linestyle='--', color='y', ax=ax)
ax.legend(labels=['y1custom', 'y2custom'])
plt.axvline(x=1.5, color='r', linestyle='--', label='vline1.5custom')
plt.axvline(x=3.5, color='k', linestyle='--', label='vline3.5custom')
plt.legend()        # <---- comment out....or not....for different effects
plt.show()

代码中的关键行是“plt.legend()”。在代码中,我得到了这个(注意图例有数据框列标签“y1”和“y2”而不是我想要的自定义标签):

NameBasedSSLVHostsWithSNI

删除“plt.legend()”后,我得到了这个(图例只有数据框值的自定义标签,垂直线的图例甚至没有出现!):

with plt.legend() call

我怎样才能充分利用这两个世界,特别是以下(以任何顺序)为我的传奇?:

y1custom
y2custom
vline1.5custom
vline3.5custom

当然我可以先重命名数据框的列,但是......呃!必须有更好的方法。

3 个答案:

答案 0 :(得分:4)

每次调用legend()都会覆盖最初创建的图例。因此,您需要创建一个包含所有所需标签的单个图例。

这意味着您可以通过ax.get_legend_handles_labels()获取当前标签,并用其他内容替换您不喜欢的标签。然后在调用legend()时指定新的标签列表。

import pandas as pd
import matplotlib.pyplot as plt

d = {'x' : [1., 2., 3., 4.], 'y1' : [8., 6., 4., 2.], 'y2' : [-4., 13., 2.2, -1.1]}
df = pd.DataFrame(d)
ax = df.plot(x='x', y=['y1'], linestyle='-', color='b')
df.plot(x='x', y=['y2'], linestyle='--', color='y', ax=ax)

ax.axvline(x=1.5, color='r', linestyle='--', label='vline1.5custom')
ax.axvline(x=3.5, color='k', linestyle='--', label='vline3.5custom')

h,labels = ax.get_legend_handles_labels()
labels[:2] = ['y1custom','y2custom']
ax.legend(labels=labels)

plt.show()

enter image description here

答案 1 :(得分:1)

只要您指定要绘制的列,就可以将

label传递给plot()

import pandas as pd
import matplotlib.pyplot as plt

d = {'x' : [1., 2., 3., 4.], 'y1' : [8., 6., 4., 2.], 'y2' : [-4., 13., 2.2, -1.1]}
df = pd.DataFrame(d)

ax = df['y1'].plot(x='x', linestyle='-', color='b', label='y1custom')
df['y2'].plot(x='x', linestyle='--', color='y', ax=ax, label='y2custom')
plt.axvline(x=1.5, color='r', linestyle='--', label='vline1.5custom')
plt.axvline(x=3.5, color='k', linestyle='--', label='vline3.5custom')
plt.legend()
plt.show()

这种方法避免了之后不得不乱用传说:

matplotlib figure+custom legend

答案 2 :(得分:0)

你可以这样做:

d = {'x' : [1., 2., 3., 4.], 'y1' : [8., 6., 4., 2.], 'y2' : [-4., 13., 2.2, -1.1]}
df = pd.DataFrame(d)
ax = df.plot(x='x', y=['y1'], linestyle='-', color='b')
df.plot(x='x', y=['y2'], linestyle='--', color='y', ax=ax)
l1 = plt.axvline(x=1.5, color='r', linestyle='--', label='vline1.5custom')
l2 = plt.axvline(x=3.5, color='k', linestyle='--', label='vline3.5custom')
#move ax.legend after axvlines and get_label
ax.legend(labels=['y1custom', 'y2custom',l1.get_label(),l2.get_label()])
plt.show()

输出:

enter image description here