可视化基础:常见图表类型及工具选择
说到药物数据的可视化,我觉得最核心的问题就两个:用什么图、拿什么画。
你可能手头有海量的化合物活性数据、临床试验的时序记录、或者药物-靶点之间的关联网络。但数据本身不会说话。图表,就是你的翻译官。
这一章,我就带你过一遍实战中最常用的三种图表:折线图、柱状图、网络图。我会结合药物数据的具体场景,说说每种图的脾气秉性,以及我踩过的坑。
折线图:盯着时间轴看变化
折线图在药物数据里出场率极高。说白了,它最适合展示连续变量的趋势。
比如药代动力学(PK)研究,你给大鼠灌了药,然后每隔半小时采血测血药浓度。把时间点放在X轴,浓度放在Y轴,连成线。这就是一条典型的药时曲线。
什么时候用折线图?
- 时间序列数据(血药浓度 vs 时间)
- 剂量-效应关系(梯度剂量下的响应变化)
- 稳定性考察(某个化合物在不同pH下的降解曲线)
我在一个项目里遇到过这样的问题:有同事把不同批次的PK数据放在同一张折线图上,但没注意横轴对齐。结果有的批次是0、0.5、1、2小时,另一批是0、1、2、4小时。折线在中间段直接「断崖」。嗯,这里要注意——折线图的横轴必须是等距或等比的连续变量,否则横轴刻度意义会乱掉。
一个有问题的做法:
# 错:批次A的时间点是[0, 0.5, 1, 2],批次B的是[0, 1, 2, 4]
# 直接把两个Series画在同一坐标上,不标注横轴偏差
# 结果:一条线在1h处下降,另一条还在升,观众以为差异显著,其实是采样点不同
那怎么才算对?确保X轴的基准统一。要么全用绝对时间,要么全用相对时间,并且在图例或注释里写清楚。
柱状图:比大小,看差异
柱状图就简单多了。你有个分类变量,然后对每个类别展示一个数值。对比意味非常强烈。
药物数据里常见的用法:
- 不同化合物对同一个靶点的抑制率(IC50值对比)
- 不同给药组之间的统计学差异(p值标记)
- 各器官组织中的药物分布浓度
我个人习惯把柱状图和误差线绑定在一起用。只有柱子没有误差线,看着总觉得少了点什么。
我做药物筛选报告时的一个小技巧
不要把30个化合物的IC50全部堆在一根柱子上。阅读效率太差了。我的做法是先排个序,只展示Top 10或者按机制分组。比如激酶类放一起,GPCR类放一起,观众看得舒服,汇报也省事。
柱状图的坑在哪里?我踩过一次——Y轴从非零起点开始。
# 假设两组数据:对照组的抑制率是12%,给药组是18%
# 如果Y轴从10%开始,两组差异会显得特别夸张
# 读者会觉得涨幅很大,但其实只有6%的差距
# 正确的做法:Y轴始终从0开始,除非你明确标注了截断符号
注意:柱状图的柱子长度代表数值大小。如果Y轴不从0开始,柱子长度会失真。这不是简单的视觉问题,在学术发表里属于数据操纵。
网络图:看清药物和靶点怎么「勾搭」
网络图是药物图谱可视化里最「性感」的部分。它展示的是实体和实体之间的关系。
举个具体场景:一个药物可能作用在多个靶点上,每个靶点又参与多条信号通路,每条通路又和若干疾病相关。把这些关系画在一起,就是一张药物-靶点-通路-疾病的四层网络。
网络图由两个核心元素构成:
- 节点(Node):代表实体,比如药物、靶点蛋白、基因、疾病
- 边(Edge):代表关系,比如「抑制」、「激活」、「结合」
这种图在药物重定位研究里特别有用。你可以快速发现:这个老药居然和一个新靶点有连接?那说不定能换个适应症。
我建议新手先用一个小数据集练手。比如5个药物、10个靶点,关系不超过30条。
# 一个极简的边列表(CSV格式)
drug,target,action
阿司匹林,COX1,抑制
阿司匹林,COX2,抑制
伊马替尼,BCR-ABL,抑制
伊马替尼,c-KIT,抑制
...
有了这个基础数据结构,大部分可视化工具都能直接解析成网络图。
工具选择:用什么画?
工具没有绝对好坏,只有合不合适。我按场景给你分个类:
| 场景 | 推荐工具 | 理由 |
|---|---|---|
| 快速出图,脚本化,批量处理 | Python (Matplotlib / Seaborn / Plotly) | 生态最强,支持折线+柱状+基础网络 |
| 交互式探索,前端展示 | D3.js / ECharts | 定制化高,支持大规模网络,动画流畅 |
| 拖拽式,非编程人员 | Cytoscape / Gephi | 专门做网络图,开箱即用,布局算法丰富 |
| 药物图谱专用,知识图谱 | Neo4j + Bloom / yFiles | 查询+可视化一体,适合大规模图数据 |
我个人习惯是:原型阶段用Python快速验证,定稿阶段用D3.js或ECharts做交付。你想想看,如果你要给老板看,拖拽一个Gephi导出的静态图可能不够「高级」;但如果你投期刊,Cytoscape的导出质量非常可靠。
举个Plotly的例子,画一个最简单的折线图:
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Scatter(
x=[0, 0.5, 1, 2, 4, 8],
y=[0, 12, 45, 78, 92, 88],
mode='lines+markers',
name='化合物A'
))
fig.update_layout(title='大鼠口服给药后血药浓度-时间曲线',
xaxis_title='时间 (h)',
yaxis_title='血药浓度 (ng/mL)')
fig.show()
这段代码跑完,你就有一条标准的药时曲线了。标注点、改颜色、加图例都很直观。
工具选择的黄金法则:
不要为了学工具而学工具。先确认你要讲什么故事,再选顺手的工具。如果数据只有几十个节点,Gephi几分钟搞定;如果数据有几百万条边,那就必须上D3.js或者图数据库了。
最后,我用一张结构图,把这一章的核心逻辑串起来。这张图展示三种图表类型、它们适合的药物数据场景,以及对应的推荐工具。
你看,这张图就是典型的三层结构。顶部是图表类型,中间映射到应用场景,底部推荐工具。你以后做任何可视化汇报,都可以用这种分层法来梳理思路——先定图,再连数据,最后选工具。