即使手动覆盖,ggplot2 图例也不匹配

ggplot2 legend is not matching even with manual overrides

我似乎无法找到与我的图表匹配的图例。我已经移动了形状并在 aes 内部填充了 aes。手动覆盖后堆栈溢出,似乎没有任何效果。

所以,我有四点(视觉上只出现三点:这对我的目的来说很好)。两点呈菱形,一绿一蓝;然后两个是圆圈,一个是绿色的,另一个是蓝色的。所以我希望图例上有四个点充满了颜色——所以有两颗钻石:一颗绿色,一颗蓝色。然后是两个圆圈:一绿一蓝。

这个graph的颜色和形状都恰到好处。有人可以帮忙解决传奇问题吗? (我不想要线条的颜色,只想要形状和填充)。

可重现的代码

colours <- data.frame(purple = '#411D64',
                  blue = '#486C8B',
                  green = '#70B87B')

library(ggplot2)
library(latex2exp)

size_y_s0 <- data.frame(
  name = 'Size Anchor',
  shape = 'size0',
  x = 0,
  y = 1,
  colour = colours$blue
)

size_y_sn <- data.frame(
  name = 'Size Response',
  shape = 'size*',
  x = 0.4,
  y = 0.9,
  colour = colours$blue
)

income_x_s0 <- data.frame(
  name = 'Income Anchor',
  shape = 'income0',
  x = 1,
  y = 0,
  colour = colours$green
)

income_x_sn <- data.frame(
  name = 'Income Response',
  shape = 'income*',
  x = 0.9,
  y = 0.4,
  colour = colours$green
)

size_y_dcc <- data.frame(
  name = "$D^{c}_{c}$",
  x = c(0,0.4),
  y = c(1,0.9),
  colour = colours$blue
)
size_y_dcc_text <- data.frame(
  name = "$D^{c}_{c}$",
  text_x = 0.38,
  text_y = 0.99,
  angle = 352
)
size_y_dcp <- data.frame(
  name = "$D^{c'}_{c}$",
  x = c(0,0.9),
  y = c(1,0.4),
  colour = colours$green
)

size_y_dcp_text <- data.frame(
  name = "$D^{c'}_{c}$",
  text_x = 0.8,
  text_y = 0.56,
  angle = 340
)

data_plot1 <- list(
  size_y_s0,
  size_y_sn,
  income_x_s0,
  income_x_sn,
  size_y_dcc,
  size_y_dcp,
  size_y_dcp_text,
  size_y_dcc_text
)

ggplot() +
  geom_line(data = data_plot1[[5]],
            aes(x = x, y = y), colour = data_plot1[[5]]$colour, size = 5, show.legend = FALSE
  ) +
  geom_line(data = data_plot1[[6]],
            aes(x = x, y = y), colour = data_plot1[[6]]$colour, size = 5, show.legend = FALSE
  ) +
  geom_point(data = data_plot1[[1]],
             aes(x = x, y = y, fill = colour, shape = shape),fill = data_plot1[[1]]$colour, shape = 21, size = 5, show.legend = TRUE
             ) +
  geom_point(data = data_plot1[[2]],
             aes(x = x, y = y, fill = colour, shape = shape), fill = data_plot1[[2]]$colour, shape = 23, size = 5, show.legend = TRUE
  ) +
  geom_point(data = data_plot1[[3]],
             aes(x = x, y = y, fill = colour, shape = shape), fill = data_plot1[[3]]$colour, shape = 21, size = 5, show.legend = TRUE
  ) +
  geom_point(data = data_plot1[[4]],
             aes(x = x, y = y, fill = colour, shape = shape), fill = data_plot1[[4]]$colour, shape = 23, size = 5, show.legend = TRUE
  ) +
  annotate(
    geom = "text", 
           x = data_plot1[[7]]$text_x, 
           y = data_plot1[[7]]$text_y, 
           label = TeX(data_plot1[[7]]$name), 
           size = 15,
           angle = data_plot1[[7]]$angle)+
  annotate(
    geom = "text", 
    x = data_plot1[[8]]$text_x, 
    y = data_plot1[[8]]$text_y, 
    label = TeX(data_plot1[[8]]$name), 
    size = 15,
    angle = data_plot1[[8]]$angle) +
  scale_fill_manual(
    name = 'Legend',
    guide = 'legend',
    labels = c(
      data_plot1[[1]]$name,
      data_plot1[[2]]$name,
      data_plot1[[3]]$name,
      data_plot1[[4]]$name
    ),
    values = c(
      data_plot1[[1]]$colour,
      data_plot1[[2]]$colour,
      data_plot1[[3]]$colour,
      data_plot1[[4]]$colour
    )
  ) +
  scale_shape_manual(
    name = 'Legend',
    guide = 'legend',
    labels = c(
      data_plot1[[1]]$name,
      data_plot1[[2]]$name,
      data_plot1[[3]]$name,
      data_plot1[[4]]$name
    ),
    values = c(
      23,
      21,
      23,
      21
    )
  )

