R ggplot2 在一个数据框中使用多个 geom_bar 自定义图例

R ggplot2 customize legend with multiple geom_bar in one dataframe

我的问题与此 很接近,但又不尽相同。让我解释一下。

我有一个如下所示的数据框:

df <- data.frame(
  'sf'=c('a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c'), 
  'totalsf'=c(28, NA, NA, 32, NA, NA, 40, NA, NA),
  'sl' = c('A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C'),
  'totalsl' = c(35, NA, NA, 40, NA, NA, 25, NA, NA),
  'min' = c('aa', 'bb', 'cc', 'aa', 'bb','cc', 'aa', 'bb', 'cc'),
  'totalmin' = c(30, 4, 0, 8, 0, 25, 8, 9, 16),
  'id' = c(1,2,3,4,5,6,7,8,9))

我主要是想绘制totalsf以sf为填充,totalsl以sl为填充,totalmin以min为填充,全部以geom_bar绘制,如下:

g <- ggplot(df  %>% mutate(id = id), aes(group=id))
g <- g + geom_bar(aes(x=0, y=totalsf, fill=sf), width=.05, stat="identity")
g <- g + geom_bar(aes(x= 0.05, y=totalsl, fill=sl), width=.05, stat="identity")
g <- g + geom_bar(aes(x=0.1, y=totalmin, fill=min), width=.05, stat="identity")
g <- g + theme_light()
g <- g + theme(axis.title.x=element_blank(),
               axis.text.x=element_blank(),
               axis.ticks.x=element_blank(),
               legend.position="bottom")
g <- g + labs(x = "Variable", y = "y", fill = "x")
g <- g + scale_y_continuous(breaks=seq(0, 100, by=10))
print(g)

这会产生下图:

请注意,这就是我想要的(我也知道如何更改颜色,但不要让代码过载)。这是我的问题的核心:图例是可怕的,我希望理想情况下这三个变量有自己的图例,而不是像现在这样按字母顺序排列。有人知道如何自定义图例以便每个变量都有自己的图例吗? (基本上 "sf" 作为 a、b、c 颜色的标题,"sl" 作为 A、B、C 颜色的标题和 "min" 作为 aa、bb、cc 颜色的标题) .

提前感谢您的回答!

最佳,

娜塔莉

我知道没有简单的技巧,但他 ggnewscale 包允许您一次将多个变量映射到多个比例,这将导致图例具有多个标题。您必须指定一个比例,然后指定您要覆盖该比例。基于您的代码的示例:

library(ggnewscale)

g <- ggplot(df %>% mutate(id = id), aes(group = id)) +
  # Note geom_col is shorthand for geom_bar(stat = "identity")
  geom_col(aes(x = 0, y = totalsf, fill = sf), width = 0.05) +
  # Scale has to be specified, not giving colour values will
  # result in all scales being red blue and green.
  # guide_legend(order = 1) ensures that the legends appear in your
  # order instead of alphanumerically
  scale_fill_manual(values = c("red", "green", "blue"), 
                    guide = guide_legend(order = 1)) +
  new_scale_fill() +
  geom_col(aes(x = 0.05, y = totalsl, fill = sl), width = 0.05) +
  scale_fill_manual(values = c("yellow", "magenta", "cyan"), 
                    guide = guide_legend(order = 2)) +
  new_scale_fill() +
  geom_col(aes(x = 0.1, y = totalmin, fill = min), width = 0.05) +
  scale_fill_manual(values = c("black", "grey50", "white"), name = "min") +
  theme_light() +
  theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank(),
        legend.position="bottom") +
  labs(x = "Variable", y = "y", fill = "x") +
  scale_y_continuous(breaks=seq(0, 100, by=10))