如何在R中使用循环基于dataframe分组绘制多幅生存时序图?
问题描述
我有如下结构的DataFrame,希望使用for循环为每一组Line、Sex、Dose的组合绘制图表,其中x轴为Time,y轴为Survival。例如,需要分别绘制Line 138、剂量1的雌性个体生存随时间变化图,Line 138、剂量1的雄性个体生存随时间变化图等,请问该如何实现?
| Time | Survival | Line | Sex | Dose |
|---|---|---|---|---|
| 28 | 0.95 | 138 | F | 1 |
| 35 | 0.65 | 138 | F | 1 |
| 41 | 0.6 | 138 | F | 1 |
| 42 | 0.15 | 138 | F | 1 |
| 48 | 0.05 | 138 | F | 1 |
| 55 | 0 | 138 | F | 1 |
| 5 | 0.95 | 138 | F | 1 |
| 11 | 0.855 | 138 | F | 1 |
| 28 | 0.95 | 138 | M | 1 |
| 35 | 0.65 | 138 | M | 1 |
| 41 | 0.6 | 138 | M | 1 |
| 42 | 0.15 | 138 | M | 1 |
| 48 | 0.05 | 138 | M | 1 |
| 55 | 0 | 138 | M | 1 |
| 5 | 0.95 | 138 | M | 1 |
| 11 | 0.855 | 138 | M | 1 |
| 28 | 0.95 | 120 | F | 2 |
| 35 | 0.65 | 120 | F | 2 |
| 41 | 0.6 | 120 | F | 2 |
| 42 | 0.15 | 120 | F | 2 |
| 48 | 0.05 | 120 | F | 2 |
| 55 | 0 | 120 | F | 2 |
| 5 | 0.95 | 120 | F | 2 |
| 11 | 0.855 | 120 | F | 2 |
| 28 | 0.95 | 120 | M | 2 |
| 35 | 0.65 | 120 | M | 2 |
| 41 | 0.6 | 120 | M | 2 |
| 42 | 0.15 | 120 | M | 2 |
| 48 | 0.05 | 120 | M | 2 |
| 55 | 0 | 120 | M | 2 |
| 5 | 0.95 | 120 | M | 2 |
| 11 | 0.855 | 120 | M | 2 |
解决方案
方法一:Pandas分组 + Matplotlib 手动循环绘制
这是完全符合要求的for循环实现方式:
import pandas as pd import matplotlib.pyplot as plt # 假设数据已加载到df中,若从文件读取可使用: # df = pd.read_csv("你的数据文件路径.csv") # 按Line、Sex、Dose三个字段分组 grouped = df.groupby(['Line', 'Sex', 'Dose']) # 遍历每个分组 for (line, sex, dose), subset in grouped: # 对Time排序,确保曲线按时间顺序绘制 subset_sorted = subset.sort_values('Time') # 创建独立绘图窗口 plt.figure(figsize=(8, 5)) # 绘制生存曲线,添加标记点增强可读性 plt.plot(subset_sorted['Time'], subset_sorted['Survival'], marker='o', linestyle='-', color='#1f77b4') # 设置图表元素 plt.title(f"Line {line} | {sex} | Dose {dose}") plt.xlabel("Time") plt.ylabel("Survival Rate") plt.grid(True, alpha=0.3) # 显示图表,或替换为savefig保存文件 plt.show() # plt.savefig(f"survival_line{line}_sex{sex}_dose{dose}.png", dpi=300, bbox_inches='tight')
关键说明:
- 分组后遍历每个子数据集,确保每个组合对应独立图表
- 对
Time排序避免数据顺序混乱导致曲线错位 - 可通过修改
marker、linestyle、color参数调整曲线样式 - 若需要批量保存图表,替换
plt.show()为plt.savefig()即可,文件名用分组参数命名方便区分
方法二:Seaborn FacetGrid 自动分面绘制(无需手动循环)
如果不需要严格手动写for循环,Seaborn可以更高效地批量生成所有分组图表,还支持同组对比:
import seaborn as sns import matplotlib.pyplot as plt # 先对全量数据按Time排序 df_sorted = df.sort_values('Time') # 创建分面网格,按Line、Dose分行列,按Sex区分曲线 g = sns.FacetGrid(df_sorted, row='Line', col='Dose', hue='Sex', height=5, aspect=1.2) # 绘制折线图 g.map(sns.lineplot, 'Time', 'Survival', marker='o') # 设置标题和标签 g.set_titles(row_template="Line {row_name}", col_template="Dose {col_name}") g.set_axis_labels("Time", "Survival Rate") g.add_legend(title="Sex") plt.show()
优势:
- 自动按分组生成子图,无需手动循环
- 支持同一子图内对比不同Sex的生存曲线
- 代码更简洁,适合快速可视化所有分组情况
内容的提问来源于stack exchange,提问作者K.W
相关产品推荐
相关产品推荐