我没有足够的代表将其作为评论,但也许这个有帮助:

在我看来,您的图例甚至没有出现在这个代码示例中。这可能是因为 ggplot 只为美学映射创建图例(在 aes 函数中)。但是,您的每个 geom_point() 只使用一个具有一行和可变级别的数据框。这是因为 geom 不相互传递它们的数据,因为它是在每个 geom 中本地定义的。您可以考虑一种将所有数据帧绑定到 ggplot 兼容 'long' 格式的方法(例如 pivot_longer() 和 bind_rows()),因此您只需要一个 geom_line() 和一个 geom_point() 映射颜色并填充数据中的某种组。

您希望提供给 ggplot 的数据形状符合您的预期,其样式如下:

p1 = data.frame(group = c('income','income'), x = c(0, 0.5), y = c(1,0.8))
p2 = data.frame(group = c('size','size'), x = c(0, 0.8), y = c(1,0.25))

dat <- rbind(p1,p2)
ggplot(dat) + geom_point(aes(x = x, y = y, fill = group, shape = group, col = group)) + 
  geom_line(aes(x=x,y=y, col = group))

我认为使用列表 data_plot1 作为数据框列表对于绘图目的来说不是一个好的选择。您可以在多个数据框(点、文本等)上拆分 geom,并更好地控制 aes。看一个例子

colours <- data.frame(
  purple = "#411D64",
  blue = "#486C8B",
  green = "#70B87B"
)

library(ggplot2)
library(latex2exp)

size_y_s0 <- data.frame(
  name = "Size Anchor",
  shape = "size0",
  x = 0,
  y = 1,
  colour = colours$blue
)

size_y_sn <- data.frame(
  name = "Size Response",
  shape = "size*",
  x = 0.4,
  y = 0.9,
  colour = colours$blue
)

income_x_s0 <- data.frame(
  name = "Income Anchor",
  shape = "income0",
  x = 1,
  y = 0,
  colour = colours$green
)

income_x_sn <- data.frame(
  name = "Income Response",
  shape = "income*",
  x = 0.9,
  y = 0.4,
  colour = colours$green
)

size_y_dcc <- data.frame(
  name = "$D^{c}_{c}$",
  x = c(0, 0.4),
  y = c(1, 0.9),
  colour = colours$blue
)
size_y_dcc_text <- data.frame(
  name = "$D^{c}_{c}$",
  text_x = 0.38,
  text_y = 0.99,
  angle = 352
)
size_y_dcp <- data.frame(
  name = "$D^{c'}_{c}$",
  x = c(0, 0.9),
  y = c(1, 0.4),
  colour = colours$green
)

size_y_dcp_text <- data.frame(
  name = "$D^{c'}_{c}$",
  text_x = 0.8,
  text_y = 0.56,
  angle = 340
)

# data frames for the plot
df_points <- rbind(
  size_y_s0,
  size_y_sn,
  income_x_s0,
  income_x_sn
)
df_tex <- rbind(size_y_dcp_text, size_y_dcc_text)

ggplot() +
  # Lines
  geom_line(
    data = size_y_dcc,
    aes(x = x, y = y), colour = size_y_dcc$colour, size = 5, show.legend = FALSE
  ) +
  geom_line(
    data = size_y_dcp,
    aes(x = x, y = y), colour = size_y_dcp$colour, size = 5, show.legend = FALSE
  ) +
  # Points
  geom_point(data = df_points, aes(x, y, shape = shape, fill = shape), size = 5) +
  scale_shape_manual(
    name = "Legend",
    guide = "legend",
    values = c(23, 21, 23, 21), labels = df_points$name
  ) +
  scale_fill_manual(
    values = rev(df_points$colour), labels = df_points$name,
    name = "Legend", guide = "legend"
  ) +
  annotate(
    geom = "text",
    x = df_tex$text_x,
    y = df_tex$text_y,
    label = TeX(df_tex$name),
    size = 10,
    angle = df_tex$angle
  )