如何在循环绘制受试者临床数据图时仅添加基线标记?
临床随访数据可视化问题解决:基线标记与叠加新数据
我看你现在遇到两个核心问题:一是没法只给基线(Visit 2 - Baseline)的bcva值加星形标记,之前的代码会显示所有点;二是想知道怎么在循环绘制每个受试者曲线时,叠加新的数据类型。咱们一个个来解决。
一、只添加基线数据的星形标记
你之前的代码错误在于没有筛选出仅基线的行,直接用了整个受试者的数据集去画标记,所以所有点都变成星形了。正确的做法是先从每个受试者的数据里提取基线记录,再单独绘制这些点:
import matplotlib.pyplot as plt import seaborn as sns for subject, sub_df in new_od_df.groupby(by='subject'): # 绘制对侧眼和治疗眼的随访曲线(原有代码保留) plt.plot(sub_df['visit_date'], sub_df['bcva_OS'], marker='^', label='OS (fellow)', color=sns.xkcd_rgb['pale red']) plt.plot(sub_df['visit_date'], sub_df['bcva_OD'], marker='o', label='OD (treated)', color=sns.xkcd_rgb['denim blue']) # 1. 筛选当前受试者的基线数据 baseline_df = sub_df[sub_df['visit_label'] == 'Visit 2 - Baseline'] # 2. 绘制基线的星形标记(用scatter更适合单独标记点,也可以用plot) if not baseline_df.empty: # 避免没有基线记录的情况报错 plt.scatter(baseline_df['visit_date'], baseline_df['bcva_OS'], marker='*', s=100, color=sns.xkcd_rgb['light pink'], label='BL (fellow)') plt.scatter(baseline_df['visit_date'], baseline_df['bcva_OD'], marker='*', s=100, color=sns.xkcd_rgb['baby blue'], label='BL (treated)') # 图例和显示设置 plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0) plt.title(f"Subject {subject} BCVA Follow-up") # 可以加个标题区分不同受试者 plt.show()
关键说明:
- 先通过
sub_df[sub_df['visit_label'] == 'Visit 2 - Baseline']筛选出基线行,确保只处理这一条记录 - 用
plt.scatter()专门绘制单个标记点,比plot_date更直观,s=100控制标记大小 - 加了
if not baseline_df.empty的判断,防止某些受试者没有基线记录时抛出错误
二、循环中叠加新数据类型
如果要在每个受试者的图里叠加其他数据(比如示例里的refract_OD、refract_OS),只需要在循环里新增对应的绘图语句即可。比如要添加屈光数据的曲线,做法如下:
for subject, sub_df in new_od_df.groupby(by='subject'): # 原有BCVA曲线绘制 plt.plot(sub_df['visit_date'], sub_df['bcva_OS'], marker='^', label='OS (fellow)', color=sns.xkcd_rgb['pale red']) plt.plot(sub_df['visit_date'], sub_df['bcva_OD'], marker='o', label='OD (treated)', color=sns.xkcd_rgb['denim blue']) # 基线标记(同上) baseline_df = sub_df[sub_df['visit_label'] == 'Visit 2 - Baseline'] if not baseline_df.empty: plt.scatter(baseline_df['visit_date'], baseline_df['bcva_OS'], marker='*', s=100, color=sns.xkcd_rgb['light pink'], label='BL (fellow)') plt.scatter(baseline_df['visit_date'], baseline_df['bcva_OD'], marker='*', s=100, color=sns.xkcd_rgb['baby blue'], label='BL (treated)') # 叠加屈光数据曲线(新数据类型) plt.plot(sub_df['visit_date'], sub_df['refract_OD'], marker='s', linestyle='--', label='Refract OD', color=sns.xkcd_rgb['orange']) plt.plot(sub_df['visit_date'], sub_df['refract_OS'], marker='d', linestyle='--', label='Refract OS', color=sns.xkcd_rgb['green']) # 调整图例和显示 plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0) plt.title(f"Subject {subject} Follow-up: BCVA + Refraction") plt.ylabel("Value") # 可以根据数据类型调整ylabel plt.show()
扩展技巧:
- 如果新数据是不同的指标(比如数值范围和BCVA差异大),可以用双Y轴:
fig, ax1 = plt.subplots() # 绘制BCVA到ax1 ax1.plot(sub_df['visit_date'], sub_df['bcva_OS'], marker='^', label='OS (fellow)', color=sns.xkcd_rgb['pale red']) ax1.set_ylabel('BCVA') # 创建ax2作为双Y轴 ax2 = ax1.twinx() ax2.plot(sub_df['visit_date'], sub_df['refract_OD'], marker='s', linestyle='--', label='Refract OD', color=sns.xkcd_rgb['orange']) ax2.set_ylabel('Refraction') # 合并图例 lines1, labels1 = ax1.get_legend_handles_labels() lines2, labels2 = ax2.get_legend_handles_labels() ax1.legend(lines1 + lines2, labels1 + labels2, bbox_to_anchor=(1.05, 1), loc=2) - 如果新数据需要单独的标记或样式,直接在循环里新增对应的
plot或scatter语句即可,只要确保每个绘图语句使用正确的列名和样式参数。
内容的提问来源于stack exchange,提问作者gadkins
相关产品推荐
相关产品推荐

