步骤 25:生成报告
生成可复现的处理报告(科研可复现性最后一步)
1. 目标
把整个预处理流程的关键参数、统计、可视化打包成 HTML 报告。这是科研可复现性的最后一步——审稿人/合作者能通过这份报告完整还原你的处理。
2. 何时使用 / 何时跳过
- 强烈建议使用:任何正式研究、可发表研究
- 可跳过:临时调试、一次性分析
3. 前置条件
- 已执行步骤 24:所有预处理已完成
- 已保存关键中间产物(raw、epochs、ica)
4. 核心代码
Python
import mne
# ====== 创建 Report 对象 ======
# 真实签名: mne.Report(self, info_fname=None, subjects_dir=None,
# subject=None, title=None, cov_fname=None,
# baseline=None, image_format='auto',
# raw_psd=False, projs=False, ...)
# 注意:无 authors / date 参数(这些应写进标题或正文)
report = mne.Report(
title='Subject 01 — EEG Preprocessing Report',
subject='subject-01',
)
# ====== 1) 添加原始/预处理后 raw ======
report.add_raw(
raw=raw,
title='Preprocessed Raw',
psd=True, # 包含 PSD
butterfly=True, # 包含蝴蝶图
scalings=dict(eeg=20e-6),
)
# ====== 2) 添加 ICA(必须传 inst) ======
report.add_ica(
ica=ica,
inst=raw, # 必需参数
title='ICA Decomposition',
picks=range(min(20, ica.n_components_)), # 仅展示前 20 个
)
# ====== 3) 添加 Epochs ======
report.add_epochs(
epochs=epochs,
title='Final Epochs',
psd=True,
)
# ====== 4) 添加 Evoked(注意是 add_evokeds 不是 add_evoked) ======
evoked = epochs.average()
report.add_evokeds(
evokeds=[evoked], # 必须是 list
titles=['Condition A'], # 长度与 evokeds 一致
)
# ====== 5) 添加自定义 HTML / 代码 ======
# 没有 add_text;改用 add_html / add_code
report.add_html(
html='<h2>Methods Summary</h2><p>0.1–40 Hz bandpass, FastICA n_components=0.95</p>',
title='Methods Summary',
)
report.add_code(
code='import mne\nraw = mne.io.read_raw_fif(...)',
title='Preprocessing Script',
language='python',
)
# ====== 6) 添加自定义图片 ======
from PIL import Image
# report.add_image(
# image=Image.open('extra_plot.png'),
# title='Custom Plot',
# )
# ====== 7) 保存 ======
# 真实签名: report.save(fname=None, open_browser=True, overwrite=False, sort_content=False)
report.save(
fname='subject-01_report.html',
overwrite=True,
)
5. 报告应包含的内容清单
| 内容 | API 方法 | 必选? |
|---|---|---|
| 原始 / 预处理后 raw | add_raw |
✅ |
| 通道 PSD | add_raw(psd=True) |
✅ |
| ICA 成分图 | add_ica |
✅ |
| Epochs 概览 | add_epochs |
✅ |
| 平均 ERP | add_evokeds |
✅ |
| 处理参数说明 | add_html / add_code |
✅ |
| 自定义分析图 | add_image / add_figure |
可选 |
| 时间-频率图 | 自定义 HTML | 可选 |
| 拓扑图 | 自定义 HTML | 可选 |
6. Report 真实签名(避免常见错误)
Python
mne.Report(
info_fname=None,
subjects_dir=None,
subject=None,
title=None,
cov_fname=None,
baseline=None,
image_format='auto',
raw_psd=False,
projs=False,
*,
img_max_width=850,
img_max_res=100,
collapse=(),
verbose=None,
)
⚠️ 常见错误:
- ❌ authors=... 不是参数
- ❌ date=... 不是参数
- ❌ add_evoked 不存在(是 add_evokeds)
- ❌ add_text 不存在(用 add_html 或 add_code)
- ❌ report.save(format='pdf') 没有 format 参数
7. 多被试报告模板
Python
for subj in ['01', '02', '03']:
raw = mne.io.read_raw_fif(f'subj-{subj}_raw.fif', preload=True)
epochs = mne.read_epochs(f'subj-{subj}_epochs.fif')
report = mne.Report(title=f'Subject {subj}', subject=subj)
report.add_raw(raw=raw, title='Preprocessed', psd=True)
report.add_epochs(epochs=epochs, title='Final Epochs')
report.add_evokeds(evokeds=[epochs.average()], titles=['Average ERP'])
os.makedirs('reports', exist_ok=True)
report.save(f'reports/subj-{subj}_report.html', overwrite=True)
8. 验证方法
Python
import os
# 验证 1:报告已生成
assert os.path.exists('subject-01_report.html'), "报告未生成"
print(f"报告大小: {os.path.getsize('subject-01_report.html') / 1024:.1f} KB")
# 验证 2:报告可重新加载
report_loaded = mne.open_report(fname.replace(".html", ".h5")) # open_report 仅支持 HDF5
print(f"报告 HTML 片段数: {len(report_loaded.html)}")
# 验证 3:浏览器中打开人工核对
# os.startfile('subject-01_report.html') # Windows
9. 常见错误
| 错误 | 原因 | 解决方案 |
|---|---|---|
TypeError: unexpected keyword 'authors' |
authors 不是 Report 参数 |
删除该参数,改写在 title 或 add_html 中 |
AttributeError: ... 'add_evoked' |
方法名错 | 改用 add_evokeds(复数) |
AttributeError: ... 'add_text' |
方法名错 | 改用 add_html 或 add_code |
TypeError: unexpected 'format' for save |
save 不接受 format |
MNE 1.x 报告仅支持 HTML,PDF 导出已被移除 |
add_ica 报错缺 inst |
必须传 inst 参数 |
report.add_ica(ica, inst=raw, ...) |
| 报告生成过慢 | 数据太多 | 用 picks=range(20) 限制 ICA 成分 |
| 中文字体显示乱码 | matplotlib 字体设置问题 | matplotlib.rcParams['font.sans-serif'] = ['SimHei'] |
10. 报告归档最佳实践
Python
# 推荐归档结构
import os, subprocess
subj_dir = 'subj-01'
os.makedirs(subj_dir, exist_ok=True)
raw.save(f'{subj_dir}/raw.fif', overwrite=True)
ica.save(f'{subj_dir}/ica.fif', overwrite=True)
epochs.save(f'{subj_dir}/epochs-epo.fif', overwrite=True)
report = mne.Report(title=f'Subject 01 — {subj_dir}')
report.add_raw(raw=raw, title='Preprocessed', psd=True)
report.add_ica(ica=ica, inst=raw, title='ICA')
report.add_epochs(epochs=epochs, title='Final Epochs')
report.add_evokeds(evokeds=[epochs.average()], titles=['Average ERP'])
# 添加 git 版本号作为可追溯性
git_hash = subprocess.check_output(['git', 'rev-parse', 'HEAD']).decode().strip()
report.add_html(f'<p>Code version: <code>{git_hash}</code></p>', title='Version')
report.save(f'{subj_dir}/report.html', overwrite=True)
11. 官方来源
| 资源类型 | 链接 |
|---|---|
mne.Report |
https://mne.tools/stable/generated/mne.Report.html |
| 报告教程 | https://mne.tools/stable/auto_tutorials/intro/70_report.html |
12. 学术引用
报告中方法学部分应引用:
Pernet, C. R., et al. (2020). Issues and recommendations from the OHBM COBIDAS MEEG committee for reproducible EEG and MEG research. Nature Neuroscience, 23(12), 1473-1483. https://doi.org/10.1038/s41593-020-00709-0