大数跨境
0
0

跟着iMeta学作图|分组柱状图+差异字母标记

跟着iMeta学作图|分组柱状图+差异字母标记 iMeta
2025-11-24
4
导读:iMeta(宏)期刊: 生物/医学类综合期刊,重点关注生物技术、大数据和组学等交叉学科。


1 写在前面

Part.1

在数据可视化领域,柱状图(bar chart)是最基础、最直观的图形之一;而当我们的数据存在“一个分类变量 + 一个分组变量”的双重结构时,分组柱状图(grouped bar chart,亦叫簇状柱形图)便成为展示“组内差异”与“组间差异”的首选。

本期我们挑选刊登在iMeta上的HLF and PPARα axis regulates metabolic-associated fatty liver disease through extracellular vesicles derived from the intestinal microbiota论文的Figure 2L进行复现

原文链接:https://onlinelibrary.wiley.com/doi/full/10.1002/imt2.70022

DOI:https://doi.org/10.1002/imt2.70022

中文链接:iMeta | 周磊/李一星组-解析HLF在代谢相关脂肪性肝病中的作用

引文格式:

Xingzhen Yang, Jiale Wang, Xinyu Qi, Menglong Hou, Mengkuan Liu, Yixing Li, Lei Zhou, et al. 2025. HLF and PPARα axis regulates metabolic-associated fatty liver disease through extracellular vesicles derived from the intestinal microbiota. iMeta 4: e70022. https://doi.org/10.1002/imt2.70022.

文中Figure 2L:


 
 


接下来,我们将通过详尽的代码逐步拆解原图,最终实现对原图的复现。


2 数据整理

Part.2

整理原文中的数据成如下格式:

分组信息整理如下:


3 代码复现

Part.3

3.1 R包检测和安装


加载使用到的R包openxlsx、dplyr、tidyr、agricolae、ggplot2

library(openxlsx)library(dplyr)library(tidyr)library(agricolae)  library(ggplot2)
# 如果没有安装R包可以使用下面的命令安装install.packages("openxlsx")install.packages("vegan")install.packages("dplyr")install.packages("ggplot2")

3.2 读取数据及数据处理


设置工作路径,读取先前整理好的数据

setwd('C:/Users/law/Desktop/')   # 设置工作路径
data = read.xlsx("imeta分组柱状图数据.xlsx", sheet = 1)   # 读取数据names(data)[1] <- "sampleid"    #  修改第一列的列名为 sampleid,减少后面代码需要改动的地方
group_data = read.xlsx("imeta分组柱状图数据.xlsx", sheet = 2)  # 读取分组数据names(group_data)[1] <- "sampleid"  names(group_data)[2] <- "group"   

读取数据之后的数据框如下:



转换数据成长格式并合并分组信息

idx_col <- names(data)[-1]   #  读取除了sampleid一列,其余列的列名,作为后续转换的临时变量
# 将数据从宽格式转换为长格式data_long <- data %>%    pivot_longer(        cols = all_of(idx_col),  # 选择要转换的列名        names_to = "Group",                 # 原列名变成新的一列列        values_to = "value"                   # 原数值变成新列    )%>%    drop_na(value)   # 删除na的行,如果有的话
# 合并分组信息到长格式数据中data_long <- merge(data_long, group_data, by = "sampleid")


分组设置为因子类型并按默认顺序排列

data_long <- data_long %>%    mutate(        sampleid = factor(sampleid, levels = unique(data$sampleid)),        Group = factor(Group, levels = idx_col)    ) %>%    arrange(sampleid, Group)


计算均值并添加显著性检验的结果

