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

第二幅(过滤后)图

代码示例
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列表生成图例,而非当前数据实际存在的类别。
以下两种方法可解决:
清理category的无用类别
修改转换category的代码,移除未使用的类别:filtered_cells['g'] = filtered_cells['t'].astype('category').cat.remove_unused_categories()这样category仅保留过滤后数据中存在的类别,Seaborn会自动生成匹配的图例。
手动筛选图例条目
若不想修改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
相关产品推荐
相关产品推荐

