Seaborn regplot图例异常:图例显示圆点而非对应回归线
Seaborn regplot图例无法对应回归线的问题解决
问题描述
使用Seaborn的regplot绘制自然灾害事件数据的回归线时,图表图例显示为圆点,无法对应各灾害类型的回归线;但改用lineplot时图例显示正常。代码如下:
import pandas as pd import matplotlib.pyplot as plt import seaborn as sns df = pd.read_csv(r'C:\Users\ASUS\Downloads\number-of-natural-disaster-events.csv') df.drop(['Code'], axis = 1) df_pivot = df.pivot(index='Year',columns='Entity',values='Number of reported natural disasters (reported disasters)') df_pivot = df_pivot.drop(['Impact'],axis=1) df_pivot = df_pivot.fillna(0) df_pivot = df_pivot.reset_index() fig, ax = plt.subplots(1, 1, sharey=True, sharex=True, figsize=(20, 10)) legend = [] for col in df_pivot.columns: if col != "Year": sns.regplot(ax=ax,data=df_pivot,x="Year", y=col) legend.append(col) ax.legend(legend,bbox_to_anchor=(0.5, -0.1),fancybox=True,loc='upper center',shadow=True, ncol=2)
问题原因
regplot默认同时绘制散点数据和拟合回归线,Matplotlib默认提取散点的标记作为图例项,而非回归线的线条,因此图例显示为圆点。- 循环中每次调用
ax.legend()会重复生成图例,覆盖之前的设置,导致图例与线条无法正确对应。 - 原代码中
df.drop(['Code'], axis=1)未赋值给df,会导致后续处理仍包含Code列,属于潜在问题。
解决方法
方法一:仅绘制回归线(隐藏散点)
如果不需要显示原始散点,只保留回归线,可在regplot中设置scatter=False,同时给每个回归线指定label参数,最后统一生成图例:
import pandas as pd import matplotlib.pyplot as plt import seaborn as sns df = pd.read_csv(r'C:\Users\ASUS\Downloads\number-of-natural-disaster-events.csv') # 修正drop操作的赋值问题 df = df.drop(['Code'], axis = 1) df_pivot = df.pivot(index='Year',columns='Entity',values='Number of reported natural disasters (reported disasters)') df_pivot = df_pivot.drop(['Impact'],axis=1) df_pivot = df_pivot.fillna(0) df_pivot = df_pivot.reset_index() fig, ax = plt.subplots(1, 1, sharey=True, sharex=True, figsize=(20, 10)) for col in df_pivot.columns: if col != "Year": # 隐藏散点,指定label对应灾害类型 sns.regplot(ax=ax, data=df_pivot, x="Year", y=col, scatter=False, label=col) # 统一生成底部图例 ax.legend(bbox_to_anchor=(0.5, -0.1), fancybox=True, loc='upper center', shadow=True, ncol=2) plt.show()
方法二:保留散点+回归线,生成对应图例
如果需要同时显示散点和回归线,需手动提取每个regplot返回的线条与散点元素,组合成匹配的图例项:
import pandas as pd import matplotlib.pyplot as plt import seaborn as sns df = pd.read_csv(r'C:\Users\ASUS\Downloads\number-of-natural-disaster-events.csv') df = df.drop(['Code'], axis = 1) df_pivot = df.pivot(index='Year',columns='Entity',values='Number of reported natural disasters (reported disasters)') df_pivot = df_pivot.drop(['Impact'],axis=1) df_pivot = df_pivot.fillna(0) df_pivot = df_pivot.reset_index() fig, ax = plt.subplots(1, 1, sharey=True, sharex=True, figsize=(20, 10)) legend_elements = [] for col in df_pivot.columns: if col != "Year": # 获取regplot返回的散点和线条对象 scatter, line = sns.regplot(ax=ax, data=df_pivot, x="Year", y=col) # 组合线条与散点为图例项 legend_elements.append(plt.Line2D([], [], color=line.get_color(), marker=scatter.get_markers()[0], linestyle='-', label=col)) # 用手动创建的图例元素生成对应图例 ax.legend(handles=legend_elements, bbox_to_anchor=(0.5, -0.1), fancybox=True, loc='upper center', shadow=True, ncol=2) plt.show()
内容的提问来源于stack exchange,提问作者mobly elliot
相关产品推荐
相关产品推荐