# 计算均值和标准差data_mean <- data_long %>%    group_by(Groupgroup) %>%    dplyr::summarize(        mean_data = mean(value, na.rm = T),        sd = sd(value, na.rm = T),        n=sum(!is.na(value)),        se = sd/sqrt(n),        max_data = max(value, na.rm = TRUE),    # 最大值        min_data = min(value, na.rm = TRUE),    # 最小值        .groups = "drop"  # 计算完毕之后,取消分组    )  #给均值添加显著性检验结果Group <- unique(data_long$Group)  # 获取所有的 Group 水平mark_result <- data.frame()   # 初始化一个空的数据框,用于存储每个 Group 的显著性标记结果for (i in Group){    # 设置临时变量    temp_data <- filter( data_long, Group == i)    # 进行 LSD 检验,这里可以根据自己的需求选择不同的多重比较方法比如:HSD、Duncan 等
    LSD_test <- LSD.test( lm(value ~ group, temp_data), 'group',p.adj = 'BH', alpha = 0.05)    # 合并检验数据    mark_result <- rbind(        mark_result,        data.frame(            LSD_test$groups,            Group = i,            group = rownames(LSD_test$groups)        ),        make.row.names = FALSE   # 不保留原始行名,让新行名自动变成 1、2、3…,防止行名混乱    )}# 将字母标记的信息和均值数据合并data_mean <- merge(data_mean, mark_result, by = c("Group""group"))

添加显著性标记之后的数据如下:


设置作图时的因子类型,保证顺序不乱

data_mean$Group <- factor(data_mean$Group, levels = unique(data_long$Group)  )  # 这里的顺序可以根据实际情况调整data_mean$group <- factor(data_mean$group, levels =  unique(data_long$group)  )  # 这里的顺序可以根据实际情况调整data_long$group <- factor(data_long$group, levels = unique(data_long$group)   )

3.3 分组柱状图的绘制


构建柱状图、散点、误差棒、显著性标记

p = ggplot(data_mean, aes(x = Group, y = mean_data, color = group)) +    geom_bar(position = position_dodge(width = 0.8), stat = "identity",             width = 0.6, linewidth = 1.5, fill = 'white') +    # 添加样本点并按照group映射颜色    geom_point(data = data_long, aes(y = value, color = group),               position = position_jitterdodge(jitter.width = 0.2, dodge.width = 0.8),               alpha = 1, size = 3, shape = 16, show.legend = FALSE) +    # 添加误差棒    geom_errorbar(aes(ymin = mean_data - sd, ymax = mean_data + sd),                  position = position_dodge(0.8), width = 0.2,                  linewidth = 1, show.legend = FALSE) +    # 添加整理好的标记字母    geom_text(data = data_mean,              aes(x = Group, y = max_data, group = group, label = groups),              color = 'black', position = position_dodge(0.8),              size = 8, vjust = -0.5, show.legend = FALSE)
p


设置颜色 + 坐标轴 + 主题样式

p = p +    scale_color_manual( values = c('#D1166D''#0F99B1''#FF7900''#028102'), name = '' ) +  # 使用 RColorBrewer 的调色板    labs(x = NULL, y = "Fat weight/BW (%)") +    theme_classic() +    scale_y_continuous(        breaks = c(0,2,4,6,8),  # 指定刻度位置        expand = expansion(mult = c(0, 0.11)) # 设置y轴的范围扩展    )+    scale_x_discrete(expand = c(0.05,0.05) ) +    theme(        axis.text.x = element_text(size = 20,face = 'bold'),        axis.text.y = element_text(size = 20),        axis.title.y = element_text(size = 20,face = 'bold'),        legend.title = element_text(size = 15),        legend.text = element_text(size = 20),        legend.position = 'top',   # 图例位置设置到上方        legend.direction = 'horizontal',   # 图例水平展示        axis.ticks = element_line(size = 1.5),  # x轴刻度线        axis.ticks.length = unit(0.4, "cm"),  # 刻度线的长度        axis.line = element_line(linewidth = 1.5) # xy轴的粗细            ) +    guides(color = guide_legend(ncol = 2))   # 图例“一行 2 个”
p


导出文件

#可以选择导出pdf、jpg、png等格式ggsave("分组柱状图.pdf", plot = p, width = 7, height = 6)


4 完整代码

Part.4

