如何在ggplot中合并颜色,线条样式和形状图例

Ben*_*Ben 48 r ggplot2

假设我在ggplot中有以下情节:

ggplot图

它是使用以下代码生成的:

x <- seq(0, 10, by = 0.2)
y1 <- sin(x)
y2 <- cos(x)
y3 <- cos(x + pi / 4)
y4 <- sin(x + pi / 4)
df1 <- data.frame(x, y = y1, Type = as.factor("sin"), Method = as.factor("method1"))
df2 <- data.frame(x, y = y2, Type = as.factor("cos"), Method = as.factor("method1"))
df3 <- data.frame(x, y = y3, Type = as.factor("cos"), Method = as.factor("method2"))
df4 <- data.frame(x, y = y4, Type = as.factor("sin"), Method = as.factor("method2"))

df.merged <- rbind(df1, df2, df3, df4)

ggplot(df.merged, aes(x, y, colour = interaction(Type, Method), linetype = Method, shape = Type)) + geom_line() + geom_point()
Run Code Online (Sandbox Code Playgroud)

我想只有一个正确显示形状,颜色和线条类型的图例(交互(类型,方法)图例最接近我想要的,但它没有正确的形状/线条类型) .

我知道如果我使用scale_xxx_manual并为所有图例指定相同的标签,它们将被合并,但我不想手动设置标签:如果有新的方法或类型,我不希望有修改我的代码:想要通用的东西.

编辑

正如下面的答案所指出的,在这种特殊情况下,有几种方法可以完成工作.所有提出的解决方案都需要通过使用scale_xxx_manual functions或guides函数手动设置图例线类型和形状.

但是,建议的解决方案在一般情况下仍然不起作用:例如,如果我使用新的"method3"方法向数据集添加新数据框,它不再起作用,我们必须手动添加新的图例形状和线条类型:

y5 <- sin(x - pi / 4)
df5 <- data.frame(x, y = y5, Type = as.factor("sin"), Method = as.factor("method3"))
df.merged <- rbind(df1, df2, df3, df4, df5)
override.shape <- c(16, 17, 16, 17, 16)
override.linetype <- c(1, 1, 3, 3, 4)

g <- ggplot(df.merged, aes(x, y, colour = interaction(Type, Method), linetype = Method, shape = Type)) + geom_line() + geom_point()
g <- g + guides(colour = guide_legend(override.aes = list(shape = override.shape, linetype = override.linetype)))
g <- g + scale_shape(guide = FALSE)
g <- g + scale_linetype(guide = FALSE)
print(g)
Run Code Online (Sandbox Code Playgroud)

这给出了:

5条曲线

现在的问题是:如何自动生成override.shapeoverride.linetype向量?

请注意,矢量大小为5,因为我们有5条曲线,而interaction(Type, Method)因子大小为6(我没有cos/method3组合的数据)

Pie*_*une 24

前几天我遇到了这个问题.传说中的R Cookbook部分解释说:

如果同时使用颜色和形状,则需要给出尺度规格.否则会有两个独立的传说.

在您的情况下,您需要shape和的规格linetype.

编辑

创建形状颜色和线条的相同数据非常重要,我通过直接定义列来组合您的交互阶段.我不是scale_linetype_discrete创建图例,而是scale_linetype_manual指定值,因为默认情况下它们将采用四个不同的值.

如果您想要详细布局所有可能的形状和线型,请检查此R图形站点以查看所有数字标识符:

df.merged$int <- paste(df.merged$Type, df.merged$Method, sep=".")

ggplot(df.merged, aes(x, y, colour = int, linetype=int, shape=int)) +
  geom_line() +
  geom_point() +
  scale_colour_discrete("") +
  scale_linetype_manual("", values=c(1,2,1,2)) +
  scale_shape_manual("", values=c(17,17,16,16))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 嗯,这与为线型和形状添加图例的方式相同,但是我认为OP希望将4种具有不同颜色/线型/形状的图例符号组合在一起 (2认同)

