# PBJ 论文图构建说明文档

> 生成日期：2026-06-05
> 基于服务器上所有图表构建脚本和原始数据分析

---

## 整体风格

所有图统一遵循 `pbj_style.py` 定义的风格：

- **字体**: Arial/Helvetica/DejaVu Sans，基础字号 8pt
- **配色**: W5=Teal蓝 `#2E86AB`，CK=Burnt红 `#C8463D`
- **分辨率**: 300 DPI，同时输出 PDF（可编辑文本）+ PNG
- **面板标签**: 大写 A/B/C/D，加粗，位于 panel 左上角
- **输出目录**: `/home/ubuntu/palm-vp/public/figures/pbj_v2/`
- **最终版同步**: 拷贝至 `.vitepress/dist/figures/pbj_v2/` 和 `final/` 子目录

---

## Fig1 — CT 发育全景图

**文件名**: `fig1_ct_panorama_v8.png`（最新版，MD5: 1.5MB 1536×1536px）

### 构建脚本
`/home/ubuntu/data_disk/build_fig1_v8.py`

### 数据来源
- 基图来自 DICOM 工作站导出的赤道面/矢状面 CT 切片
- 源文件：`/home/ubuntu/palm-vp/public/figures/pbj_v2/final/fig1_ct_panorama_v3.png`（v3 合成大图）
- v8 是在 v3 基础上裁剪、缩放、重排得到的最终版

### 构建过程
v8 直接从 v3 大图中按像素坐标裁剪出 8 个 panel：

```python
PANELS = {
    'A': (25,   220, 1180, 1370),   # W5-Apr 横断面
    'B': (1400, 220, 2470, 1370),   # CK-Apr 横断面
    'C': (2690, 220, 3760, 1370),   # W5-Dec 横断面
    'D': (3980, 220, 5205, 1370),   # CK-Dec 横断面
    'E': (25,   1570, 1180, 2640),   # W5-Apr 矢状面
    'F': (1400, 1570, 2470, 2640),   # CK-Apr 矢状面
    'G': (2690, 1570, 3760, 2640),   # W5-Dec 矢状面
    'H': (3980, 1570, 5205, 2640),   # CK-Dec 矢状面
}
```

**v8 关键修复**：每个 panel 按不同参数裁剪以移除旧版标注（旧版左下角有小写标签）

```python
CROP = {
    'A': (0.10, 0.12, 0.03, 0.02),
    'B': (0.10, 0.12, 0.03, 0.19),  # 右侧裁剪多（CK 有 Spt/Tilt）
    'C': (0.10, 0.12, 0.03, 0.02),
    'D': (0.10, 0.12, 0.03, 0.22),  # CK 右侧最多
    'E': (0.10, 0.26, 0.03, 0.02),  # 底部裁剪多（矢状面下方有 Resize 标注）
    'F': (0.10, 0.28, 0.03, 0.19),
    'G': (0.10, 0.30, 0.05, 0.02),
    'H': (0.10, 0.28, 0.03, 0.22),
}
# crop = (top%, bottom%, left%, right%)
```

### 排版参数
```python
fig, axes = plt.subplots(2, 4, figsize=(17, 9.5))
plt.subplots_adjust(wspace=0.02, hspace=0.055, left=0.042, right=0.98, top=0.88, bottom=0.04)
# 统一缩放至 850×850px 方形（LANCZOS插值）
# panel 标注：黑色半透明圆角框+白字，字号 17pt
# 纵列标题：Wenye 5/April, Local Green (CK)/April, Wenye 5/December, Local Green (CK)/December
# 行标题：Cross-section, Sagittal section（旋转90°，左侧）
```

### 面板内容
| Panel | W5(Apr) | CK(Apr) | W5(Dec) | CK(Dec) |
|:------|:--------|:--------|:--------|:--------|
| **横断面** | A | B | C | D |
| **矢状面** | E | F | G | H |

### v8 版本历史
- v3: 原始合成大图（8 panel 拼接）
- v4-v7: 尝试不同裁剪策略
- v8: 最终版，修复左侧过裁导致的白色块问题

---

## Fig2 — 代谢组品种间比较

**文件名**: `fig2_metabolomics_v3.png`（最新版，约 446KB）

### 构建脚本
`/home/ubuntu/palm-vp/figures_temp/build_fig2_v3.py`

### 数据来源
- 广泛靶向 LC-MS/MS（UHPLC-MS/MS，Q-Exactive Orbitrap）
- 624 个代谢物：131 黄酮、68 酚酸、52 氨基酸、48 脂质、41 核苷酸、39 有机酸、28 鞣质、14 萜类等
- W5 + CK，5个时间点，n=3 生物学重复×3 技术重复
- 预处理数据存储在 `/tmp/fig2_data.npz`（从原始 Excel 预处理得到）

