# bulk RNAseq可视化

图表可以从分布、联系、比较、构成4个方面对图表进行分类和选择。

<figure><img src="https://3583750438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrNJkPTdpyVMk09ldgu9A%2Fuploads%2Fx565LsJq8DBjvYuxOcVm%2Fimage.png?alt=media&#x26;token=b05c3413-4bb1-4678-a4a0-77448c83b17a" alt="" width="563"><figcaption></figcaption></figure>

## 1、展示样本分布与关联

### PCA

{% embed url="<https://mp.weixin.qq.com/s/kOpEVIxThhmTEogM89OGLg>" %}

<https://mp.weixin.qq.com/s/KmRdIBEFH6Tw-Gm7CMXZ_Q>

### 相关性热图

### 甜甜圈图 <a href="#activity-name" id="activity-name"></a>

```
// R

#https://mp.weixin.qq.com/s/-c4nP0xeCisOkUv_Oe4ijQ
```

## 2、展示差异基因分布

### 火山图

<figure><img src="https://3583750438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrNJkPTdpyVMk09ldgu9A%2Fuploads%2Fqm4HaemSrqv3hjXLtR8g%2Fimage.png?alt=media&#x26;token=e7669ad7-c6f6-40ce-add3-5f8950e38336" alt="" width="339"><figcaption><p>Fig4F. Multi-omic profiling reveals age-related immune dynamics in healthy adults</p></figcaption></figure>

```
// R

#在DESeq2差异分析基础上

library(tidyverse)
library(ggrepel)
library(ggtern)
library(ggtext)

df1 <- DEG_DESeq2

# ① 把行名变成一列：gene
df1$gene <- rownames(df1)

# ② 计算 -log10(pvalue)
df1$neg_log10_pvalue <- -log10(df1$pvalue)

# ③ 根据你的阈值生成 regulation 分组
# 你可以根据自己的实验阈值修改
df1$regulation <- dplyr::case_when(
  df1$padj < 0.05 & df1$log2FoldChange > 1 ~ "Up in CSF",
  df1$padj < 0.05 & df1$log2FoldChange < -1 ~ "Up in Control",
  #df1$padj >= 0.05 & df1$log2FoldChange > 0 ~ "Nominal Up in CSF",
  #df1$padj >= 0.05 & df1$log2FoldChange < 0 ~ "Nominal Up in Control",
  TRUE ~ "Not significant"
)

# 最终数据 df1 就可以直接用于你的火山图代码
head(df1)

# 筛选出所需展示的基因
genes_to_label <- c(
  "Ccl3", "Ccr3", "Cxcl10", "Il27", 
  "Trpv6", "Wnt16", "Krt78")

# 绘图
ggplot(data = df1, aes(x = log2FoldChange, y = neg_log10_pvalue)) +
  geom_point(aes(color = regulation),
             stroke = 0, alpha = 0.7, size = 2) +
  geom_hline(yintercept = -log10(0.05),
             linetype = "dashed", color = "black") +
  
  # 给筛选出的基因加上黑色边框点
  geom_point(data = subset(df1, gene %in% genes_to_label),
             aes(x = log2FoldChange, y = neg_log10_pvalue),
             color = "black", fill = NA, shape = 21, size = 2) +
  
  # 添加文本
  geom_text_repel(data = subset(df1, gene %in% genes_to_label),
                  aes(label = gene), size = 3, max.overlaps = Inf) +
  
  # 添加注释线段
  annotate("segment", x = -0.5, xend = 0.5, y = 15, yend = 15,
           linewidth = 0.2, color = "black",
           arrow = arrow(ends = "both", type = "closed",
                         length = unit(0.25, "cm"))) +
  annotate("text", x = -0.6, y = 16, label = "Up in Control",
           size = 3, color = "black") +
  annotate("text", x = 0.6, y = 16, label = "Up in CSF",
           size = 3, color = "black") +
  
  scale_color_manual(values = c(
    "Up in CSF" = "#b8124d",
    "Up in Control" = "#35978f",
    #"Nominal Up in CSF" = "#F3E4CD",
    #"Nominal Up in Control" = "#C3EAE7",
    "Not significant" = "gray"
  )) +
  
  scale_x_continuous(limits = c(-3, 3)) +
  labs(title = "CSF- Control", x = "Log2 Fold Change",
       y = "-Log10 (adj.P-value)", color = "Legend") +
  theme_classic() +
  theme(panel.grid = element_blank(),
        plot.title = element_text(
          vjust = 0.5, hjust = 0.5, size = 10, color = "black"),
        legend.position = "none")
```

### MA plot

