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
相关产品推荐
相关产品推荐

