单细胞可视化定制:自定义颜色与顺序的 t-SNE 及比例图
时长: 18 分钟
字数: 3.8k 字
更新: 2026-02-27
阅读: 0 次
环境配置
R
# 加载必要的R包
library(Seurat) # 用于单细胞数据分析
library(tidyverse) # 数据处理和可视化工具集
library(ggplot2) # 绘图包
library(grid) # 底层绘图系统
# 定义细胞类型的颜色方案
celltype_colors <- c(
"T cell" = "#2A85BD",
"Mono_Macro" = "#FF6700",
"NK" = "#FF96B2",
"mDC" = "#A6A6A6",
"Plasma" = "#F8D76E",
"Mast" = "#42C274",
"B cell" = "#9370DB",
"pDC" = "#89CFF0"
)
group_colors <- c(
"S150" = "#1A66B1",
"S133" = "#DB0308",
"S134" = "#BA170D",
"S135" = "#FF6700",
"S158" = "#A6A6A6",
"S158" = "#F8D568",
"S159" = "#FFAFC5",
"S149" = "#91D2F1"
)数据读取
R
# 读取Seurat对象和元数据
seurat.obj <- readRDS("data/AY1739512568405/input.rds")
meta <- read.table("data/AY1739512568405/meta.tsv", header=T, sep="\t", row.names = 1)
# 将元数据添加到Seurat对象
obj <- AddMetaData(seurat.obj, meta)
# 设置默认分析数据为RNA
DefaultAssay(obj) = "RNA"
# 查看元数据的前几行
head(obj@meta.data)| orig.ident | nCount_RNA | nFeature_RNA | Sample | mito | raw_Sample | Tissue | Patient | resolution.0.6_d20 | mitorelatedgenes | CellAnnotation | celltype | mergedcelltype | Oesophagus | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| <chr> | <int> | <int> | <chr> | <dbl> | <chr> | <chr> | <chr> | <int> | <dbl> | <chr> | <chr> | <chr> | <chr> | |
| AAACCTGAGATACACA-1_1 | SeuratProject | 2797 | 1425 | S150T | 4.2903 | GSE145370_S150T | Tumor | S150 | 1 | 3.3249911 | T_NK Cell | T cell | CD8_T | T or NK Cell |
| AAACCTGAGCTAACTC-1_1 | SeuratProject | 2790 | 1349 | S150T | 1.1470 | GSE145370_S150T | Tumor | S150 | 5 | 1.0035842 | Macrophage | Mono_Macro | Macrophage | Macrophage |
| AAACCTGAGGAGCGAG-1_1 | SeuratProject | 1768 | 1054 | S150T | 4.7511 | GSE145370_S150T | Tumor | S150 | 1 | 4.0158371 | T_NK Cell | T cell | CD8_T | T or NK Cell |
| AAACCTGAGGGAAACA-1_1 | SeuratProject | 4455 | 2017 | S150T | 2.2896 | GSE145370_S150T | Tumor | S150 | 8 | 1.8855219 | T_NK Cell | T cell | CD8_T | T or NK Cell |
| AAACCTGAGTCCCACG-1_1 | SeuratProject | 1422 | 861 | S150T | 0.9845 | GSE145370_S150T | Tumor | S150 | 1 | 0.7032349 | T_NK Cell | T cell | CD8_T | T or NK Cell |
| AAACCTGAGTGAACAT-1_1 | SeuratProject | 2522 | 1308 | S150T | 1.7843 | GSE145370_S150T | Tumor | S150 | 4 | 1.5463918 | T_NK Cell | T cell | Treg | T or NK Cell |
数据筛选
R
# 查看数据中的唯一值
unique(obj@meta.data$Tissue) # 查看治疗分组
unique(obj@meta.data$Patient) # 查看病人分组
unique(obj@meta.data$celltype) # 查看细胞类型
unique(obj@meta.data$Sample) # 查看样本ID- 'Tumor'
- 'Adjacent'
- 'S150'
- 'S133'
- 'S134'
- 'S135'
- 'S158'
- 'S159'
- 'S149'
- 'T cell'
- 'Mono_Macro'
- 'NK'
- 'mDC'
- 'Plasma'
- 'Other'
- 'Mast'
- 'B cell'
- 'pDC'
- 'S150T'
- 'S133T'
- 'S134T'
- 'S135T'
- 'S158T'
- 'S159T'
- 'S149T'
- 'S150A'
- 'S133A'
- 'S134A'
- 'S135A'
- 'S158A'
- 'S159A'
- 'S149A'
R
## t-SNE 可视化- 'T cell'
- 'Mono_Macro'
- 'NK'
- 'mDC'
- 'Plasma'
- 'Mast'
- 'B cell'
- 'pDC'
t-SNE 可视化
R
###################
# 绘制常规tSNE图 #
###################
# 设置图形大小
options(repr.plot.height=8, repr.plot.width=8)
# 创建基础tSNE图
p1 <- DimPlot(obj,
reduction = "tsne", # 使用tSNE降维结果
cols = celltype_colors, # 使用预定义的颜色方案
label = T, # 显示标签
label.size = 4, # 标签大小
pt.size = 2.0, # 点的大小
group.by = "celltype") # 按细胞类型分组
# 移除图例
p1 <- p1 + guides(color = FALSE)
p1output
Rasterizing points since number of points exceeds 100,000.
To disable this behavior set \`raster=FALSE\`
Warning message:
“The scale argument of \`guides()\` cannot be \`FALSE\`. Use "none" instead as
of ggplot2 3.3.4.”
To disable this behavior set \`raster=FALSE\`
Warning message:
“The scale argument of \`guides()\` cannot be \`FALSE\`. Use "none" instead as
of ggplot2 3.3.4.”

R
###################
# 绘制改进版tSNE图 #
###################
# 设置图形大小
options(repr.plot.height=8, repr.plot.width=8)
# 获取tSNE坐标范围
tsne_coords <- FetchData(obj, vars = c("tSNE_1", "tSNE_2"))
x_range <- range(tsne_coords$tSNE_1)
y_range <- range(tsne_coords$tSNE_2)
# 计算轴线的起点和终点位置
x_start <- x_range[1] * 1.1 # x轴起点,向左延伸10%
x_end <- x_range[2] * 0.001 # x轴终点
y_start <- y_range[1] * 1.1 # y轴起点,向下延伸10%
y_end <- y_range[2] * 0.001 # y轴终点
# 计算轴标签的位置
x_middle <- (x_start + x_end) / 2 # x轴标签位置
y_middle <- (y_start + y_end) / 2 # y轴标签位置
# 创建改进版tSNE图
p1_new <- DimPlot(obj,
reduction = "tsne",
cols = celltype_colors,
label = TRUE,
label.size = 4,
pt.size = 2.0,
group.by = "celltype") +
guides(color = FALSE) + # 移除图例
labs(title = "celltype") + # 添加标题
theme_classic() + # 使用经典主题
# 自定义主题设置
theme(
axis.line = element_blank(), # 移除坐标轴线
axis.text = element_blank(), # 移除坐标轴文本
axis.ticks = element_blank(), # 移除刻度线
axis.title = element_blank(), # 移除坐标轴标题
plot.title = element_text(size = 14, # 设置标题样式
hjust = 0.5,
vjust = 1),
panel.background = element_blank(), # 移除面板背景
plot.background = element_blank() # 移除图形背景
) +
# 添加x轴线和箭头
annotate("segment",
x = x_start,
xend = x_end,
y = y_start,
yend = y_start,
arrow = arrow(length = unit(0.3, "cm")),
color = "black") +
# 添加y轴线和箭头
annotate("segment",
x = x_start,
xend = x_start,
y = y_start,
yend = y_end,
arrow = arrow(length = unit(0.3, "cm")),
color = "black") +
# 添加x轴标签
annotate("text",
x = x_middle,
y = y_start - 2,
label = "tSNE_1",
size = 4) +
# 添加y轴标签
annotate("text",
x = x_start - 3,
y = y_middle,
label = "tSNE_2",
angle = 0,
size = 4)
p1_newoutput
Rasterizing points since number of points exceeds 100,000.
To disable this behavior set \`raster=FALSE\`
To disable this behavior set \`raster=FALSE\`

细胞数量统计图
R
#############################
# 统计细胞数量并绘制柱状图 #
#############################
# 统计每个细胞类型在不同样本中的细胞数目
counts <- table(obj@meta.data$celltype, obj@meta.data$Patient)
counts_df <- as.data.frame(counts)
# 重命名列名
colnames(counts_df) <- c("celltype", "group", "Cell number")
# 查看数据结构
head(counts_df)
unique(counts_df$group)
unique(counts_df$celltype)| celltype | group | Cell number | |
|---|---|---|---|
| <fct> | <fct> | <int> | |
| 1 | B cell | S133 | 439 |
| 2 | Mast | S133 | 1001 |
| 3 | mDC | S133 | 1586 |
| 4 | Mono_Macro | S133 | 3712 |
| 5 | NK | S133 | 684 |
| 6 | pDC | S133 | 31 |
- S133
- S134
- S135
- S149
- S150
- S158
- S159
Levels:
- 'S133'
- 'S134'
- 'S135'
- 'S149'
- 'S150'
- 'S158'
- 'S159'
- B cell
- Mast
- mDC
- Mono_Macro
- NK
- pDC
- Plasma
- T cell
Levels:
- 'B cell'
- 'Mast'
- 'mDC'
- 'Mono_Macro'
- 'NK'
- 'pDC'
- 'Plasma'
- 'T cell'
R
# 设置图形大小
options(repr.plot.height=6, repr.plot.width=12)
# 创建第一版柱状图
p2 <- ggplot(counts_df, aes(x = celltype, y = `Cell number`, fill = group)) +
# 创建分组柱状图
geom_bar(stat = "identity", position = position_dodge(width = 0.9)) +
# 设置填充颜色和图例标签
scale_fill_manual(values = group_colors,
labels = c('S133','S134','S135','S149','S150','S158','S159'),
breaks = c('S133','S134','S135','S149','S150','S158','S159')) +
# 设置轴标签
labs(x = NULL, y = "Cell number", fill = "") +
theme_minimal() +
# 自定义主题设置
theme(
panel.grid = element_line(colour = "gray", size = 0.5), # 网格线设置
axis.text.x = element_text(color = "black", size = 14), # x轴文本
axis.text.y = element_text(color = "black", size = 14), # y轴文本
axis.title.x = element_text(color = "black", size = 18), # x轴标题
axis.title.y = element_text(color = "black", size = 18), # y轴标题
axis.ticks = element_line(color = "black", size = 0.5, lineend = "butt"), # 刻度线
axis.ticks.length = unit(0.25, "cm"), # 刻度线长度
legend.text = element_text(size = 12), # 图例文本
legend.title = element_text(size = 14) # 图例标题
) +
# 添加边框
geom_rect(xmin = 0.41, xmax = 8.6, ymin = -10, ymax = 10650,
fill = "transparent",
color = "black",
size = 0.3)
p2output
Warning message:
“The \`size\` argument of \`element_line()\` is deprecated as of ggplot2 3.4.0.
ℹ Please use the \`linewidth\` argument instead.”
Warning message:
“Using \`size\` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use \`linewidth\` instead.”
“The \`size\` argument of \`element_line()\` is deprecated as of ggplot2 3.4.0.
ℹ Please use the \`linewidth\` argument instead.”
Warning message:
“Using \`size\` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use \`linewidth\` instead.”

R
# 重新排序分组水平
counts_df$group <- factor(counts_df$group,
levels = c('S149','S134','S135','S133','S150','S158','S159'))
# 创建第二版柱状图(重新排序后)
options(repr.plot.height=6, repr.plot.width=12)
p2<-ggplot(counts_df, aes(x = celltype, y = `Cell number`, fill = group)) +
geom_bar(stat = "identity", position = position_dodge(width = 0.9)) +
scale_fill_manual(values = group_colors) +
labs(x = NULL, y = "Cell number", fill = "") +
theme_minimal() +
theme(
panel.grid = element_line(colour = "gray", size = 0.5),
axis.text.x = element_text(color = "black", size = 14),
axis.text.y = element_text(color = "black", size = 14),
axis.title.x = element_text(color = "black", size = 18),
axis.title.y = element_text(color = "black", size = 18),
axis.ticks = element_line(color = "black", size = 0.5, lineend = "butt"),
axis.ticks.length = unit(0.25, "cm"),
legend.text = element_text(size = 12),
legend.title = element_text(size = 14)
) +
geom_rect(xmin = 0.41, xmax = 8.6, ymin = -15, ymax = 10650,
fill = "transparent", # 填充为透明
color = "black", # 边框颜色设为黑色
size = 0.3) # 边框宽度设为1
p2
R
# 重新排序细胞类型
counts_df$celltype <- factor(counts_df$celltype,
levels = c('T cell','Mono_Macro','NK','mDC','Plasma','Mast','B cell','pDC'))
# 创建第三版柱状图(重新排序后)
options(repr.plot.height=6, repr.plot.width=12)
p2<-ggplot(counts_df, aes(x = celltype, y = `Cell number`, fill = group)) +
geom_bar(stat = "identity", position = position_dodge(width = 0.9)) +
scale_fill_manual(values = group_colors) +
labs(x = NULL, y = "Cell number", fill = "") +
theme_minimal() +
theme(
panel.grid = element_line(colour = "gray", size = 0.5),
axis.text.x = element_text(color = "black", size = 14),
axis.text.y = element_text(color = "black", size = 14),
axis.title.x = element_text(color = "black", size = 18),
axis.title.y = element_text(color = "black", size = 18),
axis.ticks = element_line(color = "black", size = 0.5, lineend = "butt"),
axis.ticks.length = unit(0.25, "cm"),
legend.text = element_text(size = 12),
legend.title = element_text(size = 14)
) +
geom_rect(xmin = 0.41, xmax = 8.6, ymin = -15, ymax = 10650,
fill = "transparent", # 填充为透明
color = "black", # 边框颜色设为黑色
size = 0.3) # 边框宽度设为1
p2
细胞比例堆叠图
R
## 细胞比例堆叠图| group | celltype | |
|---|---|---|
| <chr> | <chr> | |
| 1 | S150 | T cell |
| 2 | S150 | Mono_Macro |
| 3 | S150 | T cell |
| 4 | S150 | T cell |
| 5 | S150 | T cell |
| 6 | S150 | T cell |
- 'T cell'
- 'Mono_Macro'
- 'NK'
- 'mDC'
- 'Plasma'
- 'Mast'
- 'B cell'
- 'pDC'
- 'S150'
- 'S133'
- 'S134'
- 'S135'
- 'S158'
- 'S159'
- 'S149'
R
# 计算每个样本中不同细胞类型的占比
tbl <- celltype_group_df %>%
group_by(group, celltype) %>% # 按组和细胞类型分组
summarise(Count = n()) %>% # 计算每组细胞数
group_by(group) %>% # 按组分组
mutate(Percent = Count / sum(Count) * 100) # 计算百分比output
\`summarise()\` has grouped output by 'group'. You can override using the
\`.groups\` argument.
\`.groups\` argument.
R
# 绘制第一版堆叠柱状图
options(repr.plot.height=8, repr.plot.width=8)
p3 <- ggplot(tbl, aes(x = group, fill = celltype, y = Percent)) +
geom_bar(stat = "identity") + # 创建堆叠柱状图
theme_bw() + # 使用黑白主题
scale_fill_manual(values = celltype_colors) + # 使用预定义的颜色
xlab(NULL) + # 不显示x轴标题
ylab("Percent(%)") + # y轴标题
labs(fill = "celltype") + # 图例标题
# 自定义主题设置
theme(axis.text.x = element_text(color = "black", vjust = 1, hjust = 1, angle = 45),
panel.grid = element_blank(), # 移除网格线
legend.text = element_text(size = 12), # 图例文本大小
legend.title = element_text(size = 12), # 图例标题大小
axis.text = element_text(size = 14), # 轴文本大小
axis.title = element_text(size = 14)) # 轴标题大小
p3
R
# 重新排序分组水平
tbl$group <- factor(tbl$group,
levels = c('S149','S134','S135','S133','S150','S158','S159'))
# 绘制第二版堆叠柱状图(重新排序后)
options(repr.plot.height=8, repr.plot.width=8)
p3 <- ggplot(tbl, aes(x = group, fill = celltype, y = Percent)) +
geom_bar(stat = "identity") +
theme_bw() +
scale_fill_manual(values = celltype_colors) +
xlab(NULL) +
ylab("Percent(%)") +
labs(fill = "celltype") +
theme(axis.text.x = element_text(color = "black", vjust = 1, hjust = 1, angle = 45),
panel.grid = element_blank(),
legend.text = element_text(size = 12),
legend.title = element_text(size = 12),
axis.text = element_text(size = 14),
axis.title = element_text(size = 14))
p3
R
# 重新排序细胞类型
tbl$celltype <- factor(tbl$celltype,
levels = c('T cell','Mono_Macro','NK','mDC','Plasma','Mast','B cell','pDC'))
# 绘制第三版堆叠柱状图(重新排序后)
options(repr.plot.height=8, repr.plot.width=8)
p3 <- ggplot(tbl, aes(x = group, fill = celltype, y = Percent)) +
geom_bar(stat = "identity") +
theme_bw() +
scale_fill_manual(values = celltype_colors) +
xlab(NULL) +
ylab("Percent(%)") +
labs(fill = "celltype") +
theme(axis.text.x = element_text(color = "black", vjust = 1, hjust = 1, angle = 45),
panel.grid = element_blank(),
legend.text = element_text(size = 12),
legend.title = element_text(size = 12),
axis.text = element_text(size = 14),
axis.title = element_text(size = 14))
p3
R
###################
# 保存所有图形 #
###################
# 保存tSNE图
ggsave("tsne.pdf", plot = p1_new, width = 8, height = 8)
# 保存细胞数量柱状图
ggsave("cellnumber.pdf", plot = p2, width = 12, height = 6)
# 保存细胞比例堆叠图
ggsave("cellratio.pdf", plot = p3, width = 8, height = 8)