You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为ggplot生成的柱状图添加多层X轴标签?

实现ggplot2多层X轴的几种方案

首先得提个小细节:你原来的代码里有个小问题——汇总后的df里已经没有Inhibition列了,所以ggplot(df, aes(x=Treatment, y=Inhibition))会报错,应该把y映射到你计算的mean列哦。

接下来针对你要的多层X轴(上层Treatment,下层Concentration),给你三种实用的实现方案:

方案1:用复合标签+ggtext实现“伪多层轴”

这种方法最简单,把Treatment和Concentration合并成带换行的标签,用ggtext渲染后看起来就是两层轴,适合分组不多的场景:

# 先加载需要的包
library(ggplot2)
library(plyr)
library(ggtext) # 如果没安装先跑:install.packages("ggtext")

# 给汇总后的数据集添加复合标签
df$x_axis_label <- paste0(df$Treatment, "\n", df$Concentration)

# 绘制图表
p <- ggplot(df, aes(x = x_axis_label, y = mean)) +
  geom_bar(stat = "identity", position = position_dodge(0.9), fill = "#2c3e50") +
  geom_errorbar(aes(ymin = mean - se, ymax = mean + se),
                position = position_dodge(0.9), width = 0.2, color = "#e74c3c") +
  labs(x = NULL, y = "Inhibition (Mean ± SE)") +
  theme_minimal() +
  theme(
    axis.text.x = element_markdown(size = 10), # 用ggtext解析换行标签
    panel.grid.major.x = element_blank(), # 去掉X轴方向的网格线,更清晰
    plot.title = element_text(hjust = 0.5, size = 14, face = "bold")
  )

p

方案2:用分面(Facet)实现分组式多层轴

如果你的Treatment分组较多,用分面会更清晰,每个Treatment作为一个独立的分面,下方显示Concentration:

library(ggplot2)
library(plyr)

p <- ggplot(df, aes(x = Concentration, y = mean)) +
  geom_bar(stat = "identity", position = position_dodge(0.9), fill = "#2c3e50") +
  geom_errorbar(aes(ymin = mean - se, ymax = mean + se),
                position = position_dodge(0.9), width = 0.2, color = "#e74c3c") +
  labs(y = "Inhibition (Mean ± SE)") +
  # 用facet_grid创建横向分面,每个Treatment对应一个分面
  facet_grid(. ~ Treatment, space = "free_x", scales = "free_x") +
  theme_minimal() +
  theme(
    strip.text.x = element_text(size = 12, face = "bold"), # 分面标题(Treatment)加粗
    panel.spacing.x = unit(0.2, "cm"), # 调整分面之间的间距
    axis.text.x = element_text(angle = 45, hjust = 1) # 如果Concentration标签长,可以旋转
  )

p

方案3:用grid包自定义真正的双层X轴

如果你想要完全独立的两层轴(上层Treatment,下层Concentration),可以用grid包手动添加上层轴标签,代码稍复杂但效果最贴合“多层轴”的需求:

library(ggplot2)
library(plyr)
library(grid)
library(gtable)

# 先绘制基础图,X轴用Concentration,同时保留Treatment的分组信息
p <- ggplot(df, aes(x = interaction(Concentration, Treatment), y = mean)) +
  geom_bar(stat = "identity", position = position_dodge(0.9), fill = "#2c3e50") +
  geom_errorbar(aes(ymin = mean - se, ymax = mean + se),
                position = position_dodge(0.9), width = 0.2, color = "#e74c3c") +
  labs(x = "Concentration", y = "Inhibition (Mean ± SE)") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# 把ggplot对象转换成grob,方便修改
g <- ggplotGrob(p)

# 计算每个Treatment对应的X轴位置
treatments <- unique(df$Treatment)
# 统计每个Treatment下的Concentration数量
conc_count <- table(df$Treatment)
# 计算每个Treatment标签的中心位置
x_positions <- cumsum(conc_count) - conc_count/2
# 转换成0-1的相对位置
x_rel_pos <- x_positions / length(df$Concentration)

# 在图表上方添加一行,用来放Treatment标签
g <- gtable_add_rows(g, unit(1.2, "lines"), pos = 4)
# 添加Treatment标签到新行
g <- gtable_add_grob(g,
                     lapply(1:length(treatments), function(i) {
                       textGrob(
                         label = treatments[i],
                         x = x_rel_pos[i],
                         gp = gpar(fontsize = 12, fontface = "bold")
                       )
                     }),
                     t = 5, l = 4, r = 4)

# 绘制最终的图形
grid.draw(g)

你可以根据自己的数据集大小和视觉需求选择合适的方案~

内容的提问来源于stack exchange,提问作者sh yang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:41:51