library(openxlsx)library(dplyr)library(tidyr)library(agricolae)  library(ggplot2)
setwd('C:/Users/law/Desktop/')  # 设置工作路径data = read.xlsx("imeta分组柱状图.xlsx", sheet = 1)   # 读取数据names(data)[1] <- "sampleid"#  修改第一列的列名为 sampleid,有利于后面代码统一减少需要改动的地方
group_data = read.xlsx("imeta分组柱状图.xlsx", sheet = 2)names(group_data)[1] <- "sampleid"names(group_data)[2] <- "group"
idx_col <- names(data)[-1]   #  读取除了sampleid一列,其余列的列名,作为后续转换的依据# 将数据从宽格式转换为长格式data_long <- data %>%    pivot_longer(        cols = all_of(idx_col),  # 选择要转换的列,就是一簇一簇的名称,通俗一些就是分组组装图的x轴名称        names_to = "Group",                 # 原列名变成新的一列列        values_to = "value"# 原数值变成新列    )%>%    drop_na(value)
# 合并分组信息到长格式数据中data_long <- merge(data_long, group_data, by = "sampleid")
# 设置为因子类型并按默认顺序排列data_long <- data_long %>%    mutate(        sampleid = factor(sampleid, levels = unique(data$sampleid)),        Group = factor(Group, levels = idx_col)    ) %>%    arrange(sampleid, Group)
# 计算均值和标准差data_mean <- data_long %>%    group_by(Groupgroup) %>%    dplyr::summarize(        mean_data = mean(value, na.rm = T),         sd = sd(value, na.rm = T),        n=sum(!is.na(value)),        se = sd/sqrt(n),        max_data = max(value, na.rm = TRUE),    # 最大值        min_data = min(value, na.rm = TRUE),    # 最小值        .groups = "drop"# 计算完毕之后,取消分组
    )  
