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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 07:30:23