ggplot2实现带偏移连线的横向堆叠直方图求助
解决方案:添加分组间连线的横向堆叠直方图
这类图表是卒中临床试验中展示预后(如mRS)分布差异的常用形式,核心是先定位每个mRS分段在堆叠图中的位置,再绘制跨组连线突出偏移。
核心思路
- 先计算每个mRS分段在两组堆叠图中的起始、结束、中心位置(基于百分比的累积和);
- 分别绘制两组的横向堆叠直方图;
- 针对每个mRS等级,连接两组对应分段的位置(中心/边缘均可)。
具体实现(Python + Matplotlib)
1. 数据预处理
将百分比转为数值,并计算堆叠分段的位置参数:
import matplotlib.pyplot as plt import pandas as pd # 加载并清洗数据 data = pd.DataFrame({ 'mRS': [0, 1, 2, 3, 4, 5, 6], 'Drug1': [0.10, 0.12, 0.22, 0.09, 0.15, 0.12, 0.20], # 去掉%转成小数 'Drug2': [0.08, 0.10, 0.18, 0.14, 0.16, 0.12, 0.22] }) # 计算每个mRS分段的起始、结束、中心位置 data['Drug1_cum'] = data['Drug1'].cumsum() data['Drug2_cum'] = data['Drug2'].cumsum() data['Drug1_start'] = data['Drug1_cum'] - data['Drug1'] data['Drug2_start'] = data['Drug2_cum'] - data['Drug2'] data['Drug1_center'] = (data['Drug1_start'] + data['Drug1_cum']) / 2 data['Drug2_center'] = (data['Drug2_start'] + data['Drug2_cum']) / 2
2. 绘制堆叠图与跨组连线
fig, ax = plt.subplots(figsize=(10, 4)) colors = plt.cm.Set3(range(len(data))) # 同一mRS用同色区分,便于对比 # 绘制Drug1的横向堆叠条形 for idx in range(len(data)): ax.barh( y=0, width=data['Drug1'][idx], left=data['Drug1_start'][idx], color=colors[idx], label=f'mRS={data["mRS"][idx]}' ) # 绘制Drug2的横向堆叠条形 for idx in range(len(data)): ax.barh( y=1, width=data['Drug2'][idx], left=data['Drug2_start'][idx], color=colors[idx] ) # 绘制跨组连线(连接对应mRS分段的中心) for idx in range(len(data)): ax.plot( [data['Drug1_center'][idx], data['Drug2_center'][idx]], [0, 1], color='gray', linestyle='--', linewidth=1 ) # 图表美化 ax.set_yticks([0, 1]) ax.set_yticklabels(['Drug1', 'Drug2']) ax.set_xlabel('Percentage') ax.set_xlim(0, 1) ax.xaxis.set_major_formatter(plt.FuncFormatter(lambda x, _: f'{x*100:.0f}%')) ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left') plt.tight_layout() plt.show()
3. 自定义调整
- 若想连接分段边缘而非中心,将
plot的x值替换为Drug1_cum/Drug2_cum(结束边缘)或Drug1_start/Drug2_start(起始边缘)即可; - 调整y轴位置(如把Drug2的y设为0.5)可缩小两组间距,让连线更紧凑;
- 更换配色方案(如临床常用的高对比度配色)可提升图表专业性。
内容的提问来源于stack exchange,提问作者user1139139
相关产品推荐
相关产品推荐

