哪些因素会影响 ggplot 图例的排序方式

What factors effect how ggplot legends are ordered

我正在 R 中创建一个散点图,用户可以在其中添加或删除显示固定参考值的水平线。这样做时,我注意到更改参考线的名称会重新排列图例,因此水平线有时会出现在散点图例元素之前,有时会出现在散点图例元素之后。

比较:

下面是一个可重现的例子


YEAR = as.integer(rep(2010:2020,5))
SERIES_NAME = rep(LETTERS[1:5], each = 11)
OBS_VALUE = runif(n = 55, min = -5, max = 20)
EA = ifelse(SERIES_NAME=='A', 'Option 1', 'Option 2')

df <- data.frame(YEAR=YEAR,
            SERIES_NAME=SERIES_NAME,
            OBS_VALUE=OBS_VALUE,
            EA=EA) 

注释掉两条线中的一条以生成图表,在其中命名图例上的水平线。

aaaaaaa <- "RGCUZYMSFP"  # appears above
aaaaaaa <- "IZTCYUXGBO"  # appears below

然后生成图表:


df %>% 
  select(YEAR,SERIES_NAME, OBS_VALUE, EA) %>%
  ggplot() + 
  ggplot2::geom_point(
    ggplot2::aes(
      x = YEAR,
      y = OBS_VALUE,
      col = EA),
    size = 2) +
  ggplot2::guides(
    color = ggplot2::guide_legend(nrow = 2, 
                                  byrow = TRUE))+ 
  scale_linetype_manual(values = 2) +
  scale_x_continuous(breaks = seq(2010,2020,5))+
  geom_hline(aes(yintercept = EAMean,
                 linetype = aaaaaaa),
             size = 1, color = "black")  

我还注意到更改变量的名称会更改输出。如果我将变量的名称从 aaaaaaaa(字母 a 的 8 倍)更改为 aaaaaaa(字母 a 的 7 倍)并相应地更新水平线的代码,图例将重新排序

有什么方法可以让我更一致地控制图例项目的去向?

正如@stefan 正确指出的那样,它取决于 'secret algorithm'。如果未设置 'order',则算法的结果是不可预测的,但我们可以对其进行逆向工程。

guide_legend() 方法的 these lines 中,我们看到构建的 'hash' 对于指南的标题、标签、方向和名称是(相对)唯一的。这里的不可预测性在于散列,它可以为相对相似(但不相同)的输入创建广泛不同的散列。

稍后,在 guides_merge() 内部函数中,我们可以看到指南(或指南定义)在其散列上被拆分。由于哈希对相同的输入产生相同的结果,这会指示 ggplot2 这些指南是否 'mergeable' 由于共享标题、标签、方向和名称。

'order' 参数的作用是将 'order' 粘贴在散列前面,因此在字典顺序中 order = 0 的指南位于 [=13= 的指南之前].未设置顺序参数的指南将获得 99 作为顺序。因为拆分 returns 会根据拆分级别产生排序顺序,这有效地首先对输出进行排序,其次是散列。