如何合并ggplot中的颜色,线条样式和形状图例 [英] How to merge color, line style and shape legends in ggplot

查看:568
本文介绍了如何合并ggplot中的颜色,线条样式和形状图例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我在ggplot中有下面的图:





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

$ p $ x < - seq(0,10,by = 0.2)$ b $ (x + pi / 4)
y4 < - sin(x + pi / 4)
y2 <-cos(x)
y3 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,color = interaction(Type,Method),linetype = Method,shape = Type))+ geom_line()+ geom_point()

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



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



编辑



正如下面的答案所指出的,在这种特殊情况下有几种方法可以完成工作。所有建议的解决方案都需要通过使用 scale_xxx_manual函数 s或 guides 函数来手动设置图例行的类型和形状。然而,所提出的解决方案在一般情况下仍然不起作用:例如,如果我用新的方法3向数据集添加新的数据框方法,它不再工作,我们必须手动添加新的图例形状和线型:

  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,color = interaction(Type,Method),linetype = Method, (color = guide_legend(override.aes = list(shape = override.shape,linetype = override.linetype)))$ b(&#160;&#160;形式=类型))+ geom_line()+ geom_point()
g< - g + $ bg <-g + scale_shape(guide = FALSE)
g <-g + scale_linetype(guide = FALSE)
print(g)

这给出:



现在问题是:如何自动生成 override.shape override.linetype 向量请注意,向量大小为5,因为我们有5条曲线,而交互(Type,Method)因子的大小为6(我没有cos / method3组合的数据)

解决方案

这里是一般的解决方案case:

 #创建数据帧
x< - seq(0,10,by = 0.2)$ b $ x 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.fact或(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(方法= as.factor(method3))

#合并数据帧
df.merged< - rbind(df1,df2,df3,df4,df5)

#创建交互
type.method.interaction< - interaction(df.merged $ Type,df.merged $ Method )

#计算类型和方法的数量
nb.types< - nlevels(df.merged $类型)
nb.methods< - nlevels(df.merged $方法)

#设置图例标题
legend.title< - 我的标题

#初始化图
g< - ggplot (df.merged,aes(x,
y,
color = type.method.interacti on,
linetype = type.method.interaction,
shape = type.method.interaction))+ geom_line()+ geom_point()
#这是神奇的
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))
#显示绘图
print(g)

结果如下:




  • 正弦曲线和余弦曲线绘制为虚线。 b
  • method1数据使用实心圆形形状。

  • method2数据使用实心三角形形状。

  • method3数据使用实心形状的钻石。

  • 图例匹配曲线


总之,这些技巧是:


  • 使用类型/方法交互 code>用于所有数据表示(颜色,形状,
    线型等)
  • 然后手动将曲线样式和图例样式设置为
    scale_xxx_manual
  • scale_xxx_manual 允许您提供更长的值向量而不是实际的曲线数量,所以很容易根据类型和方法因子的大小来计算样式矢量值


Suppose I have the following plot in ggplot:

It was generated using the code below:

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()

I would like to have only one legend that correctly displays the shapes, the colors and the line types (the interaction(Type, Method) legends is the closest to what I would like, but it does not have the correct shapes/line types).

I know that if I use scale_xxx_manual and I specify the same labels for all legends they will be merged, but I don't want to have to set the labels manually: if there are new Methods or Types, I don't want to have to modify my code: a want something generic.

Edit

As pointed in answers below, there are several ways to get the job done in this particular case. All proposed solutions require to manually set the legend line types and shapes, either by using scale_xxx_manual functions or with guides function.

However, the proposed solutions still don't work in the general case: for instance, if I add a new data frame to the data set with a new "method3" Method, it does not work anymore, we have to manually add the new legend shapes and line types:

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)

This gives:

Now the question is: how to automatically generate the override.shape and override.linetype vectors?

Note that the vector size is 5 because we have 5 curves, while the interaction(Type, Method) factor has size 6 (I don't have data for the cos/method3 combination)

解决方案

Here is the solution in the general case:

# 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)

The result is the following:

  • Sinus curves are drawn as solid lines and cosinus curves as dashed lines.
  • "method1" data use filled circles for the shape.
  • "method2" data use filled triangle for the shape.
  • "method3" data use filled diamonds for the shape.
  • The legend matches the curve

To summarize, the tricks are :

  • Use the Type/Method interaction for all data representations (colour, shape, linetype, etc.)
  • Then manually set both the curve styles and the legends styles with 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

这篇关于如何合并ggplot中的颜色,线条样式和形状图例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