### 版本修复记录
**v2 BUG**：log₂FC 方向与标签相反。log₂(W5/CK)正值应为 W5 高，负值应为 CK 高。但原始数据中 `is_up_w5` 变量实际包含的是负 log₂FC（CK 高），`is_up_ck` 包含的是正 log₂FC（W5 高）。

**v3 FIX**：交换所有颜色和标签赋值：
```python
is_w5 = is_up_ck_orig    # W5↑ (positive log2FC) → 蓝色
is_ck = is_up_w5_orig    # CK↑ (negative log2FC) → 红色
```

### 排版参数
```python
fig, axes = plt.subplots(2, 2, figsize=(7.08, 6.5))
# Panel A: 火山图
#   - 非显著：灰色 s=6 α=0.3, rasterized=True
#   - W5↑: COLOR_W5 s=12 α=0.7
#   - CK↑: COLOR_CK s=12 α=0.7
#   - 阈值线：|log2FC|=1, FDR=0.05 (-log10=1.3)
#   - 标注：Top 5 最显著代谢物（adjustText 避让）
#   - 图例：内嵌于图顶部（ns, W5↑, CK↑ 计数）
# Panel B: CK 富集 Top 10（水平条形图, height=0.7）
#   - 颜色：氨基酸类 COLOR_CK_LIGHT, 其他 COLOR_CK
# Panel C: W5 富集 Top 10（水平条形图）
#   - 颜色：黄酮类 COLOR_W5_LIGHT, 其他 COLOR_W5
# Panel D: 类级分布（分组柱状图, width=0.35, cols=W5↑蓝+CK↑红）
#   - x轴 45° 旋转
#   - 总差异数 > 5 时标注数字
```

### 关键数据
- 41 个差异代谢物（|log₂FC|>1, FDR q<0.05）
- W5↑: 26 个，全部是次生代谢物（主要为黄酮）
- CK↑: 15 个，主要为氨基酸和有机酸
- 最显著：isorhamnetin-3-O-rutinoside (16.0倍, FDR<0.001)
- 黄酮类 26/131 (19.8%) 全部 W5↑，CK 无黄酮↑
- 氨基酸和有机酸：87%/83% 富集于 CK

---

## Fig3 — 转录组渠道化分析 —— ⚠️ 当前无独立构建脚本

**文件名**: `fig3_temporal_dynamics_v2.png`

### ⚠️ 重要说明
服务器上 `fig3_temporal_dynamics_v2.png` 是**旧版**（时间动态代谢分歧图——差异代谢物数+KEGG DA 热图）。**当前 V19 论文中的 Fig3 已替换为转录组渠道化分析图**。

新 Fig3 的构建脚本**不存在于本服务器上**。以下是基于服务器上实际分析脚本和数据推断的构建参数：

### 数据来源
- 27 个胚乳 RNA-seq 样本（W5/W6/CK × AT1/AT2/AT3 × 3 个生物学重复）
- 测序：NovaSeq 6000, PE 150 bp, 每样本平均 48.6M clean reads (Q30>93%)
- 比对：HISAT2 → 椰子参考基因组 (Wang et al., 2021)，唯一比对率 87.3%
- 定量：StringTie FPKM，25,682 个表达基因
- 分析脚本：`/home/ubuntu/data_disk/pbj_final_cv.py`

### CV 分析方法
```python
# 筛选 34 个核心类黄酮酶基因（PAL/C4H/4CL/CHS/CHI/F3H/F3'H/F3'5'H/FLS/DFR/ANS/LDOX/UFGT）
# FPKM > 1 过滤（max(af_mean, h_mean, as_mean) > 1）
# 每个基因在每组的 CV = std(9个FPKM值) / mean(9个FPKM值)
# 实际论文中按论文描述应为：
#   每个基因在每个 cultivar×timepoint 的 CV = std(3个重复) / mean(3个重复)
#   再按时间点平均
```

### CV 结果（来自 pbj_final_cv.py 实际计算）
```python
H(CK):  1.0272 (n=34)
AF(W5): 0.6270 (n=34)
AS(W6): 0.8322 (n=34)
```

### 关键基因表达
```python
CHS1 (COCNU_02G015910):  CK=69.2 FPKM, W5=4.8 FPKM, W6=3.4 FPKM
LDOX (COCNU_07G008700):  CK=86.3 FPKM, W5=19.7 FPKM, W6=14.2 FPKM
PAL (COCNU_09G010210):   CK=122.8 FPKM (AT2)
CHI (COCNU_12G007230):   CK=241 FPKM (AT2)
```

