基于 Seurat v5.5.1 官方教程,系统学习单细胞数据的可视化技巧与 SCTransform 先进归一化方法。
阶段2-A:数据可视化方法(20张图,5大板块)
阶段2-B:SCTransform 归一化(9张图,7个步骤)
基于 PBMC 3k 数据集(阶段1的 pbmc3k_final.rds),演示 Seurat v5 的五大可视化功能。
library(Seurat)
library(ggplot2)
library(patchwork)
# 加载阶段1保存的最终对象
pbmc <- readRDS("output/pbmc3k_final.rds")
# 添加随机分组变量(用于演示 split.by 功能)
set.seed(42)
pbmc$groups <- sample(c("group1", "group2"), size = ncol(pbmc), replace = TRUE)
# 演示用基因列表
features <- c("LYZ", "CCL5", "IL32", "PTPRCAP", "FCGR3A", "PF4")
Seurat 提供了五种主要的基因表达可视化方法,各有侧重:
| 方法 |
函数 |
特点 |
适用场景 |
| 山脊图 |
RidgePlot() |
展示表达密度分布 |
比较多个基因的表达模式 |
| 小提琴图 |
VlnPlot() |
展示表达分布+密度 |
各聚类间基因表达比较 |
| Feature Plot |
FeaturePlot() |
在低维空间展示表达 |
空间分布模式 |
| 气泡图 |
DotPlot() |
大小=比例,颜色=表达量 |
大量基因×聚类的概览 |
| 热图 |
DoHeatmap() |
颜色梯度展示表达 |
多基因多聚类综合展示 |
展示各聚类中基因表达的密度分布。每个「山脊」代表一个聚类,宽度反映表达密度。
p_ridge <- RidgePlot(pbmc, features = features, ncol = 2)

展示各聚类中基因表达的完整分布(中位数、四分位数、密度)。
p_vln <- VlnPlot(pbmc, features = features)

在 UMAP 降维空间上展示基因表达水平,颜色深浅代表表达量。
p_feature <- FeaturePlot(pbmc, features = features)

点的大小表示该聚类中表达该基因的细胞比例,颜色深浅表示平均表达水平。适合快速概览多个基因在所有聚类中的表达模式。
p_dot <- DotPlot(pbmc, features = features) + RotatedAxis()

对每个聚类降采样后展示基因表达热图,适合同时查看多个基因在多个聚类中的表达模式。
p_heat <- DoHeatmap(subset(pbmc, downsample = 100), features = features, size = 3)

FeaturePlot 是最灵活的可视化函数,支持多种自定义选项。
默认带图例,展示连续的颜色梯度:
FeaturePlot(pbmc, features = "MS4A1")

设定表达量的最小/最大截断值,增强视觉对比度:
FeaturePlot(pbmc, features = "MS4A1", min.cutoff = 1, max.cutoff = 3)

使用分位数 cutoff(如 q10-q90),适合多基因同时绘图时统一色彩范围:
FeaturePlot(pbmc, features = c("MS4A1", "PTPRCAP"), min.cutoff = "q10", max.cutoff = "q90")

混合展示两个基因的共表达,红色和绿色分别代表两个基因,黄色表示共表达:
FeaturePlot(pbmc, features = c("MS4A1", "CD79A"), blend = TRUE)

使用 split.by 参数按分组变量分割展示同一基因的表达:
FeaturePlot(pbmc, features = c("MS4A1", "CD79A"), split.by = "groups")

VlnPlot(pbmc, features = "percent.mt", split.by = "groups")

DotPlot(pbmc, features = features, split.by = "groups") + RotatedAxis()


展示前 100 个高变基因在前 500 个细胞中的表达,使用 angle = 90 旋转基因标签:
DoHeatmap(pbmc, features = VariableFeatures(pbmc)[1:100], cells = 1:500, size = 4, angle = 90) + NoLegend()

Seurat 的图表基于 ggplot2,支持完整的 ggplot2 主题系统。
baseplot <- DimPlot(pbmc, reduction = "umap")
baseplot + labs(title = "Clustering of 2,700 PBMCs")


