Reasons that ggplot2 legend does not appear

2019-07-28 10:46发布

问题:

I was attempting (unsuccessfully) to show a legend in my R ggplot2 graph which involves multiple plots. My data frame df and code is as follows:

  Individuals        Mod.2        Mod.1          Mod.3
1           2 -0.013473145  0.010859793    -0.08914021
2           3 -0.011109863  0.009503278    -0.09049672
3           4 -0.006465788  0.011304668    -0.08869533
4           5  0.010536718  0.009110458    -0.09088954
5           6  0.015501212  0.005929766    -0.09407023
6           7  0.014565584  0.005530390    -0.09446961
7           8 -0.009712516  0.012234843    -0.08776516
8           9 -0.011282278  0.006569570    -0.09343043
9          10 -0.011330579  0.003505439    -0.09649456

str(df)
    'data.frame':   9 obs. of  4 variables:
     $ Individuals   : num  2 3 4 5 6 7 8 9 10
     $ Mod.2         : num  -0.01347 -0.01111 -0.00647 0.01054 0.0155 ...
     $ Mod.1         : num  0.01086 0.0095 0.0113 0.00911 0.00593 ...
     $ Mod.3         : num  -0.0891 -0.0905 -0.0887 -0.0909 -0.0941 ...

ggplot(df, aes(df$Individuals)) +
    geom_point(aes(y=df[,2]), colour="red") + geom_line(aes(y=df[,2]), colour="red") +
    geom_point(aes(y=df[,3]), colour="lightgreen") + geom_line(aes(y=df[,3]), colour="lightgreen") +
    geom_point(aes(y=df[,4]), colour="darkgreen") + geom_line(aes(y=df[,4]), colour="darkgreen") +
    labs(title = "Modules", x = "Number of individuals", y = "Mode")

I looked up the following stackflow threads, as well as Google searches:

  • Merging ggplot2 legend
  • ggplot2 legend not showing
  • `ggplot2` legend not showing label for added series
  • ggplot2 legend for geom_area/geom_ribbon not showing
  • ggplot and R: Two variables over time
  • ggplot legend not showing up in lift chart
  • Why ggplot2 legend not show in the graph
  • ggplot legend not showing up in lift chart. This one was created 4 days ago

This made me realize that making legends appear is a recurring issue, despite the fact that legends usually appear automatically.

My first question is what are the causes of a legend to not appear when using ggplot? The second is how to solve these causes. One of the causes appears to be related to multiple plots and the use of aes(), but I suspect there are other reasons.

回答1:

You are going about the setting of colour in completely the wrong way. You have set colour to a constant character value in multiple layers, rather than mapping it to the value of a variable in a single layer.

This is largely because your data is not "tidy" (see the following)

head(df)
  x           a          b          c
1 1 -0.71149883  2.0886033  0.3468103
2 2 -0.71122304 -2.0777620 -1.0694651
3 3 -0.27155800  0.7772972  0.6080115
4 4 -0.82038851 -1.9212633 -0.8742432
5 5 -0.71397683  1.5796136 -0.1019847
6 6 -0.02283531 -1.2957267 -0.7817367

Instead, you should reshape your data first:

df <- data.frame(x=1:10, a=rnorm(10), b=rnorm(10), c=rnorm(10))
mdf <- reshape2::melt(df, id.var = "x")

This produces a more suitable format:

head(mdf)
 x variable       value
1 1        a -0.71149883
2 2        a -0.71122304
3 3        a -0.27155800
4 4        a -0.82038851
5 5        a -0.71397683
6 6        a -0.02283531

This will make it much easier to use with ggplot2 in the intended way, where colour is mapped to the value of a variable:

ggplot(mdf, aes(x = x, y = value, colour = variable)) + 
    geom_point() + 
    geom_line()



回答2:

colour= XYZ should be inside the aes(),not outside:

geom_point(aes(data, colour=XYZ)) #------>legend

geom_point(aes(data),colour=XYZ)  #------>no legend

Hope it helps, it took me a hell long way to figure out.



回答3:

ind = 1:10
my.df <- data.frame(ind,  sample(-5:5,10,replace = T) ,  
sample(-5:5,10,replace = T) , sample(-5:5,10,replace = T))
df <- data.frame(rep(ind,3) ,c(my.df[,2],my.df[,3],my.df[,4]), 
c(rep("mod.1",10),rep("mod.2",10),rep("mod.3",10)))
colnames(df) <- c("ind","value","mod")

Your data frame should look something likes this

   ind value   mod
    1     5 mod.1
    2    -5 mod.1
    3     3 mod.1
    4     2 mod.1
    5    -2 mod.1
    6     5 mod.1

Then all you have to do is :

ggplot(df, aes(x = ind, y = value, shape = mod, color = mod)) + 
geom_line() + geom_point()


标签: r ggplot2 legend