如何解决Matplotlib/Seaborn中折线与散点图独立图例重复问题
解决Matplotlib中散点图与折线图图例分离的问题
问题原因
你之前的代码中,第二次调用plt.legend(loc='center')时,Matplotlib会自动收集所有带有label属性的绘图元素(包括散点图的元素),因此导致折线图例中混入了散点项。要解决这个问题,需要在创建完散点图例后,移除散点元素的label,确保后续图例只包含折线相关内容。
修正后的完整代码
# 导入必要库 import matplotlib.pyplot as plt import seaborn as sns # ---------------------- # 散点图绘制部分 # ---------------------- scatter1 = plt.scatter(data=df[df.ABC < 10], x='Date', y='ABC', c='cyan', s=5, label='less') scatter2 = plt.scatter(data=df[(df.ABC >=10) & (df.ABC <40)], x='Date', y='ABC', c='dodgerblue', s=5, label='normal') scatter3 = plt.scatter(data=df[(df.ABC >=40) & (df.ABC <60)], x='Date', y='ABC', c='orangered', s=5, label='good') scatter4 = plt.scatter(data=df[df.ABC >60], x='Date', y='ABC', c='brown', s=5, label='more') # ---------------------- # 折线图及指标绘制部分 # ---------------------- # 空线条用于显示计算指标 plt.plot([], [], ' ', label=f'Points above Target Budget PR = {num}/{den} = {ans}%') # 移动平均线 sns.lineplot(x='Date', y='moving avg', data=df, color='red', linewidth=1.5, label='Moving Average') # Yield趋势线 sns.lineplot(x='Date', y='Yield', color='darkgreen', linewidth=1.5, data=df, label='Yield') # ---------------------- # 创建独立图例 # ---------------------- # 1. 创建散点图图例并添加到画布 legend_scatter = plt.legend(handles=[scatter1, scatter2, scatter3, scatter4], loc='upper left') plt.gca().add_artist(legend_scatter) # 2. 清空散点元素的label,避免被后续图例收集 for scatter in [scatter1, scatter2, scatter3, scatter4]: scatter.set_label(None) # 3. 创建折线图图例(仅包含折线和指标) plt.legend(loc='center') plt.show()
关键说明
- 先创建散点图例并通过
add_artist将其保留在画布上。 - 通过
scatter.set_label(None)清空散点的标签,这样后续调用plt.legend()时,只会收集折线图和指标行的标签。 - 最终实现两个独立图例:左上角的散点图例,中心的折线图例。
内容的提问来源于stack exchange,提问作者Hatim Jhalodwala
相关产品推荐
相关产品推荐

