代码之家  ›  专栏  ›  技术社区  ›  Bogaso

以定义的方式排列图例中的项目

  •  2
  • Bogaso  · 技术社区  · 2 年前

    我有以下 ggplot

    library(ggplot2)
    DF = data.frame(val = c(10,20,30,40,50,60,70,80,90,100), param = rep(letters[1:5],2), x = rep(c('X', 'Y'), 5))
    ggplot(data = DF) + geom_bar(aes(y = val, fill = param, x = x), stat = 'identity', position = position_dodge2(preserve = 'single')) + guides(fill = guide_legend(nrom = 2, byrow = TRUE))
    

    虽然我可以生成绘图,但我希望以如下特定方式排列图例中的项目。

    1. 前2项,即。 a & b 应该在第一行
    2. 剩余项目应按阵列方式排列 具有3列和适用的行数 基于除前2项之外的项目数量,即。 a&b ,从第二行开始(第一行只包含 a&b )
    3. 我也想 大胆的面孔 项目 a&b 只是,在传说中

    有什么办法可以实现这种定制安排吗?

    根据@stefan的善意回答,我修改了我的代码如下

    library(ggplot2)
    library(scales)
    library(dplyr)
    
    DF = data.frame(val = c(10,20,30,40,50,60,70,80,90,100), param = rep(letters[1:5],2), x = rep(c('X', 'Y'), 5))
    
    DF$param <- factor(DF$param, c("a", "b", "spacer", "c", "d", "e"))
    
    pal_fill <- scales::hue_pal()(5)
    names(pal_fill) <- letters[1:5]
    
    pal_fill <- c(pal_fill, spacer = "transparent")
    
    ggplot(data = DF) +
      geom_col(aes(y = val, fill = param, x = x), alpha = 0.6,
        position = position_dodge2(preserve = "single")
      ) +
      scale_fill_manual(
        values = pal_fill,
        drop = FALSE,
        labels = ~ dplyr::case_match(
          .x, "spacer" ~ "", c("a", "b") ~ paste0("**", .x, "**"),
          .default = .x)
      ) +
      guides(fill = guide_legend(
        nrow = 2, byrow = TRUE
      )) +
      theme(
        legend.position=c(.9,.75),
        legend.background = element_rect(fill = alpha('#e5e5e5', 0.60)),
        #legend.text = ggtext::element_markdown(),
        legend.key = element_rect(fill = "transparent")
      )
    

    正如你所看到的,我看到了 white 传说中的补丁。如果我删除它,它实际上会熄灭 alpha = 0.6 在里面 geom_col .这对我来说很奇怪,因为我不明白 alpha 在里面 geom_col 和图例项目。

    是否有任何方法可以纠正此问题,即移除 白色 色斑

    任何指针都将非常有用。

    0 回复  |  直到 2 年前
        1
  •  2
  •   stefan    2 年前

    如果我理解正确,那么实现您想要的结果的一种方法是添加一些虚假的图例条目,我们通过移除标签并将填充颜色设置为例如,使图例键“不可见”。 "transparent"

    作为第一步,这需要转换 param 并在正确的位置添加伪元素。此外,我们必须设置 drop=FALSE 以使未使用的伪元素实际显示在图例中。最后,只加粗一些图例元素是最简单的任务,可以通过 ggtext::element_markdown

    注意:根据 theme 将填充颜色设置为 “透明” 不足以使伪元素不可见,例如在默认情况下 theme_grey 按键的背景填充为灰色。因此,我补充道 legend.key = element_rect(fill = "transparent") 以使背景填充也透明。

    library(ggplot2)
    library(scales)
    library(dplyr)
    
    DF$param <- factor(DF$param, c("a", "b", "spacer", "c", "d", "e"))
    
    pal_fill <- scales::hue_pal()(5)
    names(pal_fill) <- letters[1:5]
    
    pal_fill <- c(pal_fill, spacer = "transparent")
    
    ggplot(data = DF) +
      geom_col(aes(y = val, fill = param, x = x),
        position = position_dodge2(preserve = "single")
      ) +
      scale_fill_manual(
        values = pal_fill,
        drop = FALSE,
        labels = ~ dplyr::case_match(
          .x, "spacer" ~ "", c("a", "b") ~ paste0("**", .x, "**"),
          .default = .x)
      ) +
      guides(fill = guide_legend(
        nrow = 2, byrow = TRUE
      )) +
      theme(
        legend.text = ggtext::element_markdown(),
        legend.key = element_rect(fill = "transparent")
      )
    

    enter image description here

    编辑 不得不承认,我不知道到底是什么问题,但解决办法是 alpha 对于我使用的“垫片”为零 after_scale if_else 在里面 geom_col :

    ggplot(data = DF) +
      geom_col(
        aes(
          y = val, fill = param, x = x,
          alpha = after_scale(if_else(fill != "transparent", .6, 0))
        ),
        position = position_dodge2(preserve = "single")
      ) +
      scale_fill_manual(
        values = pal_fill,
        drop = FALSE,
        labels = ~ dplyr::case_match(
          .x, "spacer" ~ "", c("a", "b") ~ paste0("**", .x, "**"),
          .default = .x
        )
      ) +
      guides(fill = guide_legend(
        nrow = 2, byrow = TRUE
      )) +
      theme(
        legend.position = c(.9, .75),
        legend.background = element_rect(fill = alpha("#e5e5e5", 0.60)),
        #legend.text = ggtext::element_markdown(),
        legend.key = element_rect(fill = "transparent")
      )
    

    enter image description here