多个主题元素可以链式叠加,同时调整字体大小、图例等:
baseplot + DarkTheme() +
theme(axis.title = element_text(size = 18), legend.text = element_text(size = 18)) +
guides(colour = guide_legend(override.aes = list(size = 10)))

使用 patchwork 包的 + 和 & 运算符组合多个图表。
plot1 <- DimPlot(pbmc)
plot2 <- FeatureScatter(pbmc, feature1 = "LYZ", feature2 = "CCL5")
plot1 + plot2

& 运算符对组合图中的所有子图应用同一操作:
(plot1 + plot2) & NoLegend()

使用 LabelClusters() 在降维图上直接标注聚类编号:
p_label <- DimPlot(pbmc, reduction = "pca") + NoLegend()
p_label <- LabelClusters(plot = p_label, id = "ident")

传统标准流程使用 NormalizeData() + ScaleData() + FindVariableFeatures() 三步处理:
- LogNormalize:简单但对测序深度差异敏感
- 高变基因选择:可能受技术因素影响
- 标准化:无法完全去除批次效应
SCTransform(v2)使用负二项回归模型一步完成:
1. 对每个基因拟合 count 模型(考虑测序深度等协变量)
2. 计算 Pearson 残差(去除技术变异后的生物学信号)
3. 选择高变基因(默认 3000 个,比标准的 2000 个更多)
4. 生成「校正后」的 UMI counts(可理解为统一测序深度后的预期值)
library(Seurat)
library(ggplot2)
library(sctransform)
# 从原始数据开始(独立于阶段1的标准流程)
pbmc_data <- Read10X(data.dir = data_dir)
pbmc <- CreateSeuratObject(counts = pbmc_data)
# 计算线粒体百分比
pbmc <- PercentageFeatureSet(pbmc, pattern = "^MT-", col.name = "percent.mt")
# QC 过滤
pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)
# SCTransform 一步完成归一化 + 变量特征选择 + 标准化
# 同时回归线粒体百分比(去除技术变异)
pbmc <- SCTransform(pbmc, vars.to.regress = "percent.mt", verbose = FALSE)
运行 SCTransform() 后,创建了一个名为 SCT 的新 Assay 并设为默认:
| 层级 |
内容 |
用途 |
scale.data |
Pearson 残差 |
PCA 输入 |
counts |
校正后的 UMI counts |
重新计算归一化值 |
data |
校正 counts 的 log 归一化 |
可视化 |
> DefaultAssay(pbmc)
[1] "SCT"
> pbmc[["SCT"]]
SCTAssay data with 12519 features for 2638 cells, and 1 SCTModel(s)
Top 10 variable features:
S100A9, GNLY, LYZ, S100A8, NKG7, FTL, GZMB, IGLL5, FTH1, CCL5
- 细胞数:2,700 -> 2,638(QC 过滤后)
- 基因数:32,738 -> 12,519(过滤后参与建模)
- 耗时:约 5 分钟(未安装 glmGamPoi 加速包,使用原生实现)
- 变量特征:3,000 个(默认,比标准流程多 1,000 个)
- 模型版本:v2(Seurat v5 默认,固定斜率模型 + 排除 Poisson 基因)
pbmc <- RunPCA(pbmc, verbose = FALSE)
DimPlot(pbmc, reduction = "pca")

SCTransform 推荐使用更多 PC(30 个),因为更有效的归一化使得高阶 PC 更可能代表真实的生物学变异。
pbmc <- RunUMAP(pbmc, dims = 1:30, verbose = FALSE)
DimPlot(pbmc, reduction = "umap")

ElbowPlot(pbmc, ndims = 50)

pbmc <- FindNeighbors(pbmc, dims = 1:30, verbose = FALSE)
pbmc <- FindClusters(pbmc, verbose = FALSE)
DimPlot(pbmc, reduction = "umap", label = TRUE)