MA-plot，即M-versus-A plot，也称为 Bland-Altman plot，主要应用在数据分布情况的可视化，比如突出显示差异表达基因和/或其他基因类别，例如管家基因、高可变基因。该图将数据转换为M（对数比）和A（平均值），然后绘制这些值来可视化两个样本中测量值之间的差异。M常对应差异表达分析获得的<mark style="color:red;">差异对比组之间基因表达变化log2FC</mark>。A对应实验组与对照组的<mark style="color:red;">平均标化表达量（mean normalized count）</mark>，可以利用差异对比组的CPM、TPM、FPKM进行计算。当一个点的X轴数值很大，Y轴绝对值也很大的时候，就说明它是平均表达量高，组间差别还很大的基因。由于大部分Y轴绝对值大的点其实会集中在X轴数值居中的部位，所以大部分MA plot是沿X轴流线型或三角形的。

此外，MA plot可以直观展示数据测序质量。比如，如果大部分点的X轴数值都接近于0，说明基因表达量普遍偏低，可能测序深度不够，或者文库质量不好。另一方面，在RNA-seq数据的分析中，不仅需要进行标准化，还需要通过算法对数据进行降噪校正，去掉干扰信号。校正后的数据，其组间差异总体上应该较为平均地分布在Y=0两侧，也就是说，所有的点整体上看起来水平悬浮。但是，如果结果显示出这些点整体跑偏，中线严重偏离了Y=0，甚至形成了弧形，则说明校正方法可能不太适宜。

<figure><img src="https://3583750438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrNJkPTdpyVMk09ldgu9A%2Fuploads%2FLFYh9kH4khZRnZJntI2d%2Fimage.png?alt=media&#x26;token=5529a783-ddf7-4ebd-b4b8-ebe9bcfc57f8" alt="" width="375"><figcaption><p>De novo gene synthesis by an antiviral reverse transcriptase. Fig1B</p></figcaption></figure>

```
// R

#https://mp.weixin.qq.com/s/jScnUOAMZ6zopFQihyiG_Q


#在DESeq2差异分析基础上

df <- DEG_DESeq2

#阈值确定：
pvalue = 0.05
log2FC = 1

#添加上下调分组标签：
df$group <- case_when(
  df$log2FoldChange > log2FC & df$pvalue < pvalue ~ 'up',
  df$log2FoldChange < -log2FC & df$pvalue < pvalue ~ 'down',
  TRUE ~ 'none'
)
table(df$group)

#转换为因子，指定绘图顺序；
df$group <- factor(df$group, levels = c('up','none','down'))

#在excel中利用FPKM矩阵计算标化值（FPKM）的平均表达量：
#读入
FPKM <- read.csv("./result/1.3.gene_expression/FPKM.csv",header = T,row.names = 1,check.names=F)

#在df中新建两列，将行名对应的FPKM的矩阵中的mean的值添加：
df$mean_FPKM <- FPKM[rownames(df),]$mean

#也可以是用deseq2标准化的值计算平均值：
#提取标化后的dds矩阵
normalized_counts <- as.data.frame(counts(dds_2, normalized=TRUE))
#计算平均值
normalized_counts$mean <- rowMeans(normalized_counts)
#将平均值添加到df中：
df$mean_dds <- normalized_counts[rownames(df),]$mean



### MA Plot ####
library(ggplot2)
library(ggrepel)
library(dplyr)
library(patchwork)

#新建横纵坐标列：
df$A <- df$mean_dds
#或
df$A <- df$mean_FPKM

df$M <- df$log2FoldChange

#ggplot2绘图：
#自定义颜色：
mycol <- c("#EB4232","grey90","#2DB2EB")

#自定义主题：
mytheme <- theme_classic() +
  theme(plot.title = element_text(size = 17),
        axis.title = element_text(size = 15),
        axis.text = element_text(size = 14),
        legend.text = element_text(size = 14),
        plot.margin = margin(15,5.5,5.5,5.5))

#MA图绘制：

##注意图层叠加顺序
p1 <- ggplot() + 
  geom_point(data = df[df$group=='none',],
             aes(x = A, y = M, color = group)) + 
  geom_point(data = df[df$group=='up',],
             aes(x = A, y = M, color = group)) +
  geom_point(data = df[df$group=='down',],
             aes(x = A, y = M, color = group)) +
  scale_colour_manual(name = '', values = rev(alpha(mycol, 0.7))) + 
  scale_x_continuous(trans = 'log10', name = 'Mean normalized count') +  # 将横坐标转换为log10并修改名称
  scale_y_continuous(name = "Log2(Fold Change)") +  # 修改纵坐标名称
  geom_hline(yintercept = 0, size = 0.5, color = "black", lty = 'dashed') + 
  labs(title = 'MA_Plot') +
  mytheme+
  theme(
    axis.text = element_text(color = 'black'),  # 修改坐标轴刻度字体颜色为黑色
    axis.title = element_text(color = 'black')  # 修改坐标轴标题字体颜色为黑色
  )+
  geom_text_repel(
    data = df[rownames(df) %in% c('HPD','SERPING1', 'GAPDH'), ],
    aes(x = A, y = M, label = rownames(df)[rownames(df) %in% c('HPD','SERPING1', 'GAPDH')]),
    color = 'red',
    size = 4,
    fontface = 'bold',
    segment.color = 'black',  # 连线颜色
    segment.size = 0.5,        # 连线粗细
    force = 0.5,                           # 强制推开标签
    nudge_y = 0.5                        # 向上微调标签，确保连线清晰可见
  )
p1

```

