You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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。

尝试了两种方法都有问题:

  1. 提取线条和标签并间隔选取:
lines, labels = ax.get_legend_handles_labels()
plt.legend(lines[::2], labels[::2])

线条正确,但标签不是想要的。

  1. 手动指定标签:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 06:39:34