user2844018
user2844018

Reputation: 21

How to add ggplot legend of two different lines R?

I need to add a legend of the two lines (best fit line and 45 degree line) on TOP of my two plots. Sorry I don't know how to add plots! Please please please help me, I really appreciate it!!!!

Here is an example

type = factor(rep(c("A", "B", "C"), 5))
xvariable = seq(1, 15)
yvariable = 2 * xvariable + rnorm(15, 0, 2)
newdata = data.frame(type, xvariable, yvariable)
p = ggplot(newdata, aes(x=xvariable, y=yvariable))
p + geom_point(size=3) + facet_wrap(~ type) +
  geom_abline(intercept=0, slope=1, color="red", size=1) + 
  stat_smooth(method="lm", se=FALSE, size=1)

Upvotes: 2

Views: 6170

Answers (2)

Brian Diggs
Brian Diggs

Reputation: 58825

Here is another approach which uses aesthetic mapping to string constants to identify different groups and create a legend.

First an alternate way to create your test data (and naming it DF instead of newdata)

DF <- data.frame(type = factor(rep(c("A", "B", "C"), 5)),
                 xvariable = 1:15,
                 yvariable = 2 * (1:15) + rnorm(15, 0, 2))

Now the ggplot code. Note that for both geom_abline and stat_smooth, the colour is set inside and aes call which means each of the two values used will be mapped to a different color and a guide (legend) will be created for that mapping.

ggplot(DF, aes(x = xvariable, y = yvariable)) +
  geom_point(size = 3) + 
  geom_abline(aes(colour="one-to-one"), intercept =0, slope = 1, size = 1) +
  stat_smooth(aes(colour="best fit"), method = "lm", se = FALSE, size = 1) + 
  facet_wrap(~ type) +
  scale_colour_discrete("")

enter image description here

Upvotes: 7

Henrik
Henrik

Reputation: 67778

Try this:

# original data
type <- factor(rep(c("A", "B", "C"), 5))
x <- 1:15
y <- 2 * x + rnorm(15, 0, 2)

df <- data.frame(type, x, y)

# create a copy of original data, but set y = x
# this data will be used for the one-to-one line
df2 <- data.frame(type, x, y = x)

# bind original and 'one-to-one data' together
df3 <- rbind.data.frame(df, df2)

# create a grouping variable to separate stat_smoothers based on original and one-to-one data 
df3$grp <- as.factor(rep(1:2, each = nrow(df)))

# plot
# use original data for points
# use 'double data' for abline and one-to-one line, set colours by group
ggplot(df, aes(x = x, y = y)) +
  geom_point(size = 3) +
  facet_wrap(~ type) +
  stat_smooth(data = df3, aes(colour = grp), method = "lm", se = FALSE, size = 1) +
  scale_colour_manual(values = c("red","blue"),
                      labels = c("abline", "one-to-one"),
                      name = "") +
  theme(legend.position = "top")

# If you rather want to stack the two keys in the legend you can add:
# guide = guide_legend(direction = "vertical")
#...as argument in scale_colour_manual

Please note that this solution does not extrapolate the one-to-one line outside the range of your data, which seemed to be the case for the original geom_abline. enter image description here

Upvotes: 1

Related Questions