0

I want to combine the color legend with the linetype legend following this answer. However, when specifying the linetype as presented here the default linetype cannot be reproduced.

Here is a MWE:

# data generation
y1 <- abs(rnorm(10))
y2 <- abs(rnorm(10))
y3 <- abs(rnorm(10))
x <- seq(1,10)
df1 <- data.frame(x,y=abs(y1),type=as.factor("a"),method=as.factor("A"))
df2 <- data.frame(x,y=abs(y2),type=as.factor("b"),method=as.factor("A"))
df3 <- data.frame(x,y=abs(y3),type=as.factor("a"),method=as.factor("B"))

df <- rbind(df1,df2,df3)
inter <- interaction(df$type,df$method)

# ggplot2 colors
hues = seq(15, 375, length = 4)

# Initialize the plot without specifying the linetype
g <- ggplot(df, aes(x,y,colour = inter,linetype = inter)) + 
    geom_line(size=.9) + 
    geom_point(size=1.25) +
    scale_colour_manual(name="test",values=c(hcl(h=hues,l=65,c=100)[1:3]) +
    scale_y_continuous(name="y",trans='log',breaks=c(.1,.2,.5,1)) +
    scale_x_continuous(name="x",labels=as.character(x),breaks=x)

g

which produces: FIG: default linetype.

However, I want to have method A (df1 and df2) as solid lines and method B (df3) as dashed (with short dashes as for the green line in the previous figure). Following this answer the default linetype can be obtained by

g.plot <- ggplot_build(g)
g.plot$data[[1]]

giving

 colour linetype           y  x PANEL group size alpha
 ...
 10 #F8766D    solid  0.42922736 10     1     1  0.9    NA
 11 #00BA38       22 -2.91845300  1     1     2  0.9    NA
 ...

Therefore I adjust the plot by adding

# Initialize the plot with specifying the linetype
g <- g + scale_linetype_manual(name="test",values=c(1,1,22))

which yields FIG: incorrect linetype. While I have only one legend as desired, the linetype is obviously incorrect. However, even when using the intuitive linetype

# Initialize the plot with specifying the "intuitive" linetype
g <- g + scale_linetype_manual(name="test",values=c(1,1,2))

I obtain an incorrect result FIG: incorrect linetype2 (i.e., the dashes are longer as in the default setting).

  • You seem to want three distinct linetypes, but have only two distinct values in your code. – cory Mar 25 '19 at 12:13
  • I want to have the linetype grouped according to "method". So three values, but only two distinct linetypes. – CaptainNabla Mar 25 '19 at 12:41
  • 1
    Maybe create a new column with the corresponding data you want for linetypes, and use that in the aes call to generate default linetypes. – cory Mar 25 '19 at 13:42
  • I am not quite sure I understand your suggestion. Could you elobarate it? If I use `linetype=method` instead of `linetype=inter` I do have the desired linetype, but then I end up again with two distinct legends instead of one.. – CaptainNabla Mar 26 '19 at 08:48
  • Create a new column in your data, like you did with "inter" which was two distinct values. Use this new column in the aes linetype. – cory Mar 27 '19 at 11:58

1 Answers1

0

There may be an easier way to do this, but using what you already have, here is a possible solution. You noted that making linetype = method gives you the right linetypes in the graph, but the legend is not correct. We can get rid of the second legend with scale_linetype(guide = "none"), but then we have all solid lines in the remaining legend. Using guides() we can set the linetypes manually. In this case, I looked at the answer you listed here and found the names for the line types that you wanted.

g <- ggplot(df, aes(x,y,colour = inter, linetype = method)) + 
  geom_line(size=.9) + 
  geom_point(size=1.25) +
  scale_colour_manual(name="test",values=c(hcl(h=hues,l=65,c=100)[1:3])) +
  scale_y_continuous(name="y",trans='log',breaks=c(.1,.2,.5,1)) +
  scale_x_continuous(name="x",labels=as.character(x),breaks=x) +
  guides(color = guide_legend(title = "inter",
                              override.aes = list(linetype = c("solid", "solid", 22)))) +
  scale_linetype(guide = "none")

enter image description here

StephenK
  • 685
  • 5
  • 16