Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I not get two legends using ggplot2?

Tags:

r

ggplot2

I am plotting different models' prediction lines over some data points. I would like to get a legend indicating to which individual belongs each point colour and another legend indicating to which model belongs each line colour. Below I share a fake example for reproducibility:

set.seed(123)
df <- data.frame(Height =rnorm(500, mean=175, sd=15),
                 Weight =rnorm(500, mean=70, sd=20),
                 ID = rep(c("A","B","C","D"), (500/4)))

mod1 <- lmer(Height ~ Weight + (1|ID), df)
mod2 <- lmer(Height ~ poly(Weight,2) + (1|ID), df)

y.mod1 <- predict(mod1, data.frame(Weight=df$Weight),re.form=NA) # Prediction of y according to model 1
y.mod2 <- predict(mod2, data.frame(Weight=df$Weight),re.form=NA) # Prediction of y according to model 2

df <- cbind(df, y.mod1,y.mod2)
df <- as.data.frame(df)

head(df)

    Height   Weight ID   y.mod1   y.mod2
1 166.5929 57.96214  A 175.9819 175.4918
2 171.5473 50.12603  B 176.2844 176.3003
3 198.3806 90.53570  C 174.7241 174.7082
4 176.0576 85.02123  D 174.9371 174.5487
5 176.9393 39.81667  A 176.6825 177.7303
6 200.7260 68.09705  B 175.5905 174.8027

First I plot my data points:

Plot_a <- ggplot(df,aes(x=Weight, y=Height,colour=ID)) + 
  geom_point() +
  theme_bw() +
  guides(color=guide_legend(override.aes=list(fill=NA)))

Plot_a

enter image description here

Then, I add lines relative to the prediction models:

Plot_b <- Plot_a + 
  geom_line(data = df, aes(x=Weight, y=y.mod1,color='mod1'),show.legend = T) + 
  geom_line(data = df, aes(x=Weight, y=y.mod2,color='mod2'),show.legend = T) +
  guides(fill = guide_legend(override.aes = list(linetype = 0)),
         color=guide_legend(title=c("Model")))

Plot_b

enter image description here

Does anyone know why I am not getting two different legends, one titled Model and the other ID?

I would like to get this

enter image description here

like image 724
Dekike Avatar asked Dec 17 '22 12:12

Dekike


1 Answers

This type of problems generaly has to do with reshaping the data. The format should be the long format and the data is in wide format. See this post on how to reshape the data from long to wide format.

The plot layers become simpler, one geom_line is enough and there is no need for guideto override the aesthetics.

To customize the models' legend text, create a vector of legends, in this case with plotmath, in order to have math notation. And the colors are set manually too.

library(dplyr)
library(tidyr)
library(ggplot2)

model_labels <- c(expression(X^1), expression(X^2))

df %>%
  pivot_longer(
    cols = c(y.mod1, y.mod2),
    names_to = "Model",
    values_to = "Value"
  ) %>%
  ggplot(aes(Weight, Height)) +
  geom_point(aes(fill = ID), shape = 21) +
  geom_line(aes(y = Value, color = Model)) +
  scale_color_manual(labels = model_labels, 
                     values = c("coral", "coral4")) +
  theme_bw()

enter image description here

like image 95
Rui Barradas Avatar answered Jan 11 '23 10:01

Rui Barradas