如何为facet_rep_grid绘制的分面图添加外部多标签?
给facet_rep_grid分面添加独立左上角标签
我使用facet_rep_grid实现了同一x轴、y轴自由缩放的多分组可视化,需要给每个分面的左上角添加“A”“B”“C”这类独立标签。现有代码如下:
library(dplyr) library(ggplot2) library(ggthemes) library(lemon) library(grid) library(cowplot) # 调用ggplot2内置mpg数据集 mylabs <- c("facet 1", " facet 2", 'facet 3', 'facet 4') names(mylabs) <- c(4,5,6,8) ggplot(mpg,aes(x=year, y=hwy)) + geom_point()+ facet_rep_grid(cyl~., switch='y', scales="free", labeller=labeller(cyl=mylabs))+ theme(strip.placement = "outside", strip.background = element_blank(), axis.title.y = element_blank())
此前尝试的两种方法均存在问题:
- 使用
labs(tag)仅能添加全局单个标签,无法为每个分面单独设置; - 通过
geom_text配合自定义数据添加标签时,无法将标签移至绘图区域外。
以下是两种可行的解决方案:
方法1:基于现有facet_rep_grid添加外部标签
通过准备对应分面的标签数据,结合coord_cartesian(clip = "off")让标签显示在绘图区域外,同时调整边距预留空间:
# 准备标签数据:匹配每个cyl分组的字母标签,设置标签位置 tag_data <- data.frame( cyl = c(4,5,6,8), tag = c("A", "B", "C", "D"), x = min(mpg$year) - 0.5, # 放在year最小值左侧 y = tapply(mpg$hwy, mpg$cyl, max) + 2 # 放在每个分组hwy最大值上方 ) ggplot(mpg,aes(x=year, y=hwy)) + geom_point()+ facet_rep_grid(cyl~., switch='y', scales="free", labeller=labeller(cyl=mylabs))+ # 添加字母标签,关闭继承aes避免冲突 geom_text(data = tag_data, aes(x = x, y = y, label = tag), hjust = 0, fontface = "bold", inherit.aes = FALSE)+ # 关闭绘图区域裁剪,允许标签显示在外部 coord_cartesian(clip = "off")+ theme( strip.placement = "outside", strip.background = element_blank(), axis.title.y = element_blank(), # 调整左侧边距,给标签留出显示空间 plot.margin = margin(t = 10, r = 10, b = 10, l = 30, unit = "pt") )
方法2:用cowplot手动拼接分面(更灵活)
如果facet的限制较多,可以单独绘制每个分面,再用plot_grid拼接,直接为每个子图添加标签:
# 拆分数据,逐个绘制带标签的子图 plots <- lapply(names(mylabs), function(cyl_val) { sub_data <- filter(mpg, cyl == cyl_val) ggplot(sub_data, aes(x=year, y=hwy)) + geom_point()+ labs(title = mylabs[cyl_val], tag = letters[which(names(mylabs) == cyl_val)])+ theme( # 调整标签位置至绘图区域外 plot.tag = element_text(hjust = 0, vjust = 1, margin = margin(l = -15)), plot.title = element_text(hjust = 0, margin = margin(l = 20)), axis.title.y = element_blank() ) }) # 纵向拼接子图,对齐并共享底部x轴 plot_grid(plotlist = plots, ncol = 1, align = "v", axis = "b")
内容的提问来源于stack exchange,提问作者Becci
相关产品推荐
相关产品推荐