### 瀑布图（Waterfall plot / Rank plot）

<figure><img src="https://3583750438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrNJkPTdpyVMk09ldgu9A%2Fuploads%2FTklHl0qavg14mPDRDW0t%2Fimage.png?alt=media&#x26;token=a4704c4c-b514-4097-8153-f47db8973837" alt="" width="362"><figcaption><p>METTL17 is an Fe-S cluster checkpoint for mitochondrial translation. Fig1B/D</p></figcaption></figure>

```
// R

#https://mp.weixin.qq.com/s/FPGeRtuPxEFU7XZNYJ1okA

# 数据准备：需要基因名、logFC、分组组名、rank值，前两者与GSEA所需数据一样
#从差异基因列表导入基因（deseq2）

data <- DEG_DESeq2
data$gene_name <- rownames(data)
data$logFC <- data$log2FoldChange
data <- data[,-c(1:6)]
data <- arrange(data,desc(logFC)) #按照LogFC降序排列
#降序和升序决定了waterfall plot的方向


#指定分组
#data$group <- ifelse(data$logFC > 0,'Up','Down')
selected <- data[1:10,] #例如，选择前10个基因

#指定分组以及添加label
data %>% 
  mutate(group = case_when(
    gene_name %in% selected$gene_name~'selected',
    T~'other'
  ),
  label = case_when(
    gene_name == 'HPD'~gene_name,
    T~''
  ))->data

#添加rank列
data$rank = 1:nrow(data)

#绘制waterfall plot

#数据分隔
data_selected <- data %>% filter(group == "selected") 
data_other <- data %>% filter(group != "selected") 

# 主题设置
plot.format <- theme(
  plot.background = element_blank(),
  panel.grid = element_blank(),
  panel.background = element_blank(),
  panel.border = element_blank(),
  axis.line.x.top = element_blank(),
  axis.line.y.right = element_blank(),
  axis.line = element_line(color = "black"),
  axis.ticks = element_line(color = "black", linewidth = 0.5),
  axis.text = element_text(color = "black", size = 14),
  axis.title = element_text(color = "black", size = 14),
  plot.title = element_text(color = "black", size = 14),
  legend.background = element_blank(),
  legend.key = element_blank(),
  legend.text = element_text(color = "black", size = 14),
  legend.title = element_text(color = "black", size = 14)
)

# 画图
p = ggplot() +
  geom_hline(yintercept = 0, lty = 4, col = 'black', lwd = 0.2) +#加上0的虚线
  geom_point(data = data_other, 
             aes(x = rank, y = logFC, fill = group, color = group), 
             size = 2, shape = 21, alpha = 0.75) +#先画other
  geom_point(data = data_selected, 
             aes(x = rank, y = logFC, fill = group, color = group), 
             size = 2, shape = 21, alpha = 0.75) +#再画selected
  geom_text_repel(data = data, aes(x = rank, y = logFC, label = label), size = 4,
                  box.padding = unit(0.2, 'lines'), 
                  point.padding = unit(0.3, 'lines'), 
                  show.legend = FALSE,
                  max.overlaps = Inf) +#加上标签
  scale_fill_manual(values = c('#7D7B82','#5872D0' )) +#自定义颜色
  scale_color_manual(values = c('#7D7B82','#5872D0' )) +#自定义颜色
  labs(x = 'Rank', y = 'log2Foldchange(XX/Normal)') +#坐标轴的标签
  guides(fill = guide_legend(title = NULL), color = guide_legend(title = NULL)) +
  plot.format#自定义主题
p

#加上p value，见下文
#https://mp.weixin.qq.com/s/lwr1QwqM0KpL0WwfNVd6ug

```

### 散点图

```
// R

#https://mp.weixin.qq.com/s/1g26mRRNBTUHFb75lWRMOw




```

## 3、展示单个或多个基因表达变化

### 热图（标记差异基因+行列注释）

<div align="center"><figure><img src="https://3583750438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrNJkPTdpyVMk09ldgu9A%2Fuploads%2FTgla3ZOAlzMM85058UlA%2Fimage.png?alt=media&#x26;token=929107e9-d628-4f0a-9474-2c9935994067" alt="" width="163"><figcaption><p>The local microenvironment drives activation of neutrophils in human brain tumors. Fig3G</p></figcaption></figure></div>

