You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 16:45:04