在 ggplot 中为垂直线添加第二个图例

Adding a second legend for vertical lines in ggplot

我正在尝试为我添加到 ggplot2 线图上的 6 条垂直线添加第二个图例,代表 2 个事件中的 1 个,而不是使用 annotate 函数标记线。我试过这段代码,但我看不太清楚:

p<- data %>% 
  ggplot(aes(variable, value)) +
  geom_line(aes(color = size, group = size)) + 
  geom_vline(xintercept = c(1,9,11), linetype="dashed") +
  geom_vline(xintercept = c(5,14,17), linetype="dotted") +
  scale_linetype_manual(name = 'Events',
                        values = c('Closures' = 3,
                                   'Opening' = 3)) 

geom_label呢?

library(tidyverse)

data <- tribble(
  ~x, ~label,
  1, "first",
  1.5, "second",
  5, "third"
)

data %>%
  ggplot(aes(x = x, y = 1)) +
  geom_vline(aes(xintercept = x)) +
  geom_label(aes(label = label))

reprex package (v2.0.1)

于 2021-12-13 创建

执行此操作的一个好方法是使用 mapping= 为您在同一情节中创建第二个图例。关键是对垂直线和其他线和点使用不同的美学。

首先,示例数据和绘图:

library(ggplot2)
library(dplyr)
library(tidyr)

set.seed(8675309)
df <- data.frame(x=rep(1:25, 4), y=rnorm(100, 10, 2), lineColor=rep(paste0("col",1:4), 25))

base_plot <-
df %>%
  ggplot(aes(x=x, y=y)) +
  geom_line(aes(color=lineColor)) +
  scale_color_brewer(palette="Greens")
base_plot

现在按照 OP 在他们的问题中所做的那样添加垂直线:

base_plot +
  geom_vline(xintercept = c(1,9,11), linetype="dotted", 
            color = "red", size=1) +
  geom_vline(xintercept = c(5,14,17), linetype="dotted", 
             color = "blue", size=1)

要添加图例,我们需要在 mapping= 中添加另一种美学。当您使用 aes() 时,ggplot2 期望映射包含与 data= 中指定的数据集相同数量的观测值。在这种情况下,df 有 100 个观察值,但我们只需要 6 行。解决此问题的最简单方法是创建一个单独的小型数据集,用于垂直线。此数据框只需要包含两列:一列用于 xintercept,另一列可以映射到 linetype:

verticals <- data.frame(
  intercepts=c(1,9,11,5,14,17),
  Events=rep(c("Closure", "Opening"), each=3)
)

然后您可以在代码中使用它,并在我们的基本图中添加一个 geom_vline() 调用:

second_plot <- base_plot +
  geom_vline(
    data=verticals,
    mapping=aes(xintercept=intercepts, linetype=Events),
    size=0.8, color='blue',
    key_glyph="path"   # this makes the legend key horizontal lines, not vertical
  )
second_plot

虽然这个答案没有使用颜色来区分垂直线,但它最符合 ggplot2 所依据的图形语法原则。否则颜色已经用于指示数据中的差异,因此您可能希望使用不同的美学来分离垂直线。我使用了这些 GG 原则中的一些来组合这个答案 - 抱歉,虽然大声笑,但调色板很糟糕。在这种情况下,我对数据行使用了顺序色标,并使用不同的颜色来分隔垂直线。我显示的垂直线大小与 df 中的线不同,以进一步区分并使用线型作为垂直线之间的歧视性美学。

您可以使用这个总体思路并应用您认为最适合您自己的数据的美学。