```
// R

#https://mp.weixin.qq.com/s/R6N6rkAqUsIv79w6Lnt8PQ

#导入R包
library(ComplexHeatmap)

#读取数据 因为样本名有空格、中划线这种特殊字符，所以加了check.names = FALSE这个参数
df <- read.delim("./CD8_EOS_heatmap.txt", row.names = 1, check.names = FALSE)

#ComplexHeatmap没法均一化，所以先用scale进行均一化
df1 <- t(scale(t(df)))

#准备左侧注释色块---准备行注释信息，即基因分类注释
left_group <- c(rep("CD8T",19) ,rep("Eos",19))
left_color <- c(rep("#f9a025",19) ,rep("#94ce91",19))
names(left_color) <- left_group

#准备上方注释色块---准备列注释信息，即样本分组
top_group <- c(rep("Normal",3) ,rep("Colitis",3))
top_color <- c("#c2c3c3","#d3e6f4", "#125ba5", "#c2c3c3","#d3e6f4", "#125ba5")
names(top_color) <- colnames(df1)


#绘图
#col = colorRampPalette(c('#093263', '#f4f5f4', '#650122'))(100)
p <- Heatmap(df1,
             col = colorRampPalette(c("#2166AC", "#f7f7f7", "#B2182B"))(100), 
             show_row_names = T, #展示基因名称
             show_column_names = F,   #不展示样本名称
             cluster_rows = F,  #行不聚类
             cluster_columns = F,  #列不聚类
             column_split = top_group,  # 列分割，一般是样本分组
             row_split = left_group, # 行分割，一般是基因功能分类
             column_gap= unit(3, "mm"), #列分割间的空白宽度
             row_gap= unit(3, "mm"), #行分割间的空白宽度
             rect_gp= gpar(col = "white", lwd = 1.5),  #rect_gp 热图小格子的设置参数，gpar 对象，可设置热图格子的边框颜色（col）、线宽（lwd）和线型（lty）等属性。
             show_heatmap_legend = T, #展示图例
             name = " ", #图例名会默认成matrix_no.,这里不展示
             left_annotation = rowAnnotation(  #left_annotation左侧注释色块开始设置啦
               mark_left = left_group,
               col = list(mark_left = left_color), #左侧注释色块
               show_annotation_name = FALSE,
               annotation_legend_param = list(Group = left_group,title = "Cell marker"),
               gp = gpar(col = "white", lwd = 2)),
             top_annotation = HeatmapAnnotation(  #top_annotation上方注释色块开始设置啦
               mark_top = colnames(df1),
               show_annotation_name = FALSE,
               col = list(mark_top = top_color), #上方注释色块
               gp= gpar(col = "white", lwd = 2),
               annotation_legend_param = list(Group = top_group,title = "Tissue/cell type")),
             heatmap_legend_param = list(title = "Z-score"))    #设置热图数值的图例
p
```

### 配对热图（展示基因或富集分数）

<figure><img src="https://3583750438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrNJkPTdpyVMk09ldgu9A%2Fuploads%2FDt77R4qWlKcBQkwC4ssV%2Fimage.png?alt=media&#x26;token=9d1e4319-9f2f-4344-b736-d968173dd1c4" alt=""><figcaption></figcaption></figure>

分组数据格式如上图。表达矩阵列为样本名，行为基因/细胞/通路名。

```
// R

data <- read.csv("./tme_ssgsea_6.csv",header = T,row.names = 1) #记得删除第一列，然后把顺序改成N1\C1\N2\C2
test <- read.csv("./tme_ssgsea_group_6.csv",header = T)

library(dplyr)
col=(arrange(test,pairinfo,group_list))$gsm
od=match(col,colnames(data))
cg=c(names(data))
  
#数据准备好了就阔以画了
n=t(as.matrix(data))

annotation_col=test[,2:3]
rownames(annotation_col)=colnames(n)

pheatmap(n,show_colnames=T,
         show_rownames=T,
         scale="row",
         cluster_cols=F,
         annotation_col=annotation_col,
         gaps_col=c(2,4)) #配对之间添加空格

```

### 无监督聚类热图+各cluster富集分析

<figure><img src="https://3583750438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrNJkPTdpyVMk09ldgu9A%2Fuploads%2Fv0HXdK7R0lC8XBytqMaG%2Fimage.png?alt=media&#x26;token=7fbc391f-a3f1-46d7-82c3-18b76bbf927e" alt="" width="375"><figcaption><p>Fig3. Enteric bacterial infection stimulates remodelling of bile metabolites to promote intestinal homeostasis</p></figcaption></figure>

