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

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

问题描述

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

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

我希望只有一个图例可以正确显示形状、颜色和线型(interaction(Type, Method) 图例最接近我想要的,但它没有正确的形状/线型).

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

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

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.

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

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.

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

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)

这给出了:

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

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

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

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)

结果如下:

  • 正弦曲线绘制为实线,余弦曲线绘制为虚线.
  • method1"数据使用实心圆作为形状.
  • method2"数据使用实心三角形作为形状.
  • method3"数据使用实心菱形表示形状.
  • 图例与曲线相匹配

总而言之,技巧是:

  • 对所有数据表示(颜色、形状、线型等)
  • 然后手动设置曲线样式和图例样式scale_xxx_manual.
  • scale_xxx_manual 允许您提供比实际曲线数更长的值向量,因此可以轻松根据类型和方法因子的大小计算样式向量值
  • 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天全站免登陆