First set up the legend:
library(ggplot2)
library(ggpubr)
p <- ggplot(mtcars, aes(x=mpg, y=disp, color=as.character(cyl))) + geom_point()
legendp <- ggpubr::get_legend(p)
From legendp$grobs[[1]]
, we know that the labels are probably stored in grobs 9 to 11:
legendp$grobs[[1]]
# TableGrob (7 x 6) "layout": 11 grobs
# z cells name grob
# 1 1 (1-7,1-6) background rect[legend.background..rect.19172]
# 2 2 (2-2,2-5) title gTree[GRID.gTree.19173]
# 3 3 (4-4,2-2) key-3-1-bg rect[legend.key..rect.19163]
# 4 4 (4-4,2-2) key-3-1-1 points[GRID.points.19164]
# 5 5 (5-5,2-2) key-4-1-bg rect[legend.key..rect.19166]
# 6 6 (5-5,2-2) key-4-1-1 points[GRID.points.19167]
# 7 7 (6-6,2-2) key-5-1-bg rect[legend.key..rect.19169]
# 8 8 (6-6,2-2) key-5-1-1 points[GRID.points.19170]
# 9 9 (4-4,4-4) label-3-3 gTree[GRID.gTree.19174]
# 10 10 (5-5,4-4) label-4-3 gTree[GRID.gTree.19175]
# 11 11 (6-6,4-4) label-5-3 gTree[GRID.gTree.19176]
Then we can unlist
grobs 9 to 11 (with which(grepl("label", legendp$grobs[[1]]$layout$name))
to dynamically output the target grobs). The labels are stored under a sublist element with a name that starts with "children.guide.label" and ends with "label", therefore we can grep
that pattern to get our target labels
legendp_grobs9_11 <- unlist(legendp$grobs[[1]]$grobs[which(grepl("label", legendp$grobs[[1]]$layout$name))])
unname(legendp_grobs9_11[grepl("children.guide.label.*text.*label$", names(legendp_grobs9_11))])
# [1] "4" "6" "8"
Another example to show it works.
library(tidyverse)
library(ggpubr)
p2 <- ggplot(diamonds, aes(cut, price, col = cut)) + geom_point()
p2
legendp2 <- get_legend(p2)
legendp2_grobs13_17 <- unlist(legendp2$grobs[[1]]$grobs[which(grepl("label", legendp2$grobs[[1]]$layout$name))])
unname(legendp2_grobs13_17[grepl("children.guide.label.*text.*label$", names(legendp2_grobs13_17))])
#> [1] "Fair" "Good" "Very Good" "Premium" "Ideal"
Created on 2023-06-09 with reprex v2.0.2