```
// R
library(tidyverse)
library(DESeq2)
library(cluster)
library(ggh4x)

vsd <- vst(dds, blind = FALSE)

# 1. vsd to dataframe
mat <- assay(vsd) %>% 
  as.data.frame() %>% 
  rownames_to_column(var="gene")

# 2. significant DEGs
DEG_DESeq2$gene <- row.names(DEG_DESeq2)
sig_genes <- DEG_DESeq2 %>% 
  filter(pvalue < 0.05, abs(log2FoldChange) > 1) %>%
  pull(gene)

# 3. subset matrix
mat <- mat %>% 
  filter(gene %in% sig_genes) %>% 
  column_to_rownames(var="gene")

heatmap <- as.data.frame(t(scale(t(mat))))

pam_res <- pam(heatmap, k = 5)
clusters <- pam_res$clustering
# 构建分面条第颜色
strips <- strip_themed(
  background_y = elem_list_rect(
    fill=c("1"="#171236","2"="#5ca0bc","3"="#fcc103",#aca47c,#685704
           "4"="#36998d","5"="#a661ff")),
  background_x = elem_list_rect(fill=c("ctrl"="#125ed8","pos"="#02935f")))

heatmap %>% rownames_to_column("gene_id") %>% 
  mutate(cluster = factor(clusters[gene_id], levels = sort(unique(clusters)))) %>% 
  pivot_longer(cols = -c(gene_id, cluster),
               names_to = "sample", values_to = "value") %>% 
  mutate(group = sub(".*_(.*)[0-9]+$", "\\1", sample)) %>% 
  arrange(group, sample) %>%                        
  mutate(sample = factor(sample, levels = unique(sample)))%>%
  ggplot(aes(sample,gene_id,fill=value)) +
  geom_tile() +
  facet_grid2(cluster~group,scale="free",strip=strips,switch="y")+
  force_panelsizes(rows=table(clusters),respect=F) +
  scale_fill_gradientn(colours = rev(RColorBrewer::brewer.pal(11,"RdBu")),
                       breaks=c(seq(-2,2,by=0.5)))+
  scale_x_discrete(expand = c(0,0)) +
  labs(fill="Z score") +
  guides(fill = guide_colorbar(
    barwidth = unit(0.6,"cm"),    # 调整条宽度
    barheight = unit(5,"cm"),     # 调整条高度
    direction = "vertical"        # 纵向图例
  )) +
  theme(axis.text.y=element_blank(),
        axis.text.x=element_text(color="black",angle = 90,vjust=0.5),
        axis.ticks = element_blank(),
        axis.title=element_blank(),
        strip.text = element_text(color="white",face="bold"),
        panel.spacing.y = unit(0.01,"cm"),
        panel.spacing.x = unit(0.02,"cm"),
        legend.position = "right",      # 放在右侧
        legend.box = "vertical",
        legend.background = element_blank(),
        legend.text = element_text(color="black"),
        legend.key.height = unit(1,"null"))+ scale_fill_gradientn(
          colours = rev(RColorBrewer::brewer.pal(11,"RdBu")),
          breaks = seq(-4,4,1),
          name = "Z score"
        )
#8*8


#导出每个cluster的基因
library(dplyr)

cluster_df <- data.frame(
  gene = names(clusters),
  cluster = clusters
)

# 导出各个cluster的基因
cluster_df %>%
  group_by(cluster) %>%
  summarise(genes = paste(gene, collapse = ",")) %>%
  write.csv("./clusters_all_genes.csv", row.names = FALSE, quote = FALSE)

# 分别KEGG富集分析
library(clusterProfiler)
library(org.Mm.eg.db)  # 小鼠基因注释数据库
library(dplyr)
library(ggplot2)
library(tidyr)

# 1. cluster 数据框
cluster_df <- data.frame(
  gene = names(clusters),
  cluster = clusters,
  stringsAsFactors = FALSE
)

# 2. gene symbol 转 EntrezID
gene2entrez <- bitr(cluster_df$gene, fromType="SYMBOL",
                    toType="ENTREZID", OrgDb=org.Mm.eg.db)
cluster_df <- cluster_df %>%
  left_join(gene2entrez, by = c("gene" = "SYMBOL"))

# 3. KEGG 富集分析，每个 cluster 前10条
kegg_list <- list()
for(cl in sort(unique(cluster_df$cluster))) {
  genes_entrez <- cluster_df %>% 
    filter(cluster == cl) %>% 
    pull(ENTREZID) %>% na.omit()
  
  if(length(genes_entrez) > 0){
    kegg_res <- enrichKEGG(
      gene = genes_entrez,
      organism = 'mmu',
      pAdjustMethod = "BH",
      qvalueCutoff = 0.05
    )
    
    if(!is.null(kegg_res) && nrow(kegg_res) > 0){
      df <- as.data.frame(kegg_res)
      df$cluster <- cl
      # 按 p.adjust 排序并取前10
      df <- df %>% arrange(p.adjust) %>% head(10)
      # 去掉通路名后缀
      df$Description <- str_replace(df$Description, " - Mus.*$", "")
      kegg_list[[as.character(cl)]] <- df
    }
  }
}

# 4. 合并所有 cluster
kegg_all <- bind_rows(kegg_list)

# 5. 计算 gene ratio 数值
kegg_all <- kegg_all %>%
  mutate(GeneRatioNum = as.numeric(sapply(strsplit(GeneRatio, "/"), 
                                          function(x) as.numeric(x[1])/as.numeric(x[2]))))

# 6. pathway 纵轴顺序，按照 cluster1→cluster5 出现顺序
pathway_order <- kegg_all %>%
  arrange(cluster) %>%
  distinct(Description) %>%
  pull(Description)

kegg_all$Description <- factor(kegg_all$Description, levels = rev(pathway_order)) # 纵轴从上到下


# 7. 绘制气泡图
blue_white <- brewer.pal(11, "RdBu")[6:11]  # 前6个颜色：深蓝→白

ggplot(kegg_all, aes(x = factor(cluster), y = Description)) +
  geom_point(aes(size = GeneRatioNum, color = -log10(p.adjust))) +
  scale_size_continuous(range = c(3, 10)) +
  scale_color_gradientn(
    colors = rev(blue_white),                        # 蓝到白
    limits = c(0, max(-log10(kegg_all$p.adjust))),
    name = "-log10(adj.P)"
  ) +
  theme_bw() +
  labs(
    x = "Cluster",
    y = "KEGG Pathway",
    size = "Gene Ratio"
  ) +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1),
    axis.text.y = element_text(size = 10),
    panel.grid = element_blank(),
    legend.key.height = unit(1.2, "cm"),
    legend.key.width = unit(0.6, "cm")
  )
#10*10

```

