如何在Python循环中用Seaborn/Matplotlib生成数据集列的动态子图?
问题解决:加州住房数据集多列子图批量绘制
原代码存在的问题
- 未指定绘图的目标子图轴,导致所有图形叠加或单独弹出窗口,无法形成预期的4×3网格布局
- 缺少
statsmodels库的导入,调用sm.qqplot会触发报错 - 未设置子图标题,无法区分不同特征对应的图形类型
- 代码结构固化,新增子图类型时需要大幅修改循环逻辑,扩展性差
修正后的代码
from sklearn.datasets import fetch_california_housing import pandas as pd import seaborn as sns import matplotlib.pyplot as plt import statsmodels.api as sm # 补充缺失的导入 # 加载数据集 california_housing = fetch_california_housing(as_frame=True) features_of_interest = ["AveRooms", "AveBedrms", "AveOccup", "Population"] df = california_housing.frame target = california_housing.target # 定义子图配置:每个配置包含绘图函数、标题模板,方便后续动态扩展 plot_configs = [ {"func": sns.scatterplot, "title": "{} vs 房价散点图"}, {"func": sns.histplot, "title": "{} vs 房价直方图"}, {"func": lambda x, ax: sm.qqplot(x, line='45', ax=ax), "title": "{} QQ图"} ] # 创建子图网格:行数=特征数,列数=子图类型数 n_features = len(features_of_interest) n_plots = len(plot_configs) fig, axes = plt.subplots(n_features, n_plots, figsize=(15, 12)) # 遍历特征和子图配置,批量绘制 for row_idx, feature in enumerate(features_of_interest): for col_idx, config in enumerate(plot_configs): ax = axes[row_idx, col_idx] # 根据配置绘图:散点/直方图需要x和y,QQ图只需要x if config["title"].startswith("QQ"): config["func"](df[feature], ax=ax) else: config["func"](x=df[feature], y=target, ax=ax) # 设置子图标题 ax.set_title(config["title"].format(feature)) # 自动调整子图间距,避免元素重叠 plt.tight_layout() plt.show()
关键优化点说明
- 动态扩展设计:通过
plot_configs列表封装子图逻辑,新增子图类型时只需在列表中添加新的字典条目(比如添加箱线图),无需修改循环核心代码 - 轴指定逻辑:通过
axes[row_idx, col_idx]精准指定每个子图的绘制位置,保证网格布局正确 - 兼容性处理:针对QQ图的参数特殊性做了分支处理,确保不同类型的绘图函数都能正常运行
- 可读性提升:为每个子图添加包含特征名和图类型的标题,同时通过
figsize和tight_layout()优化可视化效果
内容的提问来源于stack exchange,提问作者Bad Coder
相关产品推荐
相关产品推荐

