Skip to content

单细胞可视化定制:自定义颜色与顺序的 t-SNE 及比例图

作者: SeekGene
时长: 18 分钟
字数: 3.8k 字
更新: 2026-02-27
阅读: 0 次
3' 转录组 5' + 免疫组库 ATAC + RNA 双组学 FFPE 单细胞转录组 Notebooks 全序列转录组 甲基化 + RNA 双组学 空间转录组 细胞注释

环境配置

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)
A data.frame: 6 × 14
orig.identnCount_RNAnFeature_RNASamplemitoraw_SampleTissuePatientresolution.0.6_d20mitorelatedgenesCellAnnotationcelltypemergedcelltypeOesophagus
<chr><int><int><chr><dbl><chr><chr><chr><int><dbl><chr><chr><chr><chr>
AAACCTGAGATACACA-1_1SeuratProject27971425S150T4.2903GSE145370_S150TTumorS15013.3249911T_NK Cell T cell CD8_T T or NK Cell
AAACCTGAGCTAACTC-1_1SeuratProject27901349S150T1.1470GSE145370_S150TTumorS15051.0035842MacrophageMono_MacroMacrophageMacrophage
AAACCTGAGGAGCGAG-1_1SeuratProject17681054S150T4.7511GSE145370_S150TTumorS15014.0158371T_NK Cell T cell CD8_T T or NK Cell
AAACCTGAGGGAAACA-1_1SeuratProject44552017S150T2.2896GSE145370_S150TTumorS15081.8855219T_NK Cell T cell CD8_T T or NK Cell
AAACCTGAGTCCCACG-1_1SeuratProject1422 861S150T0.9845GSE145370_S150TTumorS15010.7032349T_NK Cell T cell CD8_T T or NK Cell
AAACCTGAGTGAACAT-1_1SeuratProject25221308S150T1.7843GSE145370_S150TTumorS15041.5463918T_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
  1. 'Tumor'
  2. 'Adjacent'
  1. 'S150'
  2. 'S133'
  3. 'S134'
  4. 'S135'
  5. 'S158'
  6. 'S159'
  7. 'S149'
  1. 'T cell'
  2. 'Mono_Macro'
  3. 'NK'
  4. 'mDC'
  5. 'Plasma'
  6. 'Other'
  7. 'Mast'
  8. 'B cell'
  9. 'pDC'
  1. 'S150T'
  2. 'S133T'
  3. 'S134T'
  4. 'S135T'
  5. 'S158T'
  6. 'S159T'
  7. 'S149T'
  8. 'S150A'
  9. 'S133A'
  10. 'S134A'
  11. 'S135A'
  12. 'S158A'
  13. 'S159A'
  14. 'S149A'
R
## t-SNE 可视化
  1. 'T cell'
  2. 'Mono_Macro'
  3. 'NK'
  4. 'mDC'
  5. 'Plasma'
  6. 'Mast'
  7. 'B cell'
  8. '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) 
p1
output
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.”
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_new
output
Rasterizing points since number of points exceeds 100,000.
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)
A data.frame: 6 × 3
celltypegroupCell number
<fct><fct><int>
1B cell S133 439
2Mast S1331001
3mDC S1331586
4Mono_MacroS1333712
5NK S133 684
6pDC S133 31
  1. S133
  2. S134
  3. S135
  4. S149
  5. S150
  6. S158
  7. S159
Levels:
  1. 'S133'
  2. 'S134'
  3. 'S135'
  4. 'S149'
  5. 'S150'
  6. 'S158'
  7. 'S159'
  1. B cell
  2. Mast
  3. mDC
  4. Mono_Macro
  5. NK
  6. pDC
  7. Plasma
  8. T cell
Levels:
  1. 'B cell'
  2. 'Mast'
  3. 'mDC'
  4. 'Mono_Macro'
  5. 'NK'
  6. 'pDC'
  7. 'Plasma'
  8. '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)              
p2
output
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.”
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
## 细胞比例堆叠图
A data.frame: 6 × 2
groupcelltype
<chr><chr>
1S150T cell
2S150Mono_Macro
3S150T cell
4S150T cell
5S150T cell
6S150T cell
  1. 'T cell'
  2. 'Mono_Macro'
  3. 'NK'
  4. 'mDC'
  5. 'Plasma'
  6. 'Mast'
  7. 'B cell'
  8. 'pDC'
  1. 'S150'
  2. 'S133'
  3. 'S134'
  4. 'S135'
  5. 'S158'
  6. 'S159'
  7. '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.
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)
0 条评论·0 条回复