SCTransform 归一化能揭示比标准流程更精细的细胞亚群。
SCTransform 能更清晰地区分 CD8 T 细胞的三个亚群(naive / memory / effector):
| 亚群 |
标志基因 |
说明 |
| Naive CD8 T |
CD8A, CCR7 |
初始 T 细胞 |
| Memory CD8 T |
GZMK |
记忆 T 细胞 |
| Effector CD8 T |
CCL5 |
效应 T 细胞 |
同时区分 CD4 T 细胞的三亚群(naive / memory / IFN-activated):
| 亚群 |
标志基因 |
说明 |
| Naive CD4 T |
CCR7, IL32 |
初始 T 细胞 |
| Memory CD4 T |
S100A4, ANXA1 |
记忆 T 细胞 |
| IFN-activated |
ISG15 |
干素激活 |
小提琴图:
VlnPlot(pbmc, features = c("CD8A", "GZMK", "CCL5", "S100A4", "ANXA1", "CCR7", "ISG15", "CD3D"),
pt.size = 0.2, ncol = 4)

FeaturePlot(T 细胞标志):
FeaturePlot(pbmc, features = c("CD8A", "GZMK", "CCL5", "S100A4", "ANXA1", "CCR7"),
pt.size = 0.2, ncol = 3)

SCTransform 还揭示了:
- B 细胞发育亚结构(TCL1A, FCER2)
- NK 细胞 CD56dim vs. bright 亚群(XCL1, FCGR3A)
FeaturePlot(pbmc, features = c("CD3D", "ISG15", "TCL1A", "FCER2", "XCL1", "FCGR3A"),
pt.size = 0.2, ncol = 3)

SCTransform 默认返回 3,000 个变量特征(标准流程为 2,000 个):
length(VariableFeatures(pbmc)) # 3000

DimPlot(pbmc, reduction = "umap", group.by = "seurat_clusters") +
ggtitle("SCT: 30 PCs (推荐)")

