You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python seaborn按分组绘制1行3列回归子图并导出PDF

数据集与需求说明
  • 数据集包含3组调研数据(exp1、exp2、exp3)
  • 每组调研包含2个试次(trial1、trial2)
  • 每个试次采集3项特征(feature1、feature2、feature3)及对应目标变量值
  • 需求为按[调研,试次]分组,每组生成1行3列的子图画布放置3个特征的回归拟合图,所有分组结果统一保存到单个PDF文件。
原代码问题点
  • 未提前创建子图网格,每次绘制特征图都生成独立画布,无法实现同组图排布在同一页
  • 存在变量拼写错误:trialtrial为笔误,取目标变量列时data[target]未加引号,会触发运行报错
  • PDF保存、画布关闭逻辑放在特征循环内部,导致单张特征图单独占PDF页面
修改后完整代码
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.backends.backend_pdf import PdfPages
from scipy import stats

data = {'Trial': ['trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial1', 'trial2', 'trial2', 'trial2', 'trial2', 'trial2', 'trial2', 'trial2', 'trial2', 'trial2', 'trial2', 'trial2', 'trial2', 'trial2', 'trial2', 'trial2', 'trial2', 'trial2', 'trial2', 'trial2', 'trial2', 'trial2'],
        'Survey': ['exp1', 'exp1', 'exp1', 'exp1', 'exp1', 'exp1', 'exp1', 'exp1', 'exp1', 'exp1', 'exp2', 'exp2', 'exp2', 'exp2', 'exp2', 'exp2', 'exp2', 'exp2', 'exp2', 'exp2', 'exp3', 'exp3', 'exp3', 'exp3', 'exp3', 'exp3', 'exp3', 'exp3', 'exp3', 'exp3', 'exp1', 'exp1', 'exp1', 'exp1', 'exp1', 'exp1', 'exp2', 'exp2', 'exp2', 'exp2', 'exp2', 'exp2', 'exp2', 'exp3', 'exp3', 'exp3', 'exp3', 'exp3', 'exp3', 'exp3', 'exp3'],
        'feature1': [0.76, 0.72, 0.76, 0.73, 0.69, 0.76, 0.74, 0.71, 0.67, 0.74, 0.74, 0.68, 0.73, 0.67, 0.63, 0.73, 0.72, 0.7, 0.59, 0.7, 0.63, 0.52, 0.57, 0.49, 0.46, 0.59, 0.59, 0.55, 0.42, 0.55, 0.69, 0.75, 0.72, 0.8, 0.79, 0.69, 0.65, 0.73, 0.68, 0.8, 0.79, 0.79, 0.76, 0.52, 0.6, 0.53, 0.71, 0.71, 0.71, 0.64, 0.53],
        'feature2': [0.59, 0.55, 0.6, 0.56, 0.51, 0.6, 0.54, 0.51, 0.48, 0.57, 0.65, 0.57, 0.63, 0.56, 0.51, 0.64, 0.6, 0.56, 0.46, 0.6, 0.48, 0.36, 0.4, 0.32, 0.3, 0.43, 0.41, 0.36, 0.26, 0.38, 0.49, 0.57, 0.53, 0.65, 0.64, 0.5, 0.52, 0.61, 0.55, 0.75, 0.73, 0.73, 0.65, 0.34, 0.43, 0.35, 0.58, 0.58, 0.57, 0.48, 0.34],
        'feature3': [0.32, 0.28, 0.29, 0.28, 0.25, 0.3, 0.29, 0.28, 0.24, 0.28, 0.28, 0.23, 0.24, 0.22, 0.2, 0.25, 0.25, 0.24, 0.19, 0.23, 0.22, 0.17, 0.18, 0.16, 0.16, 0.19, 0.2, 0.19, 0.15, 0.18, 0.27, 0.31, 0.27, 0.35, 0.35, 0.25, 0.23, 0.26, 0.23, 0.32, 0.3, 0.31, 0.28, 0.2, 0.21, 0.19, 0.25, 0.24, 0.24, 0.21, 0.2],
        'target': [91, 88, 87, 87, 86, 89, 85, 86, 85, 87, 91, 88, 87, 87, 86, 89, 85, 86, 85, 87, 91, 88, 87, 87, 86, 89, 85, 86, 85, 87, 85, 88, 87, 93, 94, 86, 85, 88, 87, 93, 94, 91, 90, 85, 88, 87, 93, 94, 91, 90, 83]}

df = pd.DataFrame(data)
feature_list = ['feature1', 'feature2', 'feature3']

with PdfPages('regplot_example.pdf') as pdf:
    for (survey, trial), group_data in df.groupby(['Survey','Trial']):
        regResult_perSurvey = dict()
        print(f'processing: {survey} {trial}')
        # 提前创建1行3列的子图画布,设置合适尺寸
        fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(15, 4.5))
        
        for idx, feature in enumerate(feature_list):
            ax = axes[idx]
            # 拟合回归模型,修正原代码target未加引号的问题
            slope, intercept, r_value, p_value, std_err = stats.linregress(group_data[feature], group_data['target'])
            # 修正原代码trialtrial笔误
            regResult_perSurvey[f'{survey}:{trial}:{feature}'] = [
                survey, trial, feature, 
                f'{r_value:.2f}', f'{p_value:.2e}', f'{std_err:.2f}'
            ]
            
            # 在指定子图上绘制回归图
            sns.regplot(
                x=feature, y='target', data=group_data, ax=ax,
                scatter_kws={'color':'black', 'alpha':0.7},
                line_kws={
                    'color':'red',
                    'label':f"y={slope:.1f}x+{intercept:.1f}\n$R^2: {r_value**2:.2f}$"
                }
            )
            ax.set_title(f'{survey} {trial} {feature}')
            ax.legend()
        
        # 同组3张图全部绘制完成后统一调整布局、保存
        plt.tight_layout()
        # 如需保存单组整图可放开下一行注释
        # plt.savefig(f'regplot_{survey}_{trial}.png', dpi=300, bbox_inches='tight')
        pdf.savefig(fig, bbox_inches='tight')
        plt.close(fig)

# 如需导出回归统计结果可放开下部分注释
# res_df = pd.DataFrame(regResult_perSurvey, index=['Survey','Trial','Feature','r','p','std_err']).T
# res_df.to_csv('regression_results.csv', index=False)
代码说明
  • 每个[调研,试次]分组对应PDF内1页,页面横向排列3个特征的回归子图
  • 保留原有黑色散点、红色拟合线、回归公式与拟合优度标注样式,散点增加透明度避免重叠遮挡
  • 修复原代码所有语法笔误,回归统计结果的存储逻辑保留,可直接导出为CSV汇总
  • 画布尺寸、样式参数可根据实际需求调整figsize、scatter_kws、line_kws内的配置

内容的提问来源于stack exchange,提问作者Amilovsky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 23:10:00