如何用Matplotlib/Seaborn创建分组子图绘制乳腺癌特征直方图
乳腺癌数据集特征直方图分组绘制实现
需求说明
使用Python分析乳腺癌分类数据集时,需要为每个特征绘制分类直方图,将所有直方图按特征类型分为三个组别,预期效果如下:
当前初始代码如下:
from sklearn.datasets import load_breast_cancer # 加载示例数据 import pandas as pd import seaborn as sns import matplotlib.pyplot as plt data = load_breast_cancer() # 将特征数据转为DataFrame格式 df = pd.DataFrame(data.data, columns = data.feature_names) # 加入分类标签列 df["target"] = data.target # 初始绘图逻辑 plotnumber = 1 fig = plt.figure(figsize=(20, 20)) for column in df.drop('target', axis=1): if plotnumber <= 30: plt.subplot(5, 6, plotnumber) sns.distplot(df[df['target'] == 0][column], label = 'malignant') sns.distplot(df[df['target'] == 1][column], label = 'benign') plt.legend() plt.title(column) plotnumber += 1 fig.tight_layout()
运行初始代码得到的无分组效果如下:
需要调整排布规则:将所有子图划分为mean、error、worst三个分组,每个分组包含10个对应特征,按5行2列的网格排布。
实现方案
核心逻辑是先创建1行3列的顶层分组容器,每个容器对应一个特征组,再在全局5行6列的子图网格中为每个组分配固定的2列宽度,同时为每个分组添加总标题。
调整后可直接运行的代码
from sklearn.datasets import load_breast_cancer import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # 加载并整理数据 data = load_breast_cancer() df = pd.DataFrame(data.data, columns=data.feature_names) df["target"] = data.target # 按列名前缀自动拆分三组特征 feature_groups = { "mean": [col for col in df.columns if "mean" in col], "error": [col for col in df.columns if "error" in col], "worst": [col for col in df.columns if "worst" in col] } # 创建画布设置合适尺寸 fig = plt.figure(figsize=(18, 22)) # 遍历三个分组生成对应子图 for group_idx, (group_name, features) in enumerate(feature_groups.items(), 1): # 创建顶层分组占位轴,仅用于显示分组标题 group_ax = fig.add_subplot(1, 3, group_idx) group_ax.set_axis_off() group_ax.set_title(f"{group_name} group", fontsize=16, y=0.98, weight="bold") # 遍历当前组10个特征,在对应列位置绘制子图 for plot_idx, col in enumerate(features, 1): # 全局网格位置计算:每个组占2列,共10个5行2列的子图位置 ax = fig.add_subplot(5, 6, (group_idx-1)*10 + plot_idx) # 绘制两类样本分布,高版本seaborn使用histplot替代已废弃的distplot sns.histplot(df[df["target"]==0][col], label="malignant", kde=True, stat="density", alpha=0.5) sns.histplot(df[df["target"]==1][col], label="benign", kde=True, stat="density", alpha=0.5) ax.set_title(col, fontsize=10) ax.legend(fontsize=8) # 自动调整间距避免文字重叠 fig.tight_layout() plt.show()
代码说明
- 按列名前缀自动筛选分组特征,无需手动枚举30个特征名,避免错漏
- 顶层1行3列的占位轴不显示坐标轴,仅作为分组标题的载体
- 子图位置按全局5行6列网格计算,三个组分别占用左、中、右各2列,刚好匹配每组5行2列的排布要求
- 适配高版本seaborn语法,保留原代码直方图+核密度曲线的展示效果,低版本环境可直接换回原
sns.distplot语法。
内容的提问来源于stack exchange,提问作者DukeAdl
相关产品推荐
相关产品推荐

