MA图概述:从定义说起

说起MA图,很多同学第一反应是“又是一张散点图”。没错,它确实是散点图,但它的设计思路非常巧妙。我最早接触MA图是在做芯片数据分析的时候,当时觉得这图平平无奇,后来亲手跑过几批RNA-seq数据才明白——它把差异表达的“幅度”和“可信度”放在一起,一眼就能看出哪些基因值得关注。

MA图的核心就两个字母:M 和 A。别急着翻公式,我们先聊聊它为什么要叫这个名字。

M与A的数学定义

MA图有两个坐标轴:

  • 纵轴 M:代表差异倍数(Fold Change)的对数值。M = log₂(处理组表达量 / 对照组表达量)。比如基因在实验组表达是对照组的4倍,M就是2。如果是对照组的1/4,M就是-2。
  • 横轴 A:代表两个样本的平均表达量(取对数)。A = ½[log₂(处理组表达量) + log₂(对照组表达量)]。说白了就是基因整体的表达强度。

为什么要取log₂?我个人的习惯是:对数变换能让数据更接近正态分布,而且倍数变化在log尺度上是对称的——上调2倍和下调2倍在纵轴上一目了然。你想想看,如果直接用原始倍数,那上调10倍的点会飞上天,下调10倍的点挤在0附近,根本看不清楚。

数学公式很简单:

M = log2(FC) = log2(expr_treatment) - log2(expr_control)
A = (log2(expr_treatment) + log2(expr_control)) / 2

每个基因算出 (A, M) 坐标,投到二维平面上,就是一张MA图了。

关键点:M反映表达变化的幅度(正为上调,负为下调),A反映基因的基础表达水平。两者结合,能帮我们区分“高表达的微小变化”和“低表达的剧烈变化”。

MA图的设计初衷——它解决了什么难题?

上一节我们讲了定义,但你可能会想:直接用火山图(Volcano plot)不是更直观吗?为什么要单独做MA图?

嗯,这个问题我刚开始学的时候也困惑过。后来在实际项目中才体会到:差异表达分析有个天然痛点——低表达基因的波动性特别大。

举个例子:基因A在对照组表达量为1,处理组为10,FC=10,M≈3.3。基因B在对照组表达量为1000,处理组为5000,FC=5,M≈2.3。从生物学角度看,基因A的倍数变化更显著。但基因A的原始表达量太低,测序读数可能只有几个,随机噪声就能把FC推得很高。而基因B表达量高,测量更稳定,FC=5是实打实的。

MA图的横轴A正好把表达量这个因素显式地标出来。你看MA图时会发现:左边的点(低A区域)往往分布更宽,M的波动更大;右边的点(高A区域)则聚在M=0附近。这就是所谓的“低表达基因的变异膨胀”。

我的经验:我曾经在一个转录组项目中,只用FC > 2来筛选差异基因,结果前50个差异基因里30个是低表达基因,复查发现大部分是测序噪声。后来改用MA图结合阈值,才把真正有生物学意义的基因筛出来。所以MA图不是花架子,它是帮你避开统计陷阱的防护网。

如何解读MA图——从入门到避坑

MA图的判读规则很简单:

  1. M=0的水平线:这条线上面的点是上调基因,下面是下调基因。离0线越远,变化幅度越大。
  2. 低A区(左侧):点的纵向散开程度大,说明低表达基因的倍数变化不可靠。不要轻易相信这些点。
  3. 高A区(右侧):点密集在M=0附近,高表达基因通常比较稳定,变化幅度一般不会太大。
  4. 特殊模式:如果看到左侧有大量点形成“喇叭口”形状(A越小,M波动越大),说明数据中低表达基因噪声严重,需要做筛选或归一化处理。

下面这张SVG图展示了MA图的核心结构:横轴A,纵轴M,中间M=0水平线,上下两条示意图阈值线,以及几个代表性基因点的位置。

MA图结构示意 A(平均表达量) M(log₂FC) M=0 上调阈值 下调阈值 上调基因(高表达) 下调基因(高表达) 低表达上调(不可靠) 低表达下调(不可靠) 无差异基因 低A区波动大 图例 可靠差异 不可靠差异

实际应用中的注意事项——我曾经踩过的坑

MA图看起来简单,但真正用起来有几个点容易翻车:

避坑指南

  • 我曾经在项目里直接拿原始Counts数据画MA图,结果发现低表达区全是“假显著”。后来才意识到,必须先用DESeq2或edgeR做归一化(如FPKM、TPM),否则批次效应会让MA图变成一团乱麻。
  • 阈值不要死板:很多人习惯用|M| > 1(即FC > 2)来标上调/下调。但你应该结合A轴:对于高表达基因,|M| > 0.6可能就有生物学意义;对于低表达基因,即使|M| > 2也可能是假阳性。我一般会再叠加一个p值或者调整后的p值(FDR)来过滤。
  • 不要只看一张MA图:一个完整的差异表达分析,我通常同时看MA图和火山图。MA图看分布趋势和噪声水平,火山图看统计显著性。两者互补,缺一不可。

MA图的数学本质——一张表说清楚

下面这个表格总结了M和A在不同场景下的含义:

场景 M值含义 A值含义
基因上调 M > 0 基因表达强度的对数平均
基因下调 M < 0 同上
无差异 M ≈ 0 代表该基因的整体表达水平
低表达区噪声 M绝对值大但不可靠 A很小(如 < 2)
高表达区稳定 M绝对值小但可靠 A较大(如 > 5)

实用技巧:如果你想用代码画MA图,一个简单的Python脚本就够用了:

import matplotlib.pyplot as plt
import numpy as np

# 假设你有两个向量:logFC 和 baseMean
# 这里用随机数据演示
np.random.seed(42)
A = np.random.uniform(1, 8, 1000)
M = np.random.normal(0, 0.8, 1000)

plt.figure(figsize=(8,6))
plt.scatter(A, M, s=5, alpha=0.4, c='#3498db')
plt.axhline(y=0, color='#e74c3c', linestyle='--', linewidth=1)
plt.xlabel('A (mean expression)', fontsize=12)
plt.ylabel('M (log2 FC)', fontsize=12)
plt.title('MA Plot (example)', fontsize=14)
plt.show()

当然,实际项目中你会用DESeq2的plotMA()或者edgeR的plotSmear(),它们自动处理了归一化和阈值标注。但理解底层的数学原理,才能用好这些工具。