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

R ggplot2翻转坐标分面图调整Y轴刻度与分面标题位置

问题背景

使用R语言ggplot2包绘制条形图,初始绘图代码如下:

ggplot(df, aes(x=rel, y=durationHours_mean, fill=newCategory))+
geom_bar(stat='identity')+
scale_fill_manual(values=cols,labels=c('preb','b','i-b','rel','test','i-test'))+
facet_grid('newCategory') + ylab("Duration") + xlab("Rel") + coord_flip()+
theme(
legend.position='none',
panel.grid.major = element_line(colour = "grey95"),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.line.x = element_line(colour = "black"),
axis.line.y = element_line(colour = "black"),
axis.text = element_text(colour = "black"),
axis.text.x = element_text(size = 12),
axis.text.y = element_text(size = 12),
axis.title = element_text(size = 17),
strip.text.x = element_text(size = 17),
strip.text.y = element_text(size=12,angle = 360),
strip.background = element_blank()
)

初始生成效果:
当前效果图
目标效果:将分面标题移动到对应X轴刻度的中间位置,同时将X轴刻度移动到条形的右侧,参考效果如下:
目标效果图
此前尝试使用scale_fill_discrete调整,但仅能在单个分面内生效,无法实现跨分面全局调整。本次使用的数据集构造代码如下:

df<-structure(list(rel = c("1a", "1a", "1a", "1a", 
                           "1a", "1a", "1b", "1b", "1b", "1b", "1b", 
                           "1b", "2a", "2a", "2a", "2a", "2a", "2a", 
                           "3a", "3a", "3a", "3a", "3a", "3a"), 
               newCategory = c("b", "ib", "it", 
                               "preb", "rel", "test", "b", "ib", 
                               "it", "preb", "rel", "test", "b", 
                               "ib", "it", "preb", "rel", 
                               "test", "b", "ib", "it", 
                               "preb", "rel", "test"), durationHours_mean = c(0.092396019, 
                                                                                      0.010302845, 0.035852273, 0.136273024, 0.279052288, 0.543560606, 
                                                                                      0.154655266, 0.004263029, 0.20724439, 0.154030945, 0.366705574, 
                                                                                      0.789809989, 0.237409639, 0.03785531, 0.099604529, 0.227135207, 
                                                                                      0.432482151, 3.18171129, 0.157553476, 0.019273247, 0.522296866, 
                                                                                      0.255998217, 0.514912359, 1.530390671)), row.names = c(NA, 
                                                                                                                                             -24L), class = c("spec_tbl_df", "tbl_df", "tbl", "data.frame"
                                                                                                                                             ), spec = structure(list(cols = list(rel = structure(list(), class = 
                                                                                                                                                                                                        c("collector_character", 
                                                                                                                                                                                                          "collector")), newCategory = structure(list(), class = c("collector_character", 
                                                                                                                                                                                                                                                                   "collector")), durationHours_mean = structure(list(), class = c("collector_double", 
                                                                                                                                                                                                                                                                                                                                   "collector")), clusterName = structure(list(), class = c("collector_character", 
                                                                                                                                                                                                                                                                                                                                                                                            "collector"))), default = structure(list(), class = c("collector_guess", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                  "collector")), skip = 1L), class = "col_spec"))
解决方案

两种实现路径,按需选择即可。

原生ggplot2实现(无第三方依赖)

核心逻辑:关闭默认分面条带,手动在目标位置添加分面标签,同时调整坐标轴位置到条形右侧,不需要安装额外包,兼容性最好。

library(ggplot2)
library(dplyr)
# 替换为你原有自定义颜色向量即可
cols <- scales::hue_pal()(6)
# 计算每个分面的标签坐标:纵向取rel分类的中点,横向取条形最大值外侧留边
label_pos <- df %>%
  group_by(newCategory) %>%
  summarise(
    y_pos = max(durationHours_mean)*1.05,
    x_pos = median(as.numeric(factor(rel)))
  )

ggplot(df, aes(x=rel, y=durationHours_mean, fill=newCategory))+
  geom_bar(stat='identity')+
  scale_fill_manual(values=cols,labels=c('preb','b','i-b','rel','test','i-test'))+
  facet_grid(rows = vars(newCategory), scales = "free_y") + 
  labs(y="Duration", x="Rel") +
  # 分类轴位置调整,coord_flip后自动转到条形右侧
  scale_x_discrete(position = "top") +
  coord_flip()+
  # 手动添加分面标签
  geom_text(data = label_pos, aes(x = x_pos, y = y_pos, label = newCategory),
            hjust = 0, size = 5) +
  theme(
    legend.position='none',
    panel.grid.major = element_line(colour = "grey95"),
    panel.grid.minor = element_blank(),
    panel.background = element_blank(),
    axis.line = element_line(colour = "black"),
    axis.text = element_text(colour = "black"),
    axis.text.x = element_text(size = 12),
    axis.text.y = element_text(size = 12),
    axis.title = element_text(size = 17),
    # 关闭默认分面条带
    strip.text = element_blank(),
    strip.background = element_blank()
  )

ggh4x包简洁实现

如果可以接受安装第三方包,用ggh4x的分面功能可以直接调整分面条带位置,不需要手动计算标签坐标,代码更简洁:

# 首次使用先安装
# install.packages("ggh4x")
library(ggh4x)

ggplot(df, aes(x=rel, y=durationHours_mean, fill=newCategory))+
  geom_bar(stat='identity')+
  scale_fill_manual(values=cols,labels=c('preb','b','i-b','rel','test','i-test'))+
  # 直接设置分面条带显示在右侧
  facet_grid2(rows = vars(newCategory), 
              strip = strip_themed(position = "right"),
              scales = "free_y") + 
  labs(y="Duration", x="Rel") +
  scale_x_discrete(position = "top") +
  coord_flip()+
  theme(
    legend.position='none',
    panel.grid.major = element_line(colour = "grey95"),
    panel.grid.minor = element_blank(),
    panel.background = element_blank(),
    axis.line = element_line(colour = "black"),
    axis.text = element_text(colour = "black"),
    axis.text.x = element_text(size = 12),
    axis.text.y = element_text(size = 12),
    axis.title = element_text(size = 17),
    strip.text.y = element_text(size=12, angle = 0, hjust = 0),
    strip.background = element_blank()
  )

运行后即可得到分面标题在轴刻度中间、分类轴在条形右侧的目标效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 13:33:22