Python中用Matplotlib绘制Pandas DataFrame时设置正确图例的方法
问题:Pandas绘图时自定义图例匹配线条与标签
我有三个索引和列完全一致的Pandas DataFrame:df_demand、df_wind和df_net_load,数据示例如下:
df_demand的数据:
0 15 30 45 60 75 Time of the year (hour) Average >0 0 58.080597 113.445783 167.798799 223.263636 274.433735 Average <0 0 -48.649215 -93.236364 -138.090909 -180.785530 -225.054688
三个DataFrame的字典形式:
df_demand.to_dict():
{0: {'Average >0': 0, 'Average <0': 0}, 15: {'Average >0': 58.080597014925374, 'Average <0': -48.64921465968586}, 30: {'Average >0': 113.44578313253012, 'Average <0': -93.23636363636363}, 45: {'Average >0': 167.7987987987988, 'Average <0': -138.0909090909091}, 60: {'Average >0': 223.26363636363635, 'Average <0': -180.78552971576227}, 75: {'Average >0': 274.43373493975906, 'Average <0': -225.0546875}}
df_wind.to_dict():
{0: {'Average >0': 0, 'Average <0': 0}, 15: {'Average >0': 31.842261904761905, 'Average <0': -33.68783068783069}, 30: {'Average >0': 47.05278592375367, 'Average <0': -53.523936170212764}, 45: {'Average >0': 61.620588235294115, 'Average <0': -71.53439153439153}, 60: {'Average >0': 73.28323699421965, 'Average <0': -90.23783783783784}, 75: {'Average >0': 88.0632530120482, 'Average <0': -102.3733681462141}}
df_net_load.to_dict():
{0: {'Average >0': 0, 'Average <0': 0}, 15: {'Average >0': 31.842261904761905, 'Average <0': -33.68783068783069}, 30: {'Average >0': 47.05278592375367, 'Average <0': -53.523936170212764}, 45: {'Average >0': 61.620588235294115, 'Average <0': -71.53439153439153}, 60: {'Average >0': 73.28323699421965, 'Average <0': -90.23783783783784}, 75: {'Average >0': 88.0632530120482, 'Average <0': -102.3733681462141}}
我用以下代码绘图:
fig, ax = plt.subplots() df_demand.T.plot(ax = ax, color = ["blue", "blue"]) df_wind.T.plot(ax = ax, color = ["green", "green"]) df_net_load.T.plot(ax = ax, color = ["red", "red"]) plt.show()
希望图例仅显示蓝、绿、红各一条线,分别标注为Demand、Wind和Net load。
尝试了两种方法都有问题:
- 提取线条和标签并间隔选取:
lines, labels = ax.get_legend_handles_labels() plt.legend(lines[::2], labels[::2])
线条正确,但标签不是想要的。
- 手动指定标签:
lines= ax.get_legend_handles_labels()[0] plt.legend(lines[::2], labels = ["Demand", "Wind", "Net load"])
标签和线条对应关系错误。
请问如何正确设置图例,使线条与对应标签准确匹配?
解决方案
方法一:绘图时直接控制图例(推荐)
在调用plot()方法时,通过label参数指定每个DataFrame的图例名称,同时关闭每列的自动图例,最后统一添加图例:
fig, ax = plt.subplots() # 绘制每个DataFrame,指定整体标签,关闭自动图例 df_demand.T.plot(ax=ax, color=["blue", "blue"], legend=False, label="Demand") df_wind.T.plot(ax=ax, color=["green", "green"], legend=False, label="Wind") df_net_load.T.plot(ax=ax, color=["red", "red"], legend=False, label="Net load") # 添加自定义图例 ax.legend() plt.show()
方法二:事后修正图例
如果已经完成绘图,需要调整现有图例,可以通过提取每个DataFrame对应的第一条线条,然后手动关联标签:
fig, ax = plt.subplots() df_demand.T.plot(ax=ax, color=["blue", "blue"]) df_wind.T.plot(ax=ax, color=["green", "green"]) df_net_load.T.plot(ax=ax, color=["red", "red"]) # 获取所有线条 lines = ax.get_legend_handles_labels()[0] # 每个DataFrame对应2条线,取第0、2、4条分别对应Demand、Wind、Net load custom_lines = [lines[0], lines[2], lines[4]] custom_labels = ["Demand", "Wind", "Net load"] ax.legend(custom_lines, custom_labels) plt.show()
这两种方法都能确保蓝色线条对应Demand,绿色对应Wind,红色对应Net load,且图例只显示每条颜色的一个条目。
内容的提问来源于stack exchange,提问作者hbstha123
相关产品推荐
相关产品推荐