##给均值添加显著性检验结果Group <- unique(data_long$Group)  # 获取所有的 Group 水平mark_result <- data.frame()   # 初始化一个空的数据框,用于存储每个 Group 的显著性标记结果
for (i in Group){# 设置临时变量    temp_data <- filter( data_long, Group == i)
# 进行 LSD 检验,这里可以根据自己的需求选择不同的多重比较方法比如:HSD、Duncan 等    LSD_test <- LSD.test( lm(value ~ group, temp_data), 'group',p.adj = 'BH', alpha = 0.05)
    mark_result <- rbind(        mark_result,        data.frame(            LSD_test$groups            Group = i,             group = rownames(LSD_test$groups)        ),        make.row.names = FALSE# 不保留原始行名,让新行名自动变成 1、2、3…,防止行名混乱    )}
data_mean <- merge(data_mean, mark_result, by = c("Group""group"))
# 设置因子类型,保持绘图顺序和读取数据顺序一致data_mean$Group <- factor(data_mean$Group, levels = unique(data_long$Group)  )  # 这里的顺序可以根据实际情况调整data_mean$group <- factor(data_mean$group, levels =  unique(data_long$group)  )  # 这里的顺序可以根据实际情况调整data_long$group <- factor(data_long$group, levels = unique(data_long$group)   )
p = ggplot(data_mean, aes(x = Group, y = mean_data, color = group)) +    geom_bar(position = position_dodge(width = 0.8),              stat = "identity"             width = 0.6,             linewidth = 1.5,             fill = 'white'    ) +    geom_point(data = data_long,                aes(y = value, color = group),                position = position_jitterdodge(jitter.width = 0.2, dodge.width = 0.8),                alpha = 1,               size = 3               shape = 16,               show.legend = F) +
    geom_errorbar(aes(ymin = mean_data - sd, ymax = mean_data + sd),                   position = position_dodge(width = 0.8), width = 0.2, linewidth = 1, show.legend = FALSE) +
    geom_text(data = data_mean,               aes(x = Group                  y = max_data,                  group = group,                  label = groups              ),              color = 'black',              position = position_dodge(0.8),               size = 8,              show.legend = FALSE,              vjust = -0.5# 配置颜色、调整字体p = p +    scale_color_manual( values = c('#D1166D''#0F99B1''#FF7900''#028102'), name = '' ) +  # 使用 RColorBrewer 的调色板    labs(x = NULL, y = "Fat weight/BW (%)") +    theme_classic() +    scale_y_continuous(        breaks = c(0,2,4,6,8),  # 指定刻度位置        expand = expansion(mult = c(00.11)) # 设置y轴的范围扩展    )+    scale_x_discrete(expand = c(0.05,0.05) ) +    theme(        axis.text.x = element_text(size = 20,face = 'bold'),        axis.text.y = element_text(size = 20),        axis.title.y = element_text(size = 20,face = 'bold'),        legend.title = element_text(size = 15),        legend.text = element_text(size = 20),        legend.position = 'top',        legend.direction = 'horizontal',        axis.ticks = element_line(size = 1.5),  # x轴刻度线        axis.ticks.length = unit(0.4"cm"),  # 刻度线的长度        axis.line = element_line(linewidth = 1.5# xy轴的粗细
    ) +    guides(color = guide_legend(ncol = 2))   # 图例“一行 2 个”
p
ggsave("分组柱状图.pdf", plot = p, width = 7, height = 6)

更多推荐

(▼ 点击跳转)

高引文章 ▸▸▸▸

iMeta | 引用20000+,海普洛斯陈实富发布新版fastp,更快更好地处理FASTQ数据

高引文章 ▸▸▸▸

iMeta | 兰大张东组:使用PhyloSuite进行分子系统发育及系统发育树的统计分析

高引文章▸▸▸▸

iMeta | 唐海宝/张兴坦-用于比较基因组学分析的多功能分析套件JCVI

iMeta封面

1卷1期

1卷2期

1卷3期

1卷4期

2卷1期

2卷2期

2卷3期

2卷4期

3卷1期

3卷2期

3卷3期

3卷4期

3卷5期

3卷6期

4卷1期

4卷2期

4卷3期

4卷4期

4卷5期

iMetaOmics封面

1卷1期

1卷2期

2卷1期

2卷2期

2卷3期

iMetaMed封面

1卷1期

1卷2期

期刊简介

iMeta” 是由威立、宏科学和本领域数千名华人科学家合作出版的开放获取期刊,主编由中科院微生物所刘双江研究员和荷兰格罗宁根大学傅静远教授担任。目的是发表所有领域高影响力的研究、方法和综述,重点关注微生物组、生物信息、大数据和多组学等前沿交叉学科。目标是发表前10%(IF > 20)的高影响力论文。期刊特色包括中英双语图文、双语视频、可重复分析、图片打磨、60万用户的社交媒体宣传等。2022年2月正式创刊!相继被Google Scholar、PubMed、SCIE、ESI、DOAJ、Scopus等数据库收录!2025年6月影响因子33.2,中科院分区生物学1区Top,位列全球SCI期刊前千分之三(65/22249),微生物学科2/163,仅低于Nature Reviews,学科研究类期刊全球第一,中国大陆5/585!

iMetaOmics” 是“iMeta” 子刊,主编由中国科学院北京生命科学研究院赵方庆研究员和香港中文大学于君教授担任,目标是成为影响因子大于10的高水平综合期刊,欢迎投稿!

"iMetaMed"  是“iMeta” 子刊,专注于医学、健康和生物技术领域,目标是成为影响因子大于15的医学综合类期刊,欢迎投稿!

iMeta主页:

http://www.imeta.science

姊妹刊iMetaOmics主页:

http://www.imeta.science/imetaomics/

出版社iMeta主页:

https://onlinelibrary.wiley.com/journal/2770596x

出版社iMetaOmics主页:

https://onlinelibrary.wiley.com/journal/29969514

出版社iMetaMed主页:

https://onlinelibrary.wiley.com/journal/3066988x

iMeta投稿:

https://wiley.atyponrex.com/journal/IMT2

iMetaOmics投稿:

https://wiley.atyponrex.com/journal/IMO2

iMetaMed投稿:

https://wiley.atyponrex.com/submission/dashboard?siteName=IMM3

邮箱:

office@imeta.science


【声明】内容源于网络
0
0
iMeta
iMeta(宏)期刊: 生物/医学类综合期刊,重点关注生物技术、大数据和组学等交叉学科。
内容 634
粉丝 0
iMeta iMeta(宏)期刊: 生物/医学类综合期刊,重点关注生物技术、大数据和组学等交叉学科。
总阅读1.2k
粉丝0
内容634