Seaborn histplot图例标签重复问题:如何去除重复标签?
Seaborn Histplot 图例标签重复问题解决
问题场景
使用以下代码绘制两个数据集的组合直方图时,图例出现重复标签:
_,bins = np.histogram([150, 600], bins=30) alpha = 0.4 fig, ax = plt.subplots(1,1) sns.histplot(df1['Tm/K Pred.'], bins=bins, alpha=alpha, label='df1') sns.histplot(vispilsExp298Tm_bert['Tm/K Pred.'], bins=bins, alpha=alpha, label='df2') plt.yscale('log') plt.legend() plt.show()
执行ax.get_legend_handles_labels()检查,结果显示每个标签对应两个BarContainer:
([<BarContainer object of 1 artists>, <BarContainer object of 30 artists>, <BarContainer object of 1 artists>, <BarContainer object of 30 artists>], ['df1', 'df1', 'df2', 'df2'])
问题原因
Seaborn的histplot在指定自定义bins时,会自动生成一个用于图例的虚拟Bar元素,加上实际绘制直方图的Bar容器,导致每个数据集对应两个图例条目。
解决方案
方法1:手动去重图例条目
提取图例的handles和labels后,通过字典去重(保留每个标签的第一个出现):
_,bins = np.histogram([150, 600], bins=30) alpha = 0.4 fig, ax = plt.subplots(1,1) sns.histplot(df1['Tm/K Pred.'], bins=bins, alpha=alpha, label='df1') sns.histplot(vispilsExp298Tm_bert['Tm/K Pred.'], bins=bins, alpha=alpha, label='df2') plt.yscale('log') # 提取并去重图例 handles, labels = ax.get_legend_handles_labels() unique_entries = dict(zip(labels, handles)) ax.legend(unique_entries.values(), unique_entries.keys()) plt.show()
方法2:绘制时不指定label,手动关联容器与标签
绘制直方图时不设置label,直接从轴容器中取前两个元素(对应两个数据集)来创建图例:
_,bins = np.histogram([150, 600], bins=30) alpha = 0.4 fig, ax = plt.subplots(1,1) # 绘制时不指定label sns.histplot(df1['Tm/K Pred.'], bins=bins, alpha=alpha) sns.histplot(vispilsExp298Tm_bert['Tm/K Pred.'], bins=bins, alpha=alpha) plt.yscale('log') # 取前两个BarContainer作为图例条目 handles = ax.containers[:2] labels = ['df1', 'df2'] ax.legend(handles, labels) plt.show()
方法3:禁用自动图例,手动创建图例元素
通过legend=False关闭histplot的自动图例生成,然后用Matplotlib的Patch手动创建图例条目:
_,bins = np.histogram([150, 600], bins=30) alpha = 0.4 fig, ax = plt.subplots(1,1) # 禁用自动图例 sns.histplot(df1['Tm/K Pred.'], bins=bins, alpha=alpha, legend=False) sns.histplot(vispilsExp298Tm_bert['Tm/K Pred.'], bins=bins, alpha=alpha, legend=False) plt.yscale('log') # 手动创建图例色块 from matplotlib.patches import Patch legend_elements = [ Patch(facecolor=sns.color_palette()[0], alpha=alpha, label='df1'), Patch(facecolor=sns.color_palette()[1], alpha=alpha, label='df2') ] ax.legend(handles=legend_elements) plt.show()
内容的提问来源于stack exchange,提问作者zzrrhhh
相关产品推荐
相关产品推荐

