如何将pandas宽格式时间序列数据转长格式后按指标分图绘制
解决方案
1. 数据结构说明&宽表转长表
你的宽格式数据集默认列命名规则为指标名_时间点,主键为患者ID,结构参考如下:
| patient_id | 谷丙转氨酶_Baseline | 谷丙转氨酶_3 Month | 谷丙转氨酶_6 Month | 肌酐_Baseline | ... |
|---|---|---|---|---|---|
| P001 | 23 | 25 | 22 | 78 | ... |
首先通过melt方法将宽表转换为适配分组绘图的长表结构:
import pandas as pd import matplotlib.pyplot as plt # 替换为你自己的DataFrame变量名 df = 你的原始宽格式DataFrame # 宽表转长表 df_long = df.melt( id_vars="patient_id", var_name="col_raw", value_name="test_value" ) # 拆分原始列名得到指标名、时间点,若列命名规则不同可调整split参数 df_long[["test_item", "time_point"]] = df_long["col_raw"].str.split("_", n=1, expand=True) # 给时间点设置排序规则,保证x轴展示顺序符合业务逻辑 df_long["time_point"] = pd.Categorical( df_long["time_point"], categories=["Baseline", "3 Month", "6 Month"], ordered=True )
2. 按指标生成独立图表
遍历所有检验指标,每个指标单独创建画布绘图,完全避免子图数量不匹配的报错:
# 提取所有唯一的检验指标 test_item_list = df_long["test_item"].unique() for item in test_item_list: # 筛选当前指标的全部患者数据 current_data = df_long[df_long["test_item"] == item] # 为当前指标创建独立画布 plt.figure(figsize=(8, 5)) # 按患者ID分组绘制单条曲线 for pid, group in current_data.groupby("patient_id"): plt.plot( group["time_point"], group["test_value"], marker="o", alpha=0.7, label=f"患者{pid}" ) # 图表信息配置 plt.title(f"{item} 各患者时间变化趋势", fontsize=13) plt.xlabel("随访时间", fontsize=11) plt.ylabel("检测值", fontsize=11) # 患者数量较多时可注释掉图例避免遮挡 plt.legend(bbox_to_anchor=(1.02, 1), loc="upper left") plt.tight_layout() # 可选:保存图片到本地 # plt.savefig(f"./{item}_趋势图.png", dpi=300, bbox_inches="tight") plt.show()
3. 原问题原因说明
- 之前所有数据画在同一张图:没有为每个指标单独创建
plt.figure()实例,所有绘图操作都在默认画布上叠加。 - 多子图解包报错:一般是子图行列数乘积小于指标总数,或者解包时变量数量和subplot返回值不匹配,上述单画布遍历方案无需处理子图数量匹配,直接规避这类问题。
内容的提问来源于stack exchange,提问作者John Conor
相关产品推荐
相关产品推荐

