如何在Seaborn散点图中为同Record ID的两时间点数据添加匹配颜色的箭头
实现方案
你可以在原有散点图绘制逻辑后,按Record_ID分组提取每个样本两个时间点的坐标,调用matplotlib的annotate接口绘制箭头即可,箭头颜色直接复用你预先定义的colors字典,保证和对应Improvement分组颜色完全匹配。
完整可运行代码
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt dataT = [{'Record_ID': 10, 'Timepoint': 1, 'Value1':30,'Value2':15, "Improvement" : 1 }, {'Record_ID': 10, 'Timepoint': 2, 'Value1':30,'Value2':30, "Improvement" : 1 }, {'Record_ID': 12, 'Timepoint': 1, 'Value1':40,'Value2':10 , "Improvement" : 2 }, {'Record_ID': 12, 'Timepoint': 2, 'Value1':30,'Value2':30, "Improvement" : 2 }, {'Record_ID': 13, 'Timepoint': 1, 'Value1':70,'Value2':30 , "Improvement" : 3 }, {'Record_ID': 13, 'Timepoint': 2, 'Value1':25,'Value2':40 , "Improvement" : 3}, {'Record_ID': 11, 'Timepoint': 1, 'Value1':60,'Value2':50 , "Improvement" : 1 }, {'Record_ID': 11, 'Timepoint': 2, 'Value1':35,'Value2':45, "Improvement" : 1 }] data = pd.DataFrame(dataT) sns.set_style("darkgrid") colors = {1: "green", 2:"red", 3:"orange"} # 若无需使用expVarPC1可注释下行代码 # expVarPC1 = my_pcoa.eigvals.PC1/my_pcoa.eigvals.sum() fig, ax = plt.subplots(figsize=(24, 16)) # 绘制原有散点图 sns.scatterplot(x =data['Value1'], y= data['Value2'],style=data["Timepoint"], hue=data["Improvement"], s=200, palette=colors) # ----------------------新增箭头绘制逻辑开始---------------------- for record_id, group_df in data.groupby('Record_ID'): # 提取当前ID两个时间点的坐标和分组属性 t1_point = group_df[group_df['Timepoint'] == 1].iloc[0] t2_point = group_df[group_df['Timepoint'] == 2].iloc[0] # 取对应Improvement分组的颜色 line_color = colors[t1_point['Improvement']] # 绘制从T1指向T2的箭头 ax.annotate( '', xy=(t2_point['Value1'], t2_point['Value2']), # 箭头终点(T2坐标) xytext=(t1_point['Value1'], t1_point['Value2']), # 箭头起点(T1坐标) arrowprops=dict( facecolor=line_color, edgecolor=line_color, shrinkA=10, # 箭头起点和散点之间留空,避免覆盖点 shrinkB=10, # 箭头终点和散点之间留空 headwidth=8, headlength=10, width=2 ), zorder=1 # 箭头置于散点下方,避免遮挡散点 ) # ----------------------新增箭头绘制逻辑结束---------------------- plt.legend(title='', title_fontsize=20, fontsize=20, markerscale=2., scatterpoints=1) plt.xlabel("Val1" , fontsize=22) plt.ylabel("Val2 " , fontsize=22) plt.title("samples T1 & T2 " , fontsize='40') plt.show()
参数说明
shrinkA/shrinkB:控制箭头两端和散点的间距,数值越大间距越大,可根据散点大小调整headwidth/headlength/width:分别控制箭头头部宽度、头部长度、箭身宽度,可按需调整尺寸zorder=1:保证箭头层级低于散点,不会遮挡原有散点标记
内容的提问来源于stack exchange,提问作者Hedayat
相关产品推荐
相关产品推荐