lil*_*ets 15

使用labs()和设置相同的值来定义geoms外观的所有美学.

library('ggplot2')
ggplot(iris) + 
  aes(x = Sepal.Length, y = Sepal.Width, 
      color = Species, linetype = Species, shape = Species) +
  geom_line() +
  geom_point() +
  labs(color  = "Guide name", linetype = "Guide name", shape = "Guide name")
Run Code Online (Sandbox Code Playgroud)

  • 与OP的问题不同,这仅在每种美学使用相同的变量时才有效? (5认同)
  • 这是迄今为止允许合并图例类型的最简单的选项。 (2认同)

Ben*_*Ben 10

以下是一般情况下的解决方案:

# Create the data frames
x <- seq(0, 10, by = 0.2)
y1 <- sin(x)
y2 <- cos(x)
y3 <- cos(x + pi / 4)
y4 <- sin(x + pi / 4)
y5 <- sin(x - pi / 4)
df1 <- data.frame(x, y = y1, Type = as.factor("sin"), Method = as.factor("method1"))
df2 <- data.frame(x, y = y2, Type = as.factor("cos"), Method = as.factor("method1"))
df3 <- data.frame(x, y = y3, Type = as.factor("cos"), Method = as.factor("method2"))
df4 <- data.frame(x, y = y4, Type = as.factor("sin"), Method = as.factor("method2"))
df5 <- data.frame(x, y = y5, Type = as.factor("sin"), Method = as.factor("method3"))

# Merge the data frames
df.merged <- rbind(df1, df2, df3, df4, df5)

# Create the interaction
type.method.interaction <- interaction(df.merged$Type, df.merged$Method)

# Compute the number of types and methods
nb.types <- nlevels(df.merged$Type)
nb.methods <- nlevels(df.merged$Method)

# Set the legend title
legend.title <- "My title"

# Initialize the plot
g <- ggplot(df.merged, aes(x,
                           y,
                           colour = type.method.interaction,
                           linetype = type.method.interaction,
                           shape = type.method.interaction)) + geom_line() + geom_point()
# Here is the magic
g <- g + scale_color_discrete(legend.title)
g <- g + scale_linetype_manual(legend.title,
                               values = rep(1:nb.types, nb.methods))
g <- g + scale_shape_manual(legend.title,
                            values = 15 + rep(1:nb.methods, each = nb.types))
# Display the plot
print(g)
Run Code Online (Sandbox Code Playgroud)

结果如下:

解决方案

  • 窦曲线绘制为实线,余弦曲线绘制为虚线.
  • "method1"数据使用实心圆圈表示形状.
  • "method2"数据使用填充三角形作为形状.
  • "method3"数据使用填充的钻石作为形状.
  • 图例与曲线匹配

总结一下,技巧是:

  • interaction对所有数据表示(颜色,形状,线型等)使用类型/方法
  • 然后手动设置曲线样式和图例样式 scale_xxx_manual.
  • scale_xxx_manual allows you to provide a values vector that is longer than the actual number of curves, so it's easy to compute the style vector values from the sizes of the Type and Method factors


Ivo*_*ira 10

只需要将两个指南命名为相同.例如:

g+ scale_linetype_manual(name="Guide1",values= c('solid', 'solid', 'dotdash'))+
   scale_colour_manual(name="Guide1", values = c("blue", "green","red"))
Run Code Online (Sandbox Code Playgroud)


eip*_*i10 6

如果我理解你的问题,下面的代码会产生所需的图例,但我不确定我是否理解标签问题,所以请告诉我这是不是你想要的.

p = ggplot(df.merged, aes(x, y, colour=interaction(Type, Method), 
                          linetype=interaction(Type, Method), 
                          shape=interaction(Type, Method))) + 
  geom_line() + 
  geom_point()

p + scale_shape_manual(values=rep(16:17, 2)) +
  scale_linetype_manual(values=rep(c(1,3),each=2))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述