ggplot 条形图 - 按照 x 轴因子拆分填充图例

ggplot bar plot - split fill legend following x-axis factor

是否可以根据图 x 轴上的值拆分 ggplot 条形图的 fill 图例?

例如使用此数据:

library(ggplot2)
data <- data.frame(val=c(2,4,5,6,7,8,9),var1=c("A","A","A","B","B","C","C"),
      var2=sample(LETTERS[1:7]))
ggplot(data,aes(x=factor(var1),y=val,fill=var2))+geom_bar(stat="identity")

我得到以下情节:

我想要这样的东西,以便更容易找到每个 fill 颜色对应的内容:

评论链接中解决方案的替代方案。该解决方案假定数据以聚合形式提供,并且 var2 的每个类别出现在 var1 的一个且仅一个类别中。也就是说,图例中的键数(及其顺序)是正确的。所需要做的就是将 space 插入到适当的键之间,并将文本放入这些 space 中。它从初始绘图或其构建数据中获取构建绘图所需的信息。

library(ggplot2)
library(gtable)
library(grid)

set.seed(1234)
data <- data.frame(val = c(2,4,5,6,7,8,9),
      var1 = c("A","A","A","B","B","C","C"),
      var2 = sample(LETTERS[1:7]))

# Sort levels of var2
data$var2 = factor(data$var2, labels = data$var2, levels = data$var2)

p = ggplot(data, aes(x = factor(var1), y = val, fill = var2)) +
   geom_bar(stat = "identity")

# Get the ggplot grob
g = ggplotGrob(p)

# Get the legend
leg = g$grobs[[which(g$layout$name == "guide-box")]]$grobs[[1]]

# Get the labels from the ggplot build data
gt = ggplot_build(p)
labels = rev(gt$layout$panel_params[[1]]$x.labels)

## Positions of the labels
# Get the number of keys within each label from the ggplot build data
gt$data[[1]]$x
N = as.vector(table(gt$data[[1]]$x))
N = N[-length(N)]
# Get the positions of the labels in the legend gtable
pos = rev(cumsum(N)) + 3
pos = c(pos, 3)

# Add rows to the legend gtable, and add the labels to the new rows
for(i in seq_along(pos)){
leg = gtable_add_rows(leg, unit(1.5, "lines"), pos = pos[i]) 
leg = gtable_add_grob(leg, textGrob(labels[i], y = 0.1, just = "bottom"), 
         t = pos[i] + 1, l = 2)
}

# Put the legend back into the plot
g$grobs[[which(g$layout$name == "guide-box")]]$grobs[[1]] = leg

# Draw it
grid.newpage()
grid.draw(g)