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

如何在sns.heatmap()生成的试次-时间生理响应图中标记反应时间点

在Seaborn热力图每行添加反应时间标记点的实现方案

当然可行!你只需要在绘制完热力图后,借助Matplotlib的散点函数在对应位置标记反应时间点即可。下面是针对你现有代码的修改方案:

关键思路

Seaborn的heatmap本质是基于Matplotlib绘制的,每个试次(行)的单元格在y轴上占据的区间是[trial_idx, trial_idx+1],中心位置为trial_idx + 0.5;同理,每个时间采样点(列)的单元格在x轴上的中心位置是sample_value + 0.5。我们只需要获取每个试次对应的反应时间采样点,然后在这些中心位置绘制散点即可。

修改后的完整代码

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import os
from jupyterthemes import jtplot

def plot_evoked_response_map(ordered_samples_df, fig_name, fig_path=fig_path, trial_end_sample_idx=1500):
    jtplot.style('grade3', context='poster', fscale=1.4, spines=False, gridlines='--')
    ordered_samples_df = ordered_samples_df.loc[ordered_samples_df.trial_sample < trial_end_sample_idx]
    # 确保DataFrame包含反应时间采样点列,这里假设列名为reaction_time_sample
    samples_sparse = ordered_samples_df[['trial_sample', 'trial_epoch', 'z_pupil_diameter', 'reaction_time_sample']]
    samples_sparse['reset_trial_epoch_idx'] = np.repeat(np.arange(0,n_trials), trial_end_sample_idx)
    
    # 提取每个试次对应的反应时间采样点(每个试次取唯一的RT值)
    rt_per_trial = samples_sparse.groupby('reset_trial_epoch_idx')['reaction_time_sample'].first()
    
    # 生成透视表
    samples_pivot = samples_sparse.pivot(index='reset_trial_epoch_idx', columns='trial_sample', values='z_pupil_diameter')
    
    plt.figure(1)
    fig, ax = plt.subplots(figsize=(10,10))
    # 绘制热力图
    sns.heatmap(samples_pivot, fmt="g", cmap='viridis', cbar_kws={'label': 'pupil diameter'}, robust=True, vmin=0, vmax=2)
    
    # 遍历每个试次,添加反应时间标记点
    for trial_idx, rt_sample in rt_per_trial.items():
        # 跳过超出当前时间范围的RT点
        if rt_sample < trial_end_sample_idx:
            # x坐标:采样点+0.5(单元格中心);y坐标:试次索引+0.5(行中心)
            # 红色圆点,尺寸50,zorder确保点在热力图上方
            ax.scatter(rt_sample + 0.5, trial_idx + 0.5, color='red', s=50, marker='o', zorder=10)
    
    plt.title(fig_name)
    plt.ylabel('trial')
    plt.savefig(os.path.join(fig_path, fig_name + '.png'))
    return fig_name

_= plot_evoked_response_map(rt_ordered_samples_df, fig_name='RT_ordered_evoked_responses')

注意事项

  1. 确保数据包含反应时间采样点:你的ordered_samples_df需要有一列存储每个试次对应的反应时间采样点(比如命名为reaction_time_sample),如果列名不同请自行修改代码中的对应部分。
  2. 坐标偏移的必要性:因为热力图的单元格是连续的区间,直接使用试次索引和采样点数值会导致点落在单元格边缘,+0.5能让点精准落在每行的中心位置。
  3. zorder参数:设置zorder=10可以保证标记点绘制在热力图的上层,不会被热力图的颜色块覆盖。
  4. 过滤超出范围的RT:如果某个试次的反应时间采样点超过了trial_end_sample_idx,跳过该点避免绘制到热力图之外。

内容的提问来源于stack exchange,提问作者randomWalk112358

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:40:19