R语言 带有线型和颜色两个图例的“ggplot”

h9a6wy2h  于 2023-02-14  发布在  其他
关注(0)|答案(1)|浏览(174)

我们有一个数据

x <- 1:10

y1 <- x
y2 <- x^2
y3 <- x + 1

z1 <- c("m", "m", "m", "m", "m", "m", "m", "n", "n", "n")
z2 <- c("n", "n", "n", "n", "n", "n", "p", "p", "p", "p")
z3 <- c("m", "m", "m", "m", "m", "n", "n", "n", "p", "p")

df1 <- data.frame(x, y1, z1)
df2 <- data.frame(x, y2, z2)
df3 <- data.frame(x, y3, z3)

我想创建一个图,其中df1为红色,df2为蓝色,df3为绿色,并具有基于颜色的图例。
我也想改变基于矢量z的线型,并有一个图例。
这是我可以编写的代码

ggplot() +
  geom_line(data = df1, aes(x, y1, linetype = z1, color = "#f8766d"), size = 1, show.legend = TRUE) +
  geom_line(data = df2, aes(x, y2, linetype = z2, color = "#619cff"), size = 1, show.legend = TRUE) +
  geom_line(data = df3, aes(x, y3, linetype = z3, color = "#00ba38"), size = 1, show.legend = TRUE) +
  scale_linetype_manual(values = c("m" = "solid", "n" = "dotted", "p" = "dashed"), guide = "legend", labs(title = "Line type legend")) +
  scale_color_manual(values = c("#f8766d", "#619cff", "#00ba38"), guide = "legend", labs(title = "color legend"), labels = c("y1", "y2", "y3")) +
  xlim(0,10) +
  ylim(0,10)

并且输出是

问题是在图例中,颜色显示正确,但在图中,y1y3的颜色交换。
我可以通过添加

scale_color_identity() +

但是添加这行会删除颜色图例!
有人能帮忙吗?

qni6mghb

qni6mghb1#

我想你可以通过两个改变来解决这个问题:

  • color=文字设置为要在图例中显示的 * label *,并
  • 命名你的手动颜色(并删除labels=)。
ggplot() +
  geom_line(data = df1, aes(x, y1, linetype = z1, color = "y1"), size = 1, show.legend = TRUE) +
  geom_line(data = df2, aes(x, y2, linetype = z2, color = "y2"), size = 1, show.legend = TRUE) +
  geom_line(data = df3, aes(x, y3, linetype = z3, color = "y3"), size = 1, show.legend = TRUE) +
  scale_linetype_manual(values = c("m" = "solid", "n" = "dotted", "p" = "dashed"), guide = "legend", labs(title = "Line type legend")) +
  scale_color_manual(values = c(y1="#f8766d", y2="#619cff", y3="#00ba38"), guide = "legend", labs(title = "color legend")) +
  xlim(0,10) +
  ylim(0,10)

额外学分:您可以考虑透视和合并数据,以便可以使用一个geom

library(dplyr)
library(tidyr)
dflong <- lapply(
    list(df1, df2, df3), pivot_longer,
    -x, names_pattern = "(\\D+)(\\d+)", names_to = c(".value", "num")) %>% 
  bind_rows(.id = "id")
ggplot(dflong) +
  geom_line(aes(x, y, linetype = z, color = num), na.rm = TRUE) +
  scale_linetype_manual(values = c("m" = "solid", "n" = "dotted", "p" = "dashed"), guide = "legend", labs(title = "Line type legend")) +
  scale_color_manual(values = c("1"="#f8766d", "2"="#619cff", "3"="#00ba38"), guide = "legend", labs(title = "color legend")) +
  xlim(0,10) +
  ylim(0,10)

注:

  • 我们在这里没有使用id,因为在这个例子中,它看起来与num=在透视中是多余的。不确定这是否重要,我至少会保留它以供讨论。
  • color legend内的标签现在仅为1、2和3,如由原始数据中的数字部分y1y2y3所确定的;您可以轻松地将它们更改为您需要的任何内容,例如
dflong <- lapply(
    list(df1, df2, df3), pivot_longer,
    -x, names_pattern = "(\\D+)(\\d+)", names_to = c(".value", "num")) %>% 
  bind_rows(.id = "id") %>%
  mutate(num = paste0("y", num))
  • 从第一个代码块中的多个帧和这种单帧更长的思想转变的动力是,如果您添加组(例如,df4df13),则需要添加对geom_line的多个调用,并且可能添加您可能需要的任何其他geom;在这个较长的版本中,您将我迭代透视/行绑定的帧包含在list(...)中,然后绘图基本上可以工作。只要您手动控制linetype=color=,您将总是需要多做一点工作。

相关问题