### 基因表达趋势图

<figure><img src="https://3583750438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrNJkPTdpyVMk09ldgu9A%2Fuploads%2FV6ihDwvJgCwzjd7kBabg%2Fimage.png?alt=media&#x26;token=21ec0cf2-a158-450c-861e-789789549bab" alt="" width="375"><figcaption><p>Identification of markers correlating with mitochondrial function in myocardial infarction by bioinformatics</p></figcaption></figure>

```
// R

#https://mp.weixin.qq.com/s/POffKJTjY6sxBZ4Fq2erEg
##输入数据：示例里每个组有3个生物学重复。每组取的均值作为这个基因在这个组的表达量。

library(ClusterGVis)
library(org.Mm.eg.db)  # 小鼠注释数据库

#-----------------------------------------
# 1. 读取数据
#-----------------------------------------
df <- read.delim("2.txt", sep = "\t", row.names = 1, check.names = FALSE)

#-----------------------------------------
# 2. bulk RNA-seq：组内取平均表达
#-----------------------------------------
df1 <- data.frame(
  Ctrl = rowMeans(df[, 1:3]),
  T1h  = rowMeans(df[, 4:6]),
  T6h  = rowMeans(df[, 7:9]),
  T12h = rowMeans(df[, 10:12]),
  T24h = rowMeans(df[, 13:15]),
  T36h = rowMeans(df[, 16:18])
)

#-----------------------------------------
# 3. 聚类（Fuzzy C-Means）
#-----------------------------------------
df_clu <- clusterData(df1,
                      cluster.method = "mfuzz",
                      cluster.num = 6)

#-----------------------------------------
# 4. cluster GO 注释 
#    fromType=ENSEMBL → 必须保证 rownames(df1) 是 ENSEMBL ID
#-----------------------------------------
anno <- enrichCluster(
  object = df_clu,
  OrgDb = org.Mm.eg.db,
  type = "BP",
  fromType = "ENSEMBL",
  organism = "mmu",
  pvalueCutoff = 0.5,
  topn = 4
)

#-----------------------------------------
# 5. 绘图
#-----------------------------------------
pdf("2.pdf", height = 10, width = 12)

visCluster(
  object = df_clu,
  plot.type = "both",
  ht.col.list = list(col_color = c("#094483", "#ffffff", "#9c2023")),
  column_names_rot = 45,
  line.side = "left",
  annoTerm.data = anno,
  ctAnno.col = c("#f3dd28","#e9792f","#222e65",
                 "#268541","#812a88","#c72527"),
  sample.col = c("#69a0c9","#9acd8a","#eae089",
                 "#dd398f","#e294a4","#d1df6e"),
  show_row_dend = FALSE
)

dev.off()
```

### 箱线图/配对连线图

```
// R
```

### dumbbell chart

<https://mp.weixin.qq.com/s/ps_3DhoCEtBOZyT6vGH8Ww>

### 分组雷达图

**雷达图（Radar Chart）**，又称**蛛网图**或**蜘蛛图**，是一种图形化工具，用于显示多变量数据的对比。每个变量以等角度放射线（从中心向外延伸）表示，数据点在各变量轴上的位置表示各自的数值，最终形成一个闭合的多边形。其定义和特点如下：

1\. 变量展示

&#x20;  各变量沿圆周均匀分布，通常从中心向外延伸，每个放射线代表一个维度或指标。放射线的数量和多边形的边数相同，数量取决于变量的多少。

2\. 数值表示

&#x20;  每个数据点在其相应变量轴上的位置代表其数值大小，距离中心越远通常表示该变量的值越大（根据具体情况可调）。

3\. 多维数据比较

&#x20;  雷达图适合用于比较不同组别的数据在多维度上的表现，例如同类产品在不同指标上的性能对比。通过将多个多边形重叠，可以直观展示不同组别在各维度上的差异。

4\. 易于识别优势和劣势