### 推断的面板构成
| 面板 | 内容 |
|:----|:-----|
| A | 34 个核心酶在 3 品种×3 时期的 FPKM 表达热图/折线图 |
| B | CV 柱状图（CK=1.027 > W6=0.832 > W5=0.627） |
| C | CV 计算方法图示（SD/mean→3重复→平均跨时间点） |
| D | CK 中 mean FPKM vs CV 散点图（Spearman ρ=+0.64, p<0.001） |

---

## Fig4 — CT-代谢物关联框架

**文件名**: `fig4_ct_metabolite_network_v2.png`（约 415KB）

### 构建脚本
`/home/ubuntu/palm-vp/scripts_temp/generate_fig4_v2.py`

### 数据来源
- `/home/ubuntu/research-vault/代谢组学/ct_metabolite_correlation.json`
- 18 个 CT 参数 × 624 个代谢物的 Pearson 相关
- 5 个时间点均值（n=5, df=3）
- FDR 校正（Benjamini-Hochberg, q<0.05）跨 11,232 对
- 置换检验：10,000 次洗牌

### 排版参数
```python
fig = plt.figure(figsize=(10, 7.5), constrained_layout=True)
gs = GridSpec(3, 2, height_ratios=[1.3, 1.0, 0.9])
ax1 = fig.add_subplot(gs[0, :])  # A: 顶部全宽
ax2 = fig.add_subplot(gs[1, 0])  # B: 左
ax3 = fig.add_subplot(gs[1, 1])  # C: 右
ax4 = fig.add_subplot(gs[2, :])  # D: 底部全宽
```

### 各面板详情

**Panel A: Top 10 关联条形图**
- 水平条形图（barh, height=0.65）
- 颜色按代谢物类别映射（Lipids=teal, Flavonoids=red, 等）
- r 值 > 0.9 的在条形内部白色文字；< 0.9 的在条形外部标注
- CT 参数名缩写映射：`ct_name_map`
- 图例：右下角，2列

**Panel B: 类级相关模式箱线图**
- 4 组：Flavonoids×Fiber, Flavonoids×Endosperm, Nucleotides×Fiber, Nucleotides×Endosperm
- 盒须参数精细调参（whiskerprops/capprops/medianprops）
- 每组标注均值+n 数
- 颜色：黄酮=teal, 核苷酸=burnt red

**Panel C: 不对称性柱状图**
- W5（实心蓝色）+ CK（阴影红色, hatch='//', α=0.4）
- 5 个阈值：|r|≥0.7, 0.8, 0.9, 0.95, 0.99
- CK 在所有阈值下均为 0

**Panel D: 整合解读文本**
- ax.axis('off') 纯文本
- 展示关键数字、通路洞察、渠道化诊断

### 关键数据
- W5: 3,376 显著关联（FDR q<0.05），55 对 |r|>0.99
- CK: 无超过 |r|>0.95 的配对
- 置换检验 p<0.0001（中位数 0, 95% CI 0-1）
- 留一法：48/55 对在去除任何单个时间点后仍保持 |r|>0.95
- Spearman/一阶差分 Pearson 均验证同一模式

---

## Fig5 — CT 发芽预测

**文件名**: `fig5_germination_prediction_v3.png`（最新版，约 151KB）

### 构建脚本
`/home/ubuntu/data_disk/build_fig5_v3.py`

**注**：v3 是在 v2（`ct_engine/generate_fig5.py`）基础上独立重写的。

### 数据来源
- CT 特征：SQLite `/home/ubuntu/palm-vp/ct_engine/ct_knowledge.db`
- 预计算 ROC 数据：`/home/ubuntu/palm-vp/public/figures/pbj_v2/fig5_roc_data.json`
- 75 个 CT-发芽匹配样本（45 发芽，30 未发芽）

### v3 修复
**v2 BUG**：`total_area` 特征重要性为 0%，但仍显示在图里。
**v3 FIX**：
```python
fi = [x for x in data['feature_importance'] if not (x['feature'] == 'total_area' and x['importance_pct'] == 0.0)]
```

### 排版参数
```python
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(7, 3.5))
plt.subplots_adjust(wspace=0.35, left=0.08, right=0.97, top=0.88, bottom=0.22)
```

### 各面板详情

**Panel A: ROC 曲线**
- 蓝色曲线（COLOR_W5, lw=2）
- 随机参考线（灰色虚线, lw=0.8）
- AUC 填充带（α=0.15）
- x=FPR, y=TPR
- 图例右下角

