ggplot2/ggh4x 中的多个图例确实相互干扰

Multiple Legends in ggplot2/ggh4x do interfere with each other

我有一个相当复杂的情节,需要我用 ggh4x::scale_listed 创建的多个图例。一切正常,但第二个叠加条形图为 fill 变量创建了一个额外的图例。

target: IN OUT

除了我基本上“隐藏”不需要的图例的非常老套的解决方案之外,还有其他方法可以解决这个问题吗?

请注意,我的实际情节要复杂得多,我想保留一般结构,包括自定义图例。

library(ggplot2)
library(ggh4x)
my_data1 <- data.frame(case = "UK",
                       target = rep(c("IN", "OUT"), 5),
                       values = 1:10,
                       step = as.character(rep(1:2, 5)),
                       label = rep(c("A", "B"), 5))

p <- ggplot() +
  geom_bar(data = my_data1,
           position = position_stack(reverse = TRUE),
           mapping = aes(x = step, 
                         y = values, 
                         fill = target,
                         my_target_scale = target),
           stat = "identity",
           na.rm = TRUE) +
  
  # overwite prior data
  geom_bar(data = data.frame(step = 1:2,
                             purpose = "TOTAL",
                             values = c(20, 40)),
           
           # do not inherit easthetics
           inherit.aes = FALSE,
           mapping = aes(x = step,
                         y = values, 
                         # doesnt work
                         # color = purpose,
                         my_total_scale = purpose),
           show.legend = TRUE,
           position = "stack", 
           stat = "identity",
           # doesnt work
           # color = "black", 
           fill = NA,
           na.rm = TRUE) +
  ggh4x::scale_listed(scalelist = list(
    scale_fill_manual(aesthetics = "my_target_scale",
                      name = "GROUP:",
                      values = c("IN" = "red",
                                 "OUT" = "green"),
                      breaks = c("IN", "OUT"),
                      labels = c("Incoming", "Outgoing")
    ),
    scale_color_manual(aesthetics = "my_total_scale",
                       name = "Label:",
                       values = c("TOTAL" = "black"), 
                       breaks = c("TOTAL"),
                       labels = c("EVErYTHING")
    )
    # very hacky "solution"
    # ,scale_color_manual(aesthetics = "fill",
    #                    name = "",
    #                    values = c("IN", "OUT"), 
    #                    breaks = c("IN"),
    #                    labels = c(""))
  ),
  replaces = c("fill", 
               "color"
               # part of the hacky solution
               # ,"fill"
  )) +
  theme_bw() +
  theme(panel.spacing = unit(.01, "lines"),
        legend.position = "bottom",
        legend.box = "horizontal")
#> Warning: Ignoring unknown aesthetics: my_target_scale
#> Warning: Ignoring unknown aesthetics: my_total_scale

reprex package (v2.0.0)

于 2021-10-06 创建

如果我没理解错的话,你不想要有 'target: -in -out' 位的图例?如果你只是省略第一层的 fill = target 行呢?

library(ggplot2)
library(ggh4x)
my_data1 <- data.frame(case = "UK",
                       target = rep(c("IN", "OUT"), 5),
                       values = 1:10,
                       step = as.character(rep(1:2, 5)),
                       label = rep(c("A", "B"), 5))

ggplot() +
  geom_bar(data = my_data1,
           position = position_stack(reverse = TRUE),
           mapping = aes(x = step, 
                         y = values, 
                         my_target_scale = target),
           stat = "identity",
           na.rm = TRUE) +
  
  # overwite prior data
  geom_bar(data = data.frame(step = 1:2,
                             purpose = "TOTAL",
                             values = c(20, 40)),
           
           # do not inherit easthetics
           inherit.aes = FALSE,
           mapping = aes(x = step,
                         y = values, 
                         my_total_scale = purpose),
           show.legend = TRUE,
           position = "stack", 
           stat = "identity",
           fill = NA,
           na.rm = TRUE) +
  ggh4x::scale_listed(scalelist = list(
    scale_fill_manual(aesthetics = "my_target_scale",
                      name = "GROUP:",
                      values = c("IN" = "red",
                                 "OUT" = "green"),
                      breaks = c("IN", "OUT"),
                      labels = c("Incoming", "Outgoing")
    ),
    scale_color_manual(aesthetics = "my_total_scale",
                       name = "Label:",
                       values = c("TOTAL" = "black"), 
                       breaks = c("TOTAL"),
                       labels = c("EVErYTHING")
    )
  ),
  replaces = c("fill", 
               "color"
  )) +
  theme_bw() +
  theme(panel.spacing = unit(.01, "lines"),
        legend.position = "bottom",
        legend.box = "horizontal")
#> Warning: Ignoring unknown aesthetics: my_target_scale
#> Warning: Ignoring unknown aesthetics: my_total_scale

reprex package (v2.0.0)

于 2021-10-07 创建