&#x20;  图形中各边的长短及形状变化直观地展示了数据的强弱特点。图形的对称性和各变量轴上的延伸程度可以帮助快速识别数据的优势和劣势区域。

```
// R

#https://mp.weixin.qq.com/s/yWCMwkoPuOtDR5GP3DwI6Q
```

## 4、展示交集基因

### 韦恩图

```
// R

#https://mp.weixin.qq.com/s/sXg25aznznw8a787HRbrWg
```

### 成比例韦恩图 <a href="#activity-name" id="activity-name"></a>

<figure><img src="https://3583750438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrNJkPTdpyVMk09ldgu9A%2Fuploads%2FZesuSDKlvbR8Ury4yAlk%2Fimage.png?alt=media&#x26;token=251f62d0-4e44-4ee5-93d3-1af58d940ea1" alt=""><figcaption><p>The local microenvironment drives activation of neutrophils in human brain tumors. Fig2B</p></figcaption></figure>

```
// R

#https://mp.weixin.qq.com/s/W2EGbgvyIyvVxQiVX8vg4A
```

### 花瓣图

```
// R

#https://mp.weixin.qq.com/s/1somdu9AXI_YXk56UC3Luw
```

### 散点图（多组学或多对样本）

<figure><img src="https://3583750438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrNJkPTdpyVMk09ldgu9A%2Fuploads%2FHKmEZdEw5TBRSWMNGU9N%2Fimage.png?alt=media&#x26;token=0eed002e-3cdb-483e-ad69-c0ee23e73094" alt="" width="563"><figcaption><p>The local microenvironment drives activation of neutrophils in human brain tumors. Fig2H</p></figcaption></figure>

### 热图

<figure><img src="https://3583750438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrNJkPTdpyVMk09ldgu9A%2Fuploads%2FEVXSkKvqVHLGFrg1pN5k%2Fimage.png?alt=media&#x26;token=dfb11424-beef-4f70-870f-ee3d9ec794ca" alt="" width="375"><figcaption></figcaption></figure>

```
// R
#https://mp.weixin.qq.com/s/mO4BL_TEkXDgnK5WiibPPA


```

## 5、ORA通路富集可视化

### 柱状图/条形图

```
// R
#https://mp.weixin.qq.com/s/DEh7a2n9Va8GKg0kKCo6QA


```

```
// R

#https://mp.weixin.qq.com/s/T06XncgWiFTa4eUkOPGwIQ
```

```
// R
#https://mp.weixin.qq.com/s/67fdMYTAWx578dcSeMCeAA
```

### 流星图/彗星图 <a href="#activity-name" id="activity-name"></a>

```
// R

#https://mp.weixin.qq.com/s/8A6NV2M56FF3y2mLMAA3Gw
#https://mp.weixin.qq.com/s/XVSOR0Gr43TrCylYrdo5PQ


```

### 气泡图/多组气泡图

```
// R

#https://mp.weixin.qq.com/s/P-4mZXwfMBrAzR-a0utALA


```

```
// R

#https://mp.weixin.qq.com/s/MDGhpZKvrj9shfS6XtvX9Q
```

### 双向柱状图

```
// R

#https://mp.weixin.qq.com/s/QYot9vnV29TOtxapWKYjNw
```

### 棒棒糖图/火柴杆图

```
// R

#https://mp.weixin.qq.com/s/PbxpiukunqnZWdKrpMkNkg
```

```
// R
#https://mp.weixin.qq.com/s/GMPkm9TMbvv-BL_aMhJw9g
```

### 和弦图

```
// R

#https://mp.weixin.qq.com/s/YZBqackQAqfKpUmoakiQ4w

#https://mp.weixin.qq.com/s/kW7Q_BmcUILD5_18bItYLQ
```

### 富集环图

```
// R

#https://mp.weixin.qq.com/s/QnO0-ZoQGI69h4aIvSb27w
```

### 聚类热图+词云图

<figure><img src="https://3583750438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrNJkPTdpyVMk09ldgu9A%2Fuploads%2FWy9uue50P85KC4UyYVTT%2Fimage.png?alt=media&#x26;token=bb94e167-2269-45f5-8b3c-82227905009c" alt="" width="563"><figcaption><p>Small extracellular vesicles from young plasma reverse age-related functional declines by improving mitochondrial energy metabolism. Fig3D</p></figcaption></figure>

```
// R

#https://mp.weixin.qq.com/s/BmROSJCTEzHRj9yiM8rcmA


```

## 6、GSEA通路富集可视化

### GSEA图

### 峰峦图+气泡图

<figure><img src="https://3583750438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrNJkPTdpyVMk09ldgu9A%2Fuploads%2Favg7pCKAazZsf0NVc4UR%2Fimage.png?alt=media&#x26;token=623059bd-615f-4a9f-ba9c-490e30005c84" alt="" width="375"><figcaption></figcaption></figure>