| 指标 |
标准流程 |
SCTransform |
| 归一化方法 |
LogNormalize |
负二项回归(v2) |
| 变量特征数 |
2,000 |
3,000 |
| 推荐 PC 数 |
10 |
30 |
| 回归变量 |
可选 |
内置支持 |
| 测序深度影响 |
仍有残留 |
显著减弱 |
| 细胞亚群分辨率 |
基础 |
更精细(CD8 naive/memory/effector) |
| 计算耗时 |
秒级 |
分钟级(约5分钟) |
| 内存占用 |
较低 |
较高(非稀疏矩阵) |
| 适用场景 |
快速探索 |
正式分析/发表 |
- 数据中测序深度差异较大时
- 需要检测精细细胞亚群时
- 需要同时回归多个协变量时
- 准备发表正式结果时
- 跨数据集整合分析时(SCT 是整合分析的前提)
SCTransform 与管道操作符配合,可以一行代码完成完整分析:
library(dplyr)
pbmc <- CreateSeuratObject(pbmc_data) %>%
PercentageFeatureSet(pattern = "^MT-", col.name = "percent.mt") %>%
SCTransform(vars.to.regress = "percent.mt") %>%
RunPCA() %>%
FindNeighbors(dims = 1:30) %>%
RunUMAP(dims = 1:30) %>%
FindClusters()
###############################################################################
# Seurat v5 阶段2-A:数据可视化方法
# 基于官方教程: https://satijalab.org/seurat/articles/visualization_vignette
# 使用阶段1保存的 pbmc3k_final.rds 对象
###############################################################################
library(Seurat)
library(ggplot2)
library(patchwork)
# === 路径配置 ===
output_dir <- "E:/BaiduNetdiskDownload/生物信息学/pbmc3k_tutorial/output"
viz_dir <- "E:/BaiduNetdiskDownload/生物信息学/pbmc3k_tutorial/output/visualization"
dir.create(viz_dir, showWarnings = FALSE, recursive = TRUE)
# === 加载阶段1的最终对象 ===
pbmc <- readRDS(file.path(output_dir, "pbmc3k_final.rds"))
cat("已加载 pbmc3k_final.rds\n")
print(pbmc)
# 添加分组变量(用于演示 split.by 功能)
set.seed(42)
pbmc$groups <- sample(c("group1", "group2"), size = ncol(pbmc), replace = TRUE)
# 定义演示用基因列表
features <- c("LYZ", "CCL5", "IL32", "PTPRCAP", "FCGR3A", "PF4")
# ============================================================================
# 1. 五种可视化方法展示 Marker 基因表达
# ============================================================================
cat("\n========== 1. 五种可视化方法 ==========\n")
# 1.1 Ridge Plot(山脊图)- 展示各聚类的基因表达分布
p_ridge <- RidgePlot(pbmc, features = features, ncol = 2)
ggsave(file.path(viz_dir, "01_ridge_plot.png"), plot = p_ridge, width = 12, height = 10, dpi = 150)
cat("已保存: 01_ridge_plot.png\n")
# 1.2 Violin Plot(小提琴图)- 展示各聚类的基因表达分布
p_vln <- VlnPlot(pbmc, features = features)
ggsave(file.path(viz_dir, "02_violin_plot.png"), plot = p_vln, width = 14, height = 8, dpi = 150)
cat("已保存: 02_violin_plot.png\n")
# 1.3 Feature Plot - 在低维空间展示基因表达
p_feature <- FeaturePlot(pbmc, features = features)
ggsave(file.path(viz_dir, "03_feature_plot.png"), plot = p_feature, width = 14, height = 10, dpi = 150)
cat("已保存: 03_feature_plot.png\n")
# 1.4 Dot Plot(气泡图)- 点大小=表达比例,颜色=平均表达水平
p_dot <- DotPlot(pbmc, features = features) + RotatedAxis()
ggsave(file.path(viz_dir, "04_dot_plot.png"), plot = p_dot, width = 10, height = 6, dpi = 150)
cat("已保存: 04_dot_plot.png\n")
# 1.5 Heatmap(热图)- 降采样后展示基因表达
p_heat <- DoHeatmap(subset(pbmc, downsample = 100), features = features, size = 3)
ggsave(file.path(viz_dir, "05_heatmap.png"), plot = p_heat, width = 10, height = 6, dpi = 150)
cat("已保存: 05_heatmap.png\n")
# ============================================================================
# 2. 自定义 FeaturePlot
# ============================================================================
cat("\n========== 2. 自定义 FeaturePlot ==========\n")
# 2.1 带图例的 FeaturePlot
p_fp1 <- FeaturePlot(pbmc, features = "MS4A1")
ggsave(file.path(viz_dir, "06_featureplot_legend.png"), plot = p_fp1, width = 7, height = 6, dpi = 150)
cat("已保存: 06_featureplot_legend.png\n")
# 2.2 调整对比度(设定 min/max cutoff)
p_fp2 <- FeaturePlot(pbmc, features = "MS4A1", min.cutoff = 1, max.cutoff = 3)
ggsave(file.path(viz_dir, "07_featureplot_contrast.png"), plot = p_fp2, width = 7, height = 6, dpi = 150)
cat("已保存: 07_featureplot_contrast.png\n")
# 2.3 分位数 cutoff(适合多基因同时绘图)
p_fp3 <- FeaturePlot(pbmc, features = c("MS4A1", "PTPRCAP"), min.cutoff = "q10", max.cutoff = "q90")
ggsave(file.path(viz_dir, "08_featureplot_quantile.png"), plot = p_fp3, width = 12, height = 5, dpi = 150)
cat("已保存: 08_featureplot_quantile.png\n")
# 2.4 混合展示两个基因的共表达(blend 模式)
p_fp4 <- FeaturePlot(pbmc, features = c("MS4A1", "CD79A"), blend = TRUE)
ggsave(file.path(viz_dir, "09_featureplot_blend.png"), plot = p_fp4, width = 14, height = 5, dpi = 150)
cat("已保存: 09_featureplot_blend.png\n")
# 2.5 按分组分割展示
p_fp5 <- FeaturePlot(pbmc, features = c("MS4A1", "CD79A"), split.by = "groups")
ggsave(file.path(viz_dir, "10_featureplot_split.png"), plot = p_fp5, width = 14, height = 10, dpi = 150)
cat("已保存: 10_featureplot_split.png\n")
# ============================================================================
# 3. 其他可视化功能
# ============================================================================
cat("\n========== 3. 其他可视化功能 ==========\n")
# 3.1 按分组分割的小提琴图
p_vln_split <- VlnPlot(pbmc, features = "percent.mt", split.by = "groups")
ggsave(file.path(viz_dir, "11_violin_split.png"), plot = p_vln_split, width = 8, height = 5, dpi = 150)
cat("已保存: 11_violin_split.png\n")
# 3.2 按分组分割的气泡图
p_dot_split <- DotPlot(pbmc, features = features, split.by = "groups") + RotatedAxis()
ggsave(file.path(viz_dir, "12_dotplot_split.png"), plot = p_dot_split, width = 12, height = 6, dpi = 150)
cat("已保存: 12_dotplot_split.png\n")
# 3.3 DimPlot 默认使用 UMAP
p_dim1 <- DimPlot(pbmc)
ggsave(file.path(viz_dir, "13_dimplot_umap.png"), plot = p_dim1, width = 8, height = 7, dpi = 150)
cat("已保存: 13_dimplot_umap.png\n")
# 3.4 DoHeatmap 带分组条
p_heat2 <- DoHeatmap(pbmc, features = VariableFeatures(pbmc)[1:100], cells = 1:500, size = 4, angle = 90) + NoLegend()
ggsave(file.path(viz_dir, "14_heatmap_grouped.png"), plot = p_heat2, width = 10, height = 8, dpi = 150)
cat("已保存: 14_heatmap_grouped.png\n")
# ============================================================================
# 4. 应用主题(Theme)
# ============================================================================
cat("\n========== 4. 应用主题 ==========\n")
baseplot <- DimPlot(pbmc, reduction = "umap")
# 4.1 添加标题
p_theme1 <- baseplot + labs(title = "Clustering of 2,700 PBMCs")
ggsave(file.path(viz_dir, "15_theme_title.png"), plot = p_theme1, width = 8, height = 7, dpi = 150)
cat("已保存: 15_theme_title.png\n")
# 4.2 暗色主题
p_theme2 <- baseplot + DarkTheme()
ggsave(file.path(viz_dir, "16_theme_dark.png"), plot = p_theme2, width = 8, height = 7, dpi = 150)
cat("已保存: 16_theme_dark.png\n")
# 4.3 链式主题
p_theme3 <- baseplot + DarkTheme() +
theme(axis.title = element_text(size = 18), legend.text = element_text(size = 18)) +
guides(colour = guide_legend(override.aes = list(size = 10)))
ggsave(file.path(viz_dir, "17_theme_chained.png"), plot = p_theme3, width = 10, height = 8, dpi = 150)
cat("已保存: 17_theme_chained.png\n")
# ============================================================================
# 5. 图组合并
# ============================================================================
cat("\n========== 5. 图组合并 ==========\n")
plot1 <- DimPlot(pbmc)
plot2 <- FeatureScatter(pbmc, feature1 = "LYZ", feature2 = "CCL5")
# 5.1 拼接两图
p_combine1 <- plot1 + plot2
ggsave(file.path(viz_dir, "18_combine_plots.png"), plot = p_combine1, width = 14, height = 6, dpi = 150)
cat("已保存: 18_combine_plots.png\n")
# 5.2 移除所有图例
p_combine2 <- (plot1 + plot2) & NoLegend()
ggsave(file.path(viz_dir, "19_combine_nolegend.png"), plot = p_combine2, width = 14, height = 6, dpi = 150)
cat("已保存: 19_combine_nolegend.png\n")
# ============================================================================
# 6. 聚类标签
# ============================================================================
cat("\n========== 6. 聚类标签 ==========\n")
# 6.1 标注聚类
p_label1 <- DimPlot(pbmc, reduction = "pca") + NoLegend()
p_label1 <- LabelClusters(plot = p_label1, id = "ident")
ggsave(file.path(viz_dir, "20_label_clusters.png"), plot = p_label1, width = 8, height = 7, dpi = 150)
cat("已保存: 20_label_clusters.png\n")
# ============================================================================
# 总结
# ============================================================================
cat("\n")
cat("=======================================================\n")
cat(" 阶段2-A 可视化教程完成!\n")
cat("=======================================================\n")
cat(" 输出目录:", viz_dir, "\n")
cat(" 图片数量: 20 张\n")
cat(" 覆盖内容:\n")
cat(" 01-05: 五种核心可视化方法\n")
cat(" 06-10: FeaturePlot 自定义技巧\n")
cat(" 11-14: 分组分割与热图\n")
cat(" 15-17: 主题定制\n")
cat(" 18-19: 图组合并\n")
cat(" 20: 聚类标签\n")
cat("=======================================================\n")
###############################################################################
# Seurat v5 阶段2-B:SCTransform 归一化分析
# 基于官方教程: https://satijalab.org/seurat/articles/sctransform_vignette
# SCTransform 替代 NormalizeData + ScaleData + FindVariableFeatures 三步
# 使用 PBMC 3k 数据从头创建新对象(独立于阶段1的标准流程)
###############################################################################
library(Seurat)
library(ggplot2)
library(sctransform)
library(patchwork)
# === 路径配置 ===
data_dir <- "E:/BaiduNetdiskDownload/生物信息学/pbmc3k_tutorial/data/filtered_gene_bc_matrices/hg19"
output_dir <- "E:/BaiduNetdiskDownload/生物信息学/pbmc3k_tutorial/output"
sct_dir <- "E:/BaiduNetdiskDownload/生物信息学/pbmc3k_tutorial/output/sctransform"
dir.create(sct_dir, showWarnings = FALSE, recursive = TRUE)
# ============================================================================
# 1. 加载数据并创建 Seurat 对象
# ============================================================================
cat("\n========== 1. 加载数据 ==========\n")
pbmc_data <- Read10X(data.dir = data_dir)
pbmc <- CreateSeuratObject(counts = pbmc_data)
cat("已创建 Seurat 对象\n")
print(pbmc)
# ============================================================================
# 2. 计算线粒体百分比并应用 SCTransform
# ============================================================================
cat("\n========== 2. SCTransform 归一化 ==========\n")
# 计算线粒体基因百分比
pbmc <- PercentageFeatureSet(pbmc, pattern = "^MT-", col.name = "percent.mt")
cat("已计算线粒体百分比\n")
# QC 过滤(与阶段1一致)
pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)
cat("QC 过滤后细胞数:\n")
cat(ncol(pbmc), "\n")
# 应用 SCTransform(同时回归线粒体百分比)
# SCTransform 一步完成:归一化 + 变量特征选择 + 标准化
cat("正在运行 SCTransform(可能需要1-2分钟)...\n")
pbmc <- SCTransform(pbmc, vars.to.regress = "percent.mt", verbose = TRUE)
cat("SCTransform 完成!\n")
cat("当前默认 assay:\n")
print(DefaultAssay(pbmc))
# ============================================================================
# 3. 降维分析:PCA + UMAP
# ============================================================================
cat("\n========== 3. 降维分析 ==========\n")
# PCA(使用 SCT residuals)
pbmc <- RunPCA(pbmc, verbose = FALSE)
cat("PCA 完成\n")
# UMAP(使用前30个PC,SCTransform 推荐使用更多PC)
pbmc <- RunUMAP(pbmc, dims = 1:30, verbose = FALSE)
cat("UMAP 完成\n")
# 3.1 PCA 可视化
p_pca <- DimPlot(pbmc, reduction = "pca")
ggsave(file.path(sct_dir, "01_pca.png"), plot = p_pca, width = 8, height = 7, dpi = 150)
cat("已保存: 01_pca.png\n")
# 3.2 UMAP 可视化
p_umap <- DimPlot(pbmc, reduction = "umap")
ggsave(file.path(sct_dir, "02_umap.png"), plot = p_umap, width = 8, height = 7, dpi = 150)
cat("已保存: 02_umap.png\n")
# 3.3 PCA Elbow Plot(选择PC数量参考)
p_elbow <- ElbowPlot(pbmc, ndims = 50)
ggsave(file.path(sct_dir, "03_elbow_plot.png"), plot = p_elbow, width = 8, height = 5, dpi = 150)
cat("已保存: 03_elbow_plot.png\n")
# ============================================================================
# 4. 聚类分析
# ============================================================================
cat("\n========== 4. 聚类分析 ==========\n")
pbmc <- FindNeighbors(pbmc, dims = 1:30, verbose = FALSE)
pbmc <- FindClusters(pbmc, verbose = FALSE)
cat("聚类完成\n")
# 4.1 带标签的 UMAP
p_umap_label <- DimPlot(pbmc, reduction = "umap", label = TRUE)
ggsave(file.path(sct_dir, "04_umap_labeled.png"), plot = p_umap_label, width = 8, height = 7, dpi = 150)
cat("已保存: 04_umap_labeled.png\n")
# ============================================================================
# 5. SCTransform 优势展示:更精细的细胞亚群
# ============================================================================
cat("\n========== 5. SCTransform 优势展示 ==========\n")
# 5.1 T 细胞亚群标志基因小提琴图
# SCTransform 能更清晰地区分 CD8 T 细胞亚群(naive/memory/effector)
p_vln_t <- VlnPlot(pbmc, features = c("CD8A", "GZMK", "CCL5", "S100A4", "ANXA1", "CCR7", "ISG15", "CD3D"),
pt.size = 0.2, ncol = 4)
ggsave(file.path(sct_dir, "05_violin_tcell_markers.png"), plot = p_vln_t, width = 16, height = 10, dpi = 150)
cat("已保存: 05_violin_tcell_markers.png\n")
# 5.2 T 细胞标志基因 FeaturePlot
p_fp_t <- FeaturePlot(pbmc, features = c("CD8A", "GZMK", "CCL5", "S100A4", "ANXA1", "CCR7"),
pt.size = 0.2, ncol = 3)
ggsave(file.path(sct_dir, "06_featureplot_tcell.png"), plot = p_fp_t, width = 14, height = 10, dpi = 150)
cat("已保存: 06_featureplot_tcell.png\n")
# 5.3 B 细胞与 NK 细胞标志基因 FeaturePlot
p_fp_bnk <- FeaturePlot(pbmc, features = c("CD3D", "ISG15", "TCL1A", "FCER2", "XCL1", "FCGR3A"),
pt.size = 0.2, ncol = 3)
ggsave(file.path(sct_dir, "07_featureplot_bnk.png"), plot = p_fp_bnk, width = 14, height = 10, dpi = 150)
cat("已保存: 07_featureplot_bnk.png\n")
# ============================================================================
# 6. SCTransform 与标准归一化对比
# ============================================================================
cat("\n========== 6. 对比分析 ==========\n")
# 6.1 SCTransform 变量特征数量(默认3000个,比标准流程的2000更多)
sct_features <- VariableFeatures(pbmc)
cat("SCTransform 变量特征数量:", length(sct_features), "\n")
# 6.2 展示前20个变量特征
p_var <- LabelPoints(plot = VariableFeaturePlot(pbmc), points = sct_features[1:20], repel = TRUE)
ggsave(file.path(sct_dir, "08_variable_features.png"), plot = p_var, width = 10, height = 8, dpi = 150)
cat("已保存: 08_variable_features.png\n")
# 6.3 SCT assay 结构说明
cat("\nSCT Assay 层级结构:\n")
print(pbmc[["SCT"]])
# 6.4 标准流程对比图:使用前10个PC(标准流程推荐)vs 前30个PC(SCT推荐)
p_umap_10 <- DimPlot(pbmc, reduction = "umap", group.by = "seurat_clusters") +
ggtitle("SCT: 30 PCs (推荐)")
ggsave(file.path(sct_dir, "09_umap_sct_30pc.png"), plot = p_umap_10, width = 8, height = 7, dpi = 150)
cat("已保存: 09_umap_sct_30pc.png\n")
# ============================================================================
# 7. 保存 SCTransform 结果
# ============================================================================
cat("\n========== 7. 保存结果 ==========\n")
saveRDS(pbmc, file.path(output_dir, "pbmc3k_sct.rds"))
cat("已保存 SCTransform 对象: pbmc3k_sct.rds\n")
# ============================================================================
# 总结
# ============================================================================
cat("\n")
cat("=======================================================\n")
cat(" 阶段2-B SCTransform 教程完成!\n")
cat("=======================================================\n")
cat(" 输出目录:", sct_dir, "\n")
cat(" 图片数量: 9 张\n")
cat(" 覆盖内容:\n")
cat(" 01-03: PCA + UMAP + Elbow Plot\n")
cat(" 04: 聚类标注\n")
cat(" 05-07: T/B/NK 细胞亚群标志基因可视化\n")
cat(" 08: SCTransform 变量特征\n")
cat(" 09: SCT UMAP(30 PCs)\n")
cat(" SCT vs 标准流程:\n")
cat(" - 变量特征: 3000(SCT) vs 2000(标准)\n")
cat(" - 推荐PC数: 30(SCT) vs 10(标准)\n")
cat(" - 归一化方法: 负二项回归 vs LogNormalize\n")
cat(" - 能揭示更精细的细胞亚群(CD8 naive/memory/effector)\n")
cat("=======================================================\n")
| 编号 |
文件名 |
内容 |
| 01 |
01_ridge_plot.png |
山脊图 |
| 02 |
02_violin_plot.png |
小提琴图 |
| 03 |
03_feature_plot.png |
Feature Plot |
| 04 |
04_dot_plot.png |
气泡图 |
| 05 |
05_heatmap.png |
热图 |
| 06 |
06_featureplot_legend.png |
带图例 FeaturePlot |
| 07 |
07_featureplot_contrast.png |
调整对比度 |
| 08 |
08_featureplot_quantile.png |
分位数 cutoff |
| 09 |
09_featureplot_blend.png |
混合模式 |
| 10 |
10_featureplot_split.png |
分组分割 |
| 11 |
11_violin_split.png |
分组小提琴图 |
| 12 |
12_dotplot_split.png |
分组气泡图 |
| 13 |
13_dimplot_umap.png |
UMAP |
| 14 |
14_heatmap_grouped.png |
分组热图 |
| 15 |
15_theme_title.png |
添加标题 |
| 16 |
16_theme_dark.png |
暗色主题 |
| 17 |
17_theme_chained.png |
链式主题 |
| 18 |
18_combine_plots.png |
图组合并 |
| 19 |
19_combine_nolegend.png |
移除图例 |
| 20 |
20_label_clusters.png |
聚类标签 |
| 编号 |
文件名 |
内容 |
| 01 |
01_pca.png |
PCA |
| 02 |
02_umap.png |
UMAP |
| 03 |
03_elbow_plot.png |
Elbow Plot |
| 04 |
04_umap_labeled.png |
聚类标注 UMAP |
| 05 |
05_violin_tcell_markers.png |
T 细胞标志小提琴图 |
| 06 |
06_featureplot_tcell.png |
T 细胞 FeaturePlot |
| 07 |
07_featureplot_bnk.png |
B/NK 细胞 FeaturePlot |
| 08 |
08_variable_features.png |
变量特征图 |
| 09 |
09_umap_sct_30pc.png |
SCT UMAP(30 PCs) |
本教程基于 Seurat v5.5.1 官方文档整理
R 4.6.1 + Seurat 5.5.1 + Windows 环境
阶段2-A: 数据可视化方法 | 阶段2-B: SCTransform 归一化