Plot dataframe then add vertical lines; how get custom legend text for all?

sas*_*ner 5 python matplotlib pandas

I can plot a dataframe (2 "Y" values) and add vertical lines (2) to the plot, and I can specify custom legend text for either the Y values OR the vertical lines, but not both at the same time.

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()
Run Code Online (Sandbox Code Playgroud)

A key line in the code is "plt.legend()". With it in the code, I get this (note legend has dataframe column labels "y1" and "y2" instead of my desired custom labels):

与plt.legend()调用

With "plt.legend()" removed, I get this (legend has my custom labels for the dataframe values only, legend for vertical lines does not even appear!):

没有plt.legend()调用

How can I get the best of both worlds, specifically the following (in whatever order) for my legend?:

y1custom
y2custom
vline1.5custom
vline3.5custom
Run Code Online (Sandbox Code Playgroud)

Sure I could rename the columns of the dataframe first, but...ugh! There must be a better way.

Imp*_*est 6

每次调用都会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()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明