2016-05-10 38 views
24

假设我有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() 

我想:

ggplot graph

它是用下面的代码生成喜欢只有一个图例正确显示形状,颜色和线条类型(交互(Type,Method)图例与我想要的最接近,但它没有正确的形状/线条类型)。

我知道,如果我使用scale_xxx_manual和我指定他们将合并所有的传说一样的标签,但我不希望有手动设置标签:如果有新的方法或类型,我不我不想修改我的代码:想要一些通用的东西。

编辑

正如下面的答案指出,有几种方式来获得在这种特殊情况下完成工作。所有建议的解决方案都需要手动设置图例线条类型和形状,可以使用scale_xxx_manual function s或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) 

这给:

5 curves

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

注意,矢量大小为5,因为我们有5条曲线,而interaction(Type, Method)因素有大小6(我没有对COS /方法3组合数据)

+1

您的色阶对于组合形状和线型比例是多余的。你应该只使用其中的一个。 – Roland

+0

是的,它是多余的。起初,我将颜色映射到了类型,并将线型映射到了方法。但是,当曲线彼此靠得太近时,很难区分它们。因此冗余 – Ben

+1

有冗余形状/颜色组定义通常是适当的。在许多科学出版物中,颜色是区分群体最直观有效的方式,但您也知道很大一部分读者将会打印纸张的黑白副本,因此您还需要包含一个视觉提示,取决于颜色。 – neuropsych

回答

3

这里是在一般情况下的解决方案:

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

  • 正弦曲线s以实线绘制,余弦曲线绘制为虚线。
  • “method1”数据使用实心圆形状。
  • “method2”数据使用填充三角形的形状。
  • “method3”数据使用实心菱形作为形状。
  • 传说曲线

总结相匹配,这些技巧有:

  • 使用Type /法interaction所有数据表示(颜色,形状, 线型等)
  • 然后用 scale_xxx_manual手动设置曲线样式和图例样式。
  • scale_xxx_manual允许你提供一个值向量比曲线的实际数量长,所以很容易从类型的大小计算风格矢量值和方法因素
16

我有这个问题的一天。在Legends将R食谱部分解释:

如果同时使用的颜色和形状,它们都需要给予规模 规格。否则会有两个独立的传说。

在你的情况下,你需要规格shapelinetype

编辑

这是具有相同的数据创建形状色彩和线条很重要,我直接定义列相结合的互动阶段。用scale_linetype_discrete创建图例,我用scale_linetype_manual来指定值,因为默认情况下它们将采用四个不同的值。

如果你想所有可能的形状和线条类型的详细布局,检查this R Graphics site看到所有的数字标识符:

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

enter image description here

+1

嗯,这将与线条和形状的传奇传说相同,但我认为OP需要4个不同的颜色/线型/形状的传说符号,每个 – beetroot

+0

嗯,这几乎是我要找的东西:你有一个传说,真正。但是我可以通过scale_shape(guide = FALSE)和scale_linetype(guide = FALSE)得到相同的结果。用你的解决方案,我没有传说中的实线/虚线,也没有形状。 – Ben

+0

@beetroot我同意 – Ben

5

低于所需的传奇结果的代码,如果我理解你的问题,但我不确定我是否理解标签问题,请告诉我这是不是你想要的。

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

enter image description here

+0

确实是这样做的一种方式。我会发布我找到的另一个解决方案。恕我直言,两者都不是很简单,我希望有一个更好的办法来处理这种情况。 – Ben

2

一个只需要名字两个指南都一样。例如:

g+ scale_linetype_manual(name="Guide1",values= c('solid', 'solid', 'dotdash'))+ 
    scale_colour_manual(name="Guide1", values = c("blue", "green","red")) 
+0

这实际上工作得很好!!!!! –

相关问题