如何在Seaborn散点图图例中排除hue变量,仅显示标记标签?
解决Seaborn散点图仅显示分组标记图例的问题
问题场景
用Seaborn绘制两组散点图,分别用菱形(D)和叉形(X)标记区分"White"和"Black",同时通过hue映射对手的Elo值,但图例自动混入了hue对应的所有条目,无法只保留两组标记的标签。尝试以下方法均出现问题:
- 直接指定
ax.legend(labels=['White', 'Black']):第二组标记显示错误(变成圆形而非叉形) - 指定
handles=[plot_white, plot_black]:图例为空,且报错提示不支持AxesSubplot实例
原始代码:
fig, ax = plt.subplots(1,1) plot_white = sns.scatterplot(data=df_white, x='EngCorr_Player', y='EngCorr_Opponent', hue='Elo_Opponent', ax=ax, marker='D', label='White') plot_black = sns.scatterplot(data=df_black, x='EngCorr_Player', y='EngCorr_Opponent', hue='Elo_Opponent', ax=ax, marker='X', s=140, label='Black') ax.legend() plt.show()
解决方案
方法1:手动创建代理艺术家
因为seaborn.scatterplot返回的是Axes对象,不是图例可识别的Artist,所以可以手动创建代理元素模拟两组散点的样式:
import matplotlib.patches as mpatches import seaborn as sns import matplotlib.pyplot as plt fig, ax = plt.subplots(1,1) # 绘制散点时清空label,避免自动生成多余图例 sns.scatterplot(data=df_white, x='EngCorr_Player', y='EngCorr_Opponent', hue='Elo_Opponent', ax=ax, marker='D', label='') sns.scatterplot(data=df_black, x='EngCorr_Player', y='EngCorr_Opponent', hue='Elo_Opponent', ax=ax, marker='X', s=140, label='') # 创建对应两组标记的代理元素 white_patch = mpatches.Patch(marker='D', color=ax.collections[0].get_facecolor()[0], label='White', linestyle='', markersize=8) black_patch = mpatches.Patch(marker='X', color=ax.collections[1].get_facecolor()[0], label='Black', linestyle='', markersize=10) # 添加自定义图例 ax.legend(handles=[white_patch, black_patch]) plt.show()
方法2:提取现有散点的Artist
Seaborn绘制的散点会存在ax.collections中,直接提取前两个集合(对应两组散点)来生成图例:
import seaborn as sns import matplotlib.pyplot as plt fig, ax = plt.subplots(1,1) sns.scatterplot(data=df_white, x='EngCorr_Player', y='EngCorr_Opponent', hue='Elo_Opponent', ax=ax, marker='D') sns.scatterplot(data=df_black, x='EngCorr_Player', y='EngCorr_Opponent', hue='Elo_Opponent', ax=ax, marker='X', s=140) # 清除自动生成的冗余图例 ax.get_legend().remove() # 提取两组散点的Artist并设置标签 handles = [ax.collections[0], ax.collections[1]] labels = ['White', 'Black'] ax.legend(handles=handles, labels=labels) plt.show()
补充说明
- 方法1适合需要自定义标记颜色、大小的场景,自由度更高;
- 方法2更简洁,直接复用现有绘图元素,适合无需额外调整样式的情况;
- 如果不需要
hue的颜色映射,也可以直接删除hue参数,此时自动图例只会显示两组标记的标签,但要保留颜色区分的话,必须用上述方法手动处理图例。
内容的提问来源于stack exchange,提问作者JoMo_DS
相关产品推荐
相关产品推荐

