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

如何让Seaborn散点图图例仅显示当前图中存在的类别?

问题描述

我写了一段脚本,先用sns.scatterplot生成散点图,接着过滤数据后生成新的散点图。已经用plt.clf()避免两幅图重叠,但新图的图例还是没从原始图更新——理想状态下第二幅图的图例应该只包含图里实际存在的类别。试过sns.reset_orig()和sns.reset_defaults()都没用,有没有可行的解决办法?

第一幅图

Plot 1

第二幅(过滤后)图

Plot 2

代码示例

ax = sns.scatterplot('x', 'y', data=cell_localization_df, hue='t',linewidth=0, palette="deep")
ax.legend(loc='upper left',ncol=4, title="Cell #",bbox_to_anchor=(1, 1),fontsize='small',title_fontsize='medium')

filtered_cells = pd.DataFrame()  
for bb in cell_number_no_dups:
    cell_local_filter = cell_localization_df[cell_localization_df['cell_num'] == bb]
    if len(cell_local_filter) >= min_cell_pixels:
        if len(cell_local_filter) <= max_cell_pixels:
            filtered_cells = pd.concat([filtered_cells, cell_local_filter])
        else:
            pass
    else:
        pass
filtered_cells['g'] = filtered_cells['t'].astype('category') 
plt.clf()
sns.reset_defaults()
sns.reset_orig()
ax2 = sns.scatterplot('x', 'y', data=filtered_cells, hue='g',linewidth=0, palette="deep")
ax2.legend(loc='upper left',ncol=4, title="Cell #",bbox_to_anchor=(1, 1),fontsize='small',title_fontsize='medium')
解决办法

问题核心是:将filtered_cells['g']转为category类型时,默认保留了原始数据的所有类别(包括已过滤掉的),Seaborn会基于完整的category列表生成图例,而非当前数据实际存在的类别。

以下两种方法可解决:

  1. 清理category的无用类别
    修改转换category的代码,移除未使用的类别:

    filtered_cells['g'] = filtered_cells['t'].astype('category').cat.remove_unused_categories()
    

    这样category仅保留过滤后数据中存在的类别,Seaborn会自动生成匹配的图例。

  2. 手动筛选图例条目
    若不想修改category类型,可在生成第二幅图后,手动提取当前图中存在的类别来构建图例:

    ax2 = sns.scatterplot('x', 'y', data=filtered_cells, hue='g',linewidth=0, palette="deep")
    # 获取当前图的图例元素和标签
    handles, labels = ax2.get_legend_handles_labels()
    # 筛选出当前数据存在的类别(跳过第一个默认的hue标题)
    valid_entries = [(h, l) for h, l in zip(handles[1:], labels[1:]) if l in filtered_cells['g'].unique()]
    filtered_handles, filtered_labels = zip(*valid_entries) if valid_entries else ([], [])
    # 重新生成图例
    ax2.legend(handles=filtered_handles, labels=filtered_labels, 
               loc='upper left', ncol=4, title="Cell #", 
               bbox_to_anchor=(1, 1), fontsize='small', title_fontsize='medium')
    

另外,plt.clf()已足够清除画布,sns.reset_defaults()和sns.reset_orig()与图例问题无关,可删除。

内容的提问来源于stack exchange,提问作者lcfields

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 21:47:11