如何用Seaborn在长格式DataFrame中生成多密度图或叠加密度图?
解决方案:生成叠加图或多图网格
针对你当前只能单独生成图像的问题,提供两种高效实现方案:
方案1:单张叠加KDE图(所有类别同图对比)
先统一预处理数据,再用Seaborn的displot直接生成叠加图,无需循环:
import seaborn as sns import matplotlib.pyplot as plt import pandas as pd # 第一步:统一计算每个图像中各类别的出现次数(替代原循环分组逻辑) image_counts_df = merged_df.groupby(['image', 'class_name']).size().reset_index(name='per_image_count') # 生成叠加KDE图 sns.displot( data=image_counts_df, x='per_image_count', hue='class_name', # 按类别区分颜色 kind='kde', multiple='stack', # 可选参数:'layer'分层显示、'fill'填充区域 palette='tab10' ) plt.title('Top5类别单图出现次数的KDE分布') plt.xlabel('单图中类别出现次数') plt.show()
方案2:多图网格(每个类别独立子图)
提供两种实现方式,按需选择:
方式A:Matplotlib手动控制布局
适合需要精细调整子图样式的场景:
# 获取Top5类别列表 top_classes = top_5_class_counts.index.tolist() n_classes = len(top_classes) # 创建2行3列的子图网格(适配5个类别) fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(15, 10)) axes = axes.flatten() # 转为一维数组方便循环 # 循环绘制每个类别的KDE图 for idx, class_name in enumerate(top_classes): class_data = image_counts_df[image_counts_df['class_name'] == class_name] sns.kdeplot(data=class_data, x='per_image_count', ax=axes[idx], fill=True) axes[idx].set_title(f'{class_name} 出现次数分布') axes[idx].set_xlabel('单图中出现次数') # 隐藏多余的空图(2行3列共6个位置,第6个为空) for i in range(n_classes, len(axes)): axes[i].set_visible(False) plt.tight_layout() plt.show()
方式B:Seaborn FacetGrid快速生成
代码更简洁,自动处理布局:
g = sns.FacetGrid( data=image_counts_df, col='class_name', col_wrap=3, # 每行最多显示3个图 height=4, aspect=1.2 ) g.map(sns.kdeplot, 'per_image_count', fill=True) g.set_titles(col_template='{col_name} 分布') g.set_xlabels('单图中类别出现次数') plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者tucomax
相关产品推荐
相关产品推荐

