如何在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')
注意事项
- 确保数据包含反应时间采样点:你的
ordered_samples_df需要有一列存储每个试次对应的反应时间采样点(比如命名为reaction_time_sample),如果列名不同请自行修改代码中的对应部分。 - 坐标偏移的必要性:因为热力图的单元格是连续的区间,直接使用试次索引和采样点数值会导致点落在单元格边缘,
+0.5能让点精准落在每行的中心位置。 - zorder参数:设置
zorder=10可以保证标记点绘制在热力图的上层,不会被热力图的颜色块覆盖。 - 过滤超出范围的RT:如果某个试次的反应时间采样点超过了
trial_end_sample_idx,跳过该点避免绘制到热力图之外。
内容的提问来源于stack exchange,提问作者randomWalk112358
相关产品推荐
相关产品推荐

