4. 雷达图在药物化学中的应用场景归纳总结
聊了这么多雷达图的绘制和解读,咱们得回头看看这玩意儿到底在药物化学里头怎么落地。我这些年做项目,雷达图几乎是天天见,说它是我的“第二个笔记本”也不夸张。它不只是个花架子图表,更是一个高效的决策工具。
那具体有哪些场景呢?我归纳了以下几个核心方向,你看看是不是也是你常碰到的。
4.1 场景一:候选化合物的早期筛选
项目刚开始,手里可能握着几十上百个候选分子。一个个去读数值?那效率太低了。我习惯先把关键指标拉出来,比如活性(pIC50)、选择性、肝微粒体稳定性、Caco-2 渗透性、水溶性,画成雷达图一扫。
选点思路:
- 看面积:多属性平衡好的分子,图形面积通常比较大且饱满。
- 找单属性洼地:某个维度分值特别低(比如水溶性太差),这个分子大概率后续修起来很费劲。
4.2 场景二:先导化合物优化过程监控
这是雷达图最核心的用法。你从先导出发,做了几轮结构修饰,到底优化了什么,牺牲了什么?雷达图能给你最直观的答案。
我通常会把优化前的分子设为一圈“基准线”,然后优化后的新分子叠加上去。看一眼就知道了:
- 活性那条线是不是往外扩了?
- 选择性是不是往里缩了?
- 代谢稳定性有没有跟着降?
常见优化路径雷达图对比:
| 维度 | 先导(Lead) | 优化后(Optimized) | 变化趋势 |
|---|---|---|---|
| LogD | 3.0 | 2.2 | ✓ 改善 |
| 水溶性 (μM) | 15 | 80 | ✓ 改善 |
| 肝微粒体稳定性 (T₁/₂, min) | 8 | 35 | ✓ 改善 |
| Caco-2 渗透性 (×10⁻⁶ cm/s) | 12 | 18 | ✓ 改善 |
| hERG 安全性 (IC₅₀, μM) | 1.5 | 0.9 | ✗ 变差 |
4.3 场景三:成药性评估与风险预警
分子做到差不多时候,该不该推进到下一个阶段?雷达图能辅助做“成药性评分”。我们通常将理想分子的各项属性归一化到0-1之间,画一个“标准靶心”。
参考指标范围:
- 活性:pIC₅₀ ≥ 7.0 → 1.0;pIC₅₀ ≤ 5.0 → 0.0
- LogD:1 ~ 3 → 1.0;<0 或 >5 → 0.0
- 分子量:≤ 450 → 1.0;≥ 600 → 0.0
- 氢键供体:≤ 3 → 1.0;≥ 7 → 0.0
- TPSA:20 ~ 120 Ų → 1.0;超出范围 → 逐渐递减
归一化之后,将测试分子的分值填进去。如果某个维度低于0.5,那就是需要你警惕的红区。
4.4 场景四:系列化合物的横向对比
如果一个系列做了几十个化合物,怎么快速选出最有潜力的几个?我的做法是先画出每个化合物的雷达图,再按照结构骨架分组,同一组内的图放在一起对比。
你会发现:
- 某些取代基对水溶性和渗透性影响很大,但活性基本不变。
- 某些核心骨架会整体拉动稳定性。
- 某些手性中心翻转后,选择性发生了逆转。
这些模式用表格看不出来,但用雷达图一看,图形会“说话”。
4.5 知识体系总览
讲了这么多,咱们把整个知识结构梳理一下。我画了一张图,把雷达图在药物化学里的应用场景串起来。
这张图你看懂了吗?从中心节点“先导化合物优化”出发,向四个核心场景发散,每个场景都是在不同的项目阶段发挥作用。场景二到场景四是递进关系——你先用雷达图筛选出苗头分子,然后在优化阶段持续监控,最后再做一个全面的成药性评估。场景四则像是一个回溯分析,帮你总结构效关系规律。
4.6 一个小彩蛋:自动生成分析脚本
每次做几十个分子的多属性评估,手动一个一个点开文件太累了。后来我写了个小脚本,能批量读取数据并一次性生成对比雷达图矩阵。核心代码如下,你可以参考:
import pandas as pd
import plotly.express as px
from plotly.subplots import make_subplots
import plotly.graph_objects as go
def batch_radar_matrix(data_path, labels, columns):
"""
批量生成化合物雷达图矩阵
:param data_path: CSV文件路径
:param labels: 化合物ID列名
:param columns: 需要显示的属性列名列表
"""
df = pd.read_csv(data_path)
fig = make_subplots(rows=5, cols=5, specs=[[{'type': 'polar'}]*5]*5)
for i in range(min(len(df), 25)):
row = i // 5 + 1
col = i % 5 + 1
comp = df.iloc[i]
fig.add_trace(go.Scatterpolar(
r=[comp[col] for col in columns],
theta=columns,
fill='toself',
name=comp[labels]
), row=row, col=col)
fig.update_layout(height=1200, width=1200, showlegend=False)
return fig