```
// R

#https://mp.weixin.qq.com/s/tfy8T2pz1PQ_C-HDFMkgVQ

library(ggridges)

gsearesult <- gseaRes %>% 
  dplyr::arrange(p.adjust) %>%
  head(50) %>%
  dplyr::mutate(log10P = -log10(p.adjust)) %>%
  separate_rows(core_enrichment, sep = "/")


gsearesult <- gsearesult %>%
  left_join(gene, by = c("core_enrichment" = "gene_name")) %>%
  dplyr::mutate(Description = factor(Description, levels = rev(unique(Description))))

custom_colors <- colorRampPalette(c("#3daeb7", "#eeeeee", "#8075ad"))(100)
# 使用 iris 数据集，根据不同物种绘制峰峦图
p <- ggplot(gsearesult, aes(x = log2FoldChange, y = Description, fill = NES)) +
  geom_density_ridges(alpha = 0.7, scale = 1.5) +
  labs(x = "Log2FoldChange", y = "") +
  scale_fill_gradientn(colors = custom_colors) +
  theme(
    panel.background = element_blank(),
    panel.grid = element_blank(),
    panel.border = element_rect(colour = "black", fill = NA, linewidth = 1),
    axis.text = element_text(color = "black", size = 12),
    axis.title = element_text(size = 12),
    legend.text = element_text(size = 12),
    legend.title = element_text(size = 12)
  )
p


custom_colors1 <- colorRampPalette(c("#008bd0", "#eeeeee", "#fc4e00"))(100)
p1 <- ggplot(gsearesult, aes(x = 1, y = Description)) +
  geom_point(aes(size = abs(NES), color = NES)) + # 气泡大小和颜色映射 NES 数据
  scale_color_gradientn(colors = custom_colors1, name = "NES", limits = c(-3, 3)) + # 颜色渐变
  scale_size_continuous(range = c(2, 6)) + # 气泡大小范围
  labs(x = NULL, y = NULL) + # 去除 x 和 y 轴标签
  theme_minimal() + # 简洁主题
  theme(
    panel.background = element_blank(), # 无背景
    panel.grid = element_blank(),
    panel.border = element_blank(), # 无边框
    axis.ticks = element_blank(), # 去除刻度
    axis.text.x = element_blank() # 去除 x 轴标签
  )
p1

在AI中组合两图
```

### 火柴杆图

<figure><img src="https://3583750438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrNJkPTdpyVMk09ldgu9A%2Fuploads%2F1eyMF7ICj6v1Rb3idB02%2Fimage.png?alt=media&#x26;token=1fd08a35-1fcd-4e20-a20d-bae1d274fea5" alt="" width="375"><figcaption></figcaption></figure>

```
// R

##https://mp.weixin.qq.com/s/5ya8N4Nxp6u7-l1ClI05Hg

#输入文件：准备通路名、NES、p value
library(ggplot2)
library(RColorBrewer)

df = read.csv("GSEA.csv", check.names = FALSE)

df$pathway <- factor(df$pathway, levels = rev(unique(df$pathway)))
df$NES <- abs(df$NES)
#df$lgpval <- -log10(df$pval)

ggplot(df) +
  geom_segment(aes(x = pathway, xend = pathway, y = 0, yend = NES),
               color = "black") +
  geom_point(aes(x = pathway, y = NES, size = NES, color = lgpval)) +
  scale_color_distiller(palette = "Spectral") +
  scale_size_continuous(range = c(5, 10)) +
  labs(x = "", y = "NES") +
  coord_flip() +
  theme_classic() +
  theme(
    legend.title = element_text(size = 10),
    legend.text  = element_text(size = 10),
    legend.spacing.x = unit(2, "cm"),
    axis.text = element_text(size = 10),
    axis.title = element_text(size = 10)
  ) +
  guides(
    size  = guide_legend(title = "NES"),
    color = guide_colorbar(title = "-log10(adj.P value)")
  )
```

### 分组柱状图

### 气泡图

<figure><img src="https://3583750438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrNJkPTdpyVMk09ldgu9A%2Fuploads%2F2EnpvOMQlcYLzhbeuV6r%2Fimage.png?alt=media&#x26;token=4f7900cb-4975-40be-870d-c6c813799a6c" alt="" width="563"><figcaption><p>Obesity reshapes regulatory T cells in the visceral adipose tissue by disrupting cellular cholesterol homeostasis. Fig1A</p></figcaption></figure>

### 雷达图

用于展示不同分组/亚群的不同得分

### 热图

## 7、免疫浸润

### 1、箱线图

<figure><img src="https://3583750438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrNJkPTdpyVMk09ldgu9A%2Fuploads%2FIMO2wmyjK80AXtr7n3VJ%2Fimage.png?alt=media&#x26;token=f358c888-2d36-4c81-ae71-d0dfc9e13d80" alt="" width="375"><figcaption><p>Y chromosome loss in cancer drives growth by evasion of adaptive immunity. Fig4A</p></figcaption></figure>

使用MCP counter计算TCGA样本的免疫浸润分数，并进行统计检验。
