循环绘制多DataFrame时plt.legend()的图例设置问题
Pandas绘图自定义图例问题解决
问题场景
原始代码如下:
import pandas as pd import matplotlib.pyplot as plt df1 = pd.DataFrame({"A" : [1,2,3], "B" : [4,5,6]}) df2 = pd.DataFrame({"A" : [2,5,3], "B" : [7,3,1]}) df3 = pd.DataFrame({"A" : [1,2,1], "B" : [5,3,6]}) dframes = [df1, df2, df3] for frame in dframes: frame["C"] = frame["A"] + frame["B"] plt.plot(frame["C"])
绘图正常,但添加图例时遇到问题:
- 直接调用
plt.legend()报错:No artists with labels found to put in legend - 若传入
frame到legend,图例显示列名"A""B""C",而非期望的"df1""df2""df3"
解决方案
方法1:绘图时指定label参数
将DataFrame与对应名称打包成元组列表,循环时给每个plot指定自定义label:
import pandas as pd import matplotlib.pyplot as plt df1 = pd.DataFrame({"A" : [1,2,3], "B" : [4,5,6]}) df2 = pd.DataFrame({"A" : [2,5,3], "B" : [7,3,1]}) df3 = pd.DataFrame({"A" : [1,2,1], "B" : [5,3,6]}) # 绑定DataFrame和自定义名称 dframes = [(df1, "df1"), (df2, "df2"), (df3, "df3")] for frame, name in dframes: frame["C"] = frame["A"] + frame["B"] # 绘图时设置label为自定义名称 plt.plot(frame["C"], label=name) # 直接生成图例 plt.legend() plt.show()
方法2:手动收集线条句柄和标签
如果不想修改原列表结构,可手动收集每个线条的句柄,再传入legend:
import pandas as pd import matplotlib.pyplot as plt df1 = pd.DataFrame({"A" : [1,2,3], "B" : [4,5,6]}) df2 = pd.DataFrame({"A" : [2,5,3], "B" : [7,3,1]}) df3 = pd.DataFrame({"A" : [1,2,1], "B" : [5,3,6]}) dframes = [df1, df2, df3] custom_labels = ["df1", "df2", "df3"] line_handles = [] for frame, label in zip(dframes, custom_labels): frame["C"] = frame["A"] + frame["B"] # 获取单个线条的句柄(注意逗号,解包返回的列表) line, = plt.plot(frame["C"]) line_handles.append(line) # 传入句柄和自定义标签生成图例 plt.legend(handles=line_handles, labels=custom_labels) plt.show()
问题原因
- 原始代码中
plt.plot(frame["C"])未给线条设置label,legend无法识别可标注的元素,因此报错。 - 若直接传
frame给legend,matplotlib会默认将DataFrame的列名作为标签,导致显示不符合预期。
内容的提问来源于stack exchange,提问作者krawall
相关产品推荐
相关产品推荐

