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

ggplot多分类双轴条形图X轴多层标签设置求助

解决ggplot双轴条形图的多层X轴标签问题

问题说明

已成功绘制双轴条形图,但无法设置多层X轴标签:每2个条形对应Resistant/Susceptible分组,前12个条形对应48hpi时间点,需要实现「Timepoint → Sample → Group」的三层X轴标签结构。

解决方案

ggplot本身不支持原生多层轴标签,推荐通过**分面(facet)**模拟多层标签效果,同时修正数据处理逻辑避免手动赋值错误,以下是完整实现代码:

library(tidyverse)

# 构建数据并添加Sample、Timepoint属性
DF_blood <- data.frame(Group = c("Resistant", "Susceptible"), 
                       Host_DEGs = c(3558, 5635), 
                       Viral_counts = c(0.4771213, 5.608774)) |>
  mutate(Sample = "Blood", Timepoint = "48hpi")

DF_Lung <- data.frame(Group = c("Resistant", "Susceptible"), 
                      Host_DEGs = c(126, 10866), 
                      Viral_counts = c(1.531479, 6.325484)) |>
  mutate(Sample = "Lung", Timepoint = "48hpi")

DF_NasalT_72 <- data.frame(Group = c("Resistant", "Susceptible"), 
                           Host_DEGs = c(2830, 4632), 
                           Viral_counts = c(0, 4.716613)) |>
  mutate(Sample = "Nasal_Turbinate", Timepoint = "72hpi")

DF_NasalT_48 <- data.frame(Group = c("Resistant", "Susceptible"), 
                           Host_DEGs = c(81, 6126), 
                           Viral_counts = c(2.41162, 4.985206)) |>
  mutate(Sample = "Nasal_Turbinate", Timepoint = "48hpi")

# 合并数据框
combined_df <- rbind(DF_blood, DF_Lung, DF_NasalT_48, DF_NasalT_72)

# 转长格式并缩放数值(适配双Y轴)
DFlong <- combined_df |> 
  pivot_longer(cols = -c(Group, Sample, Timepoint), names_to = "Type") |> 
  mutate(scaled_value = ifelse(Type == "Host_DEGs", value, value / 0.001))

# 绘制图形
g2 <- ggplot(DFlong, aes(x = Group, y = scaled_value, fill = Type)) + 
  geom_col(position = "dodge", width = 0.8) + 
  # 双Y轴配置:确保反向转换与缩放逻辑一致
  scale_y_continuous(
    name = "Host DEGs", 
    limits = c(0, 11000), 
    sec.axis = sec_axis(~ . * 0.001, name = "Viral gene counts (log10)")
  ) +
  # 分面实现多层标签:Timepoint(上层)→ Sample(中层)→ Group(底层)
  facet_grid(cols = vars(Timepoint, Sample), scales = "free_x", space = "free_x") +
  # 主题调整优化视觉效果
  theme_classic() +
  theme(
    strip.background = element_blank(), # 隐藏分面边框
    strip.text.x = element_text(size = 10, face = "bold"),
    strip.text.x.top = element_text(margin = margin(b = 5)), # 上层标签间距
    strip.text.x.bottom = element_text(margin = margin(b = 10)), # 中层标签间距
    axis.text.x = element_text(size = 9),
    axis.title.x = element_blank(),
    legend.position = "top"
  )

print(g2)

关键说明

  1. 数据处理优化:直接在每个数据框创建时添加Sample和Timepoint属性,避免手动赋值的错误。
  2. 分面模拟多层轴:通过facet_grid将Timepoint设为上层标签、Sample设为中层标签,X轴原生显示Group,实现三层结构。
  3. 双Y轴修正:修正了轴转换公式,保证右侧轴的Viral_counts数值与原始数据一致。
  4. 主题调整:隐藏分面边框、调整标签间距,让多层标签的视觉层次更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 13:17:25