缘由
生信之路,道阻且长,记录经验,但渡有缘人。
碎碎念
及时当勉励,岁月不饶人 ——陶渊明
原图 & 文章
Zhou, J., Hu, F., Berhe, M. et al. Genome-wide identification, classification, and expression profiling of LAC gene family in sesame. BMC Plant Biol 24, 1254 (2024).
功能:同时展示了聚类tree和表达数据数据
炫图
代码
1. 加载必要的库
library(tidyverse) # 数据处理和可视化
library(reshape2) # 数据框格式转换
library(ggsci) # 颜色主题
library(gground) # 自定义可视化工具
library(patchwork) # 图形拼接
library(ape) # 树状图生成和处理2. 创建模拟数据
set.seed(42) # 设置随机数种子,保证结果可重复
gene_names <- paste0("Gene", 1:30) # 模拟基因名称
samples1 <- paste0("CK_Sample", 1:20) # 对照组样本名称
samples2 <- paste0("TR_Sample", 1:20) # 处理组样本名称
fpkm1_values <- matrix(runif(30 * 40, min = 0, max = 100), nrow = 30, ncol = 40)- 随机生成 30 个基因在 40 个样本中的表达量数据,范围为
[0, 100]。 samples1和samples2分别表示对照组和处理组的样本。
3. 数据框构造与预处理
data1 <- data.frame(Gene_Name = gene_names, fpkm1_values)
colnames(data1)[2:41] <- c(samples1, samples2) # 设置列名
selected_columns1 <- data1[, c(1, 2:41)] # 选择基因表达相关列
rownames(selected_columns1) <- selected_columns1[, 1] # 设置行名为基因名称
selected_columns1 <- selected_columns1[, 2:41] # 移除基因名称列
log_data1 <- log2(selected_columns1 + 1) # log2 转换,防止零值问题- 将矩阵数据转为数据框格式,并对列名和行名进行设置。
- 数据进行
log2(FPKM+1)转换,压缩数据范围并避免取对数时的零值问题。
4. 计算距离矩阵与层次聚类
dist_matrix <- dist(log_data1, method = "euclidean") # 计算基因表达的欧几里得距离
hc <- hclust(dist_matrix, method = "ward.D2") # 使用 Ward.D2 方法聚类
phylo_tree <- ape::as.phylo(hc) # 转换为树状结构- 通过欧几里得距离衡量基因表达模式的差异。
ward.D2是一种层次聚类方法,适合构建树状关系。- 最终结果转换为树状图对象
phylo_tree。
5. 热图输入数据处理
log_data_ordered <- log_data1[hc$order, ] # 按聚类结果对基因排序
draw1 <- melt(as.matrix(log_data_ordered)) # 转换为长格式,适合 ggplot- 使用聚类结果的顺序对基因重新排序。
- 使用
melt将矩阵数据转为长格式,便于热图绘制。
6. 绘制树状图
tree_plot <- ggtree(phylo_tree, branch.length = "none")ggtree绘制聚类结果的树状图,设置branch.length = "none"使分支长度一致。
draw1$Var1 <- factor(draw1$Var1,
level = tree_plot$data %>% arrange(y) %>% na.omit() %>% pull(label) %>% unique())- 根据树状图数据的顺序调整热图中基因名称的顺序,确保热图和树状图的基因对齐。
**7. 画图与拼图
p <- ggplot(draw1 )+
geom_round_rect(data=data.frame(xmin=0,xmax=20.4,ymin=0, ymax=12.3),
aes(xmin=xmin,xmax=xmax, ymin=ymin, ymax=ymax),radius = unit(0.1,"npc"),fill="#ecf7dd")+
geom_round_rect(data=data.frame(xmin=0,xmax=20.4,ymin=12.5, ymax=15.3),
aes(xmin=xmin,xmax=xmax, ymin=ymin, ymax=ymax),radius = unit(0.2,"npc"),fill="#fae8f3")+
geom_round_rect(data=data.frame(xmin=0,xmax=20.4,ymin=15.5, ymax=18.3),
aes(xmin=xmin,xmax=xmax, ymin=ymin, ymax=ymax),radius = unit(0.2,"npc"),fill="#e0f3ec")+
geom_round_rect(data=data.frame(xmin=0, xmax=20.4,ymin=18.5, ymax=Inf),
aes(xmin=xmin,xmax=xmax, ymin=ymin, ymax=ymax),radius = unit(0.1,"npc"),fill="#e9ecf8")+
geom_round_rect(data=data.frame(xmin=20.6,xmax=41,ymin=0, ymax=12.3),
aes(xmin=xmin,xmax=xmax, ymin=ymin, ymax=ymax),radius = unit(0.1,"npc"),fill="#ecf7dd")+
geom_round_rect(data=data.frame(xmin=20.6,xmax=41,ymin=12.5, ymax=15.3),
aes(xmin=xmin,xmax=xmax, ymin=ymin, ymax=ymax),radius = unit(0.2,"npc"),fill="#fae8f3")+
geom_round_rect(data=data.frame(xmin=20.6,xmax=41,ymin=15.5, ymax=18.3),
aes(xmin=xmin,xmax=xmax, ymin=ymin, ymax=ymax),radius = unit(0.2,"npc"),fill="#e0f3ec")+
geom_round_rect(data=data.frame(xmin=20.6, xmax=41,ymin=18.5, ymax=Inf),
aes(xmin=xmin,xmax=xmax, ymin=ymin, ymax=ymax),radius = unit(0.1,"npc"),fill="#e9ecf8")+
geom_point(data=draw1,aes(Var2, Var1, fill = value, size = value), stroke =1, shape=21, color="black",inherit.aes = F,alpha=0.75)
p <- p + scale_size(c(1,6))+scale_x_discrete(position="top")+
scale_fill_gradient2(
low = "white", mid = "#e58537", high = "red",
midpoint = median(draw1$value), # 中间值的定义
na.value = "grey" # NA 值使用灰色
) + theme_minimal() + # 调整圆的大小范围
labs(x = NULL, y = NULL, fill = "Expression\n(log2(FPKM+1))") +
scale_y_discrete(position = "right") + # 将基因名放右边
guides(
fill = guide_legend(title = "(log2(FPKM+1))", override.aes = list(size = 5)),
size = guide_legend(title = "(log2(FPKM+1))", override.aes = list(shape = 21, color = "black"))
)+
theme(axis.text.x=element_text(angle=90),
panel.grid = element_blank()
)
tree_plot+p+plot_layout(ncol=2,widths = c(1,2)) ALL
```r
#devtools::install_github("dxsbiocc/gground")
library(tidyverse)
library(reshape2)
library(ggsci)
library(gground)
library(patchwork)
library(ape)
# 创建一个模拟数据框
set.seed(42)
gene_names <- paste0("Gene", 1:30) # 30个基因名称
samples1 <- paste0("CK_Sample", 1:20) # 20个样本
samples2 <- paste0("TR_Sample", 1:20) # 20个样本
fpkm1_values <- matrix(runif(30 * 40, min = 0, max = 100), nrow = 30, ncol = 40)
# 构建数据框,并添加基因名称列
data1 <- data.frame(Gene_Name = gene_names, fpkm1_values)
colnames(data1)[2:41] <- c(samples1,samples2)
selected_columns1<- data1[, c(1, 2:41)]
rownames(selected_columns1) <- selected_columns1[, 1]
selected_columns1 <- selected_columns1[, 2:41]
log_data1 <- log2(selected_columns1 + 1)
# 计算距离矩阵
dist_matrix <- dist(log_data1, method = "euclidean")
# 进行层次聚类
hc <- hclust(dist_matrix, method = "ward.D2")
# 转换聚类结果为树结构
phylo_tree <- ape::as.phylo(hc)
# 绘制热图数据的矩阵,按聚类顺序排列
log_data_ordered <- log_data1[hc$order, ]
draw1 <- melt(as.matrix(log_data_ordered))
#tree
tree_plot <- ggtree(phylo_tree, branch.length = "none",)#+geom_tiplab(size=3, color="purple")
draw1$Var1 <- factor(draw1$Var1,
level=tree_plot$data %>% arrange(y)
%>%na.omit() %>% pull(label) %>% unique()
)
#geom_point
p <- ggplot(draw1 )+
geom_round_rect(data=data.frame(xmin=0,xmax=20.4,ymin=0, ymax=12.3),
aes(xmin=xmin,xmax=xmax, ymin=ymin, ymax=ymax),radius = unit(0.1,"npc"),fill="#ecf7dd")+
geom_round_rect(data=data.frame(xmin=0,xmax=20.4,ymin=12.5, ymax=15.3),
aes(xmin=xmin,xmax=xmax, ymin=ymin, ymax=ymax),radius = unit(0.2,"npc"),fill="#fae8f3")+
geom_round_rect(data=data.frame(xmin=0,xmax=20.4,ymin=15.5, ymax=18.3),
aes(xmin=xmin,xmax=xmax, ymin=ymin, ymax=ymax),radius = unit(0.2,"npc"),fill="#e0f3ec")+
geom_round_rect(data=data.frame(xmin=0, xmax=20.4,ymin=18.5, ymax=Inf),
aes(xmin=xmin,xmax=xmax, ymin=ymin, ymax=ymax),radius = unit(0.1,"npc"),fill="#e9ecf8")+
geom_round_rect(data=data.frame(xmin=20.6,xmax=41,ymin=0, ymax=12.3),
aes(xmin=xmin,xmax=xmax, ymin=ymin, ymax=ymax),radius = unit(0.1,"npc"),fill="#ecf7dd")+
geom_round_rect(data=data.frame(xmin=20.6,xmax=41,ymin=12.5, ymax=15.3),
aes(xmin=xmin,xmax=xmax, ymin=ymin, ymax=ymax),radius = unit(0.2,"npc"),fill="#fae8f3")+
geom_round_rect(data=data.frame(xmin=20.6,xmax=41,ymin=15.5, ymax=18.3),
aes(xmin=xmin,xmax=xmax, ymin=ymin, ymax=ymax),radius = unit(0.2,"npc"),fill="#e0f3ec")+
geom_round_rect(data=data.frame(xmin=20.6, xmax=41,ymin=18.5, ymax=Inf),
aes(xmin=xmin,xmax=xmax, ymin=ymin, ymax=ymax),radius = unit(0.1,"npc"),fill="#e9ecf8")+
geom_point(data=draw1,aes(Var2, Var1, fill = value, size = value), stroke =1, shape=21, color="black",inherit.aes = F,alpha=0.75)
p <- p + scale_size(c(1,6))+scale_x_discrete(position="top")+
scale_fill_gradient2(
low = "white", mid = "#e58537", high = "red",
midpoint = median(draw1$value), # 中间值的定义
na.value = "grey" # NA 值使用灰色
) + theme_minimal() + # 调整圆的大小范围
labs(x = NULL, y = NULL, fill = "Expression\n(log2(FPKM+1))") +
scale_y_discrete(position = "right") + # 将基因名放右边
guides(
fill = guide_legend(title = "(log2(FPKM+1))", override.aes = list(size = 5)),
size = guide_legend(title = "(log2(FPKM+1))", override.aes = list(shape = 21, color = "black"))
)+
theme(axis.text.x=element_text(angle=90),
panel.grid = element_blank()
)
tree_plot+p+plot_layout(ncol=2,widths = c(1,2))