**Panel B: 特征重要性**
- 水平条形图（height=0.65）
- 特征名：下划线→空格 → Title（如 `shell_thickness_avg` → "Shell Thickness Avg"）
- 颜色：>7% 用蓝色，其余浅蓝
- 均值参考线（灰色点线）
- 右侧标注百分比值（保留1位小数）
- y 轴反转（最大特征在顶部）

### 关键数据
- AUC = 0.716
- Top 特征：shell_thickness_avg = 8.7%, embryo_size = 8.2%
- 重复随机分割 100 次均值 AUC = 0.678 ± 0.072
- 评估时间从 2-3 个月缩短至约 15 分钟/果

---

## FigS3 — 代谢物共调控网络

**文件名**: `figS3_network_v2.png`（约 224KB）

### 构建脚本
`/home/ubuntu/palm-vp/figures_temp/build_figS3_v2.py`

### 数据来源
- 原始代谢组 Excel：
  `文椰5号及本地绿广靶代谢-21-2347-01/1.Data_assess/all_group/ALL_sample_data.xlsx`
- 624 个代谢物，CK 18 个样品（列 14-31），W5 18 个样品（列 32-49）
- Log10 变换 → Pearson 相关矩阵（624×624）

### 排版参数
```python
fig, axes = plt.subplots(1, 3, figsize=(7.08, 2.8))
bins = np.linspace(0, 1, 60)
```

### 各面板详情

**Panel A: |r| 分布密度图**
- 直方图（60 bins）+ 填充样式
- CK（红色, α=0.5）, W5（蓝色, α=0.5）
- 内嵌小图：|r|>0.8 局部放大（20 bins）

**Panel B: Hub 代谢物散点图**
- 灰色散点：全部 624 个代谢物
- W5 Top 15 hubs（蓝色大圈）+ CK Top 15 hubs（红色大圈）
- 对角线参考线
- 编号标注前 5 个 + 文本框显示 Top 3 名称

**Panel C: 正/负相关平衡柱状图**
- 分组柱状图（width=0.3）
- CK（红色）+ W5（蓝色）
- 正/负相关百分比 + 数值标注

---

## 数据流总览

```
┌─────────────────────────────────────────────────────┐
│  DICOM CT 扫描 (SOMATOM AS+, 7,686 slices)          │
│  ↓                                                   │
│  DeepLabV3+ 分割 (Dice=0.93) → 4组织CT值提取         │
│  ↓                                                   │
│  fig1: CT 扫描工作站输出 v3 → build_fig1_v8.py 剪裁  │
│                                                     │
│  UHPLC-MS/MS (Q-Exactive, 624代谢物)                 │
│  ↓                                                   │
│  prep_fig2_data.py → .npz → build_fig2_v3.py         │
│  ↓  ↓                                                │
│  fig2 (代谢差异)     figS3 (共调控网络)               │
│                                                     │
│  RNA-seq (NovaSeq 6000, 27样本)                       │
│  ↓                                                   │
│  pbj_final_cv.py → 34核心酶CV(FPKM>1)                │
│  ↓                                                   │
│  Fig3 (转录组渠道化) — 脚本不在本服务器               │
│                                                     │
│  CT参数 × 代谢物 → ct_metabolite_correlation.json     │
│  ↓                                                   │
│  generate_fig4_v2.py → fig4 (CT-代谢关联)             │
│                                                     │
│  germination.db + results.json                        │
│  ↓                                                   │
│  build_fig5_v3.py → fig5 (发芽预测, 修复total_area)   │
│                                                     │
│  群体遗传 VCF → plot_cdi_fst_v2.py → CDI三轨图       │
└─────────────────────────────────────────────────────┘
```

---

## 版本变更记录

| 图 | 版本 | 变动 | 脚本 |
|:---|:-----|:-----|:-----|
| Fig1 | v3 → v8 | 像素级裁剪修复白色块、统一方形缩放 | `build_fig1_v8.py` |
| Fig2 | v2 → v3 | 修复 W5↑/CK↑ 颜色方向反转 | `build_fig2_v3.py` |
| Fig3 | 旧→新 | 旧版(时间代谢)→新版(转录渠道化) | 不在本服务器 |
| Fig4 | v1 → v2 | GridSpec 布局重排、Top10 替代 Top15 | `generate_fig4_v2.py` |
| Fig5 | v2 → v3 | 移除 total_area=0% 特征项 | `build_fig5_v3.py` |
| FigS3 | v1 → v2 | 使用真实原始 Excel 数据替代随机模拟 | `build_figS3_v2.py` |
