ixodid
ixodid

Reputation: 2400

Select colors of linear regression line

How do I set the colors of the linear regression lines independent of the line colors?


library(tidyverse)

df <- tibble(
  x = c(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6),
  y = c(1, 3, 2, 4, 1, 4, 2, 5, 3, 7, 5, 10),
  type = c("A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B")
)

ggplot(df, aes(x = x, y = y)) +
  geom_line(aes(colour = type), size = 4) +
  scale_x_continuous(breaks = 1:6) +
  geom_smooth(data = filter(df, x >= 3), aes(x = x, y = y, group = type), method = "lm", se = FALSE, size = 0.5) +
  scale_color_manual(values = c("A" = "dark red", "B" = "dark blue")) +
  theme_minimal()

Upvotes: 0

Views: 1118

Answers (2)

Christopher Dudley
Christopher Dudley

Reputation: 138

The simplest way, if you are just looking for a single colour for both regression lines, is to add a colour argument to your call to geom_smooth.

library(tidyverse)

df <- tibble(
  x = c(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6),
  y = c(1, 3, 2, 4, 1, 4, 2, 5, 3, 7, 5, 10),
  type = c("A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B")
)

ggplot(df, aes(x = x, y = y)) +
  geom_line(aes(colour = type), size = 4) +
  scale_x_continuous(breaks = 1:6) +
  scale_color_manual(values = c("A" = "dark red", "B" = "dark blue")) +
  geom_smooth(data = filter(df, x >= 3), aes(x = x, y = y, group = type), 
              colour = 'black', method = "lm", se = FALSE, size = 0.5) 
  theme_minimal()

If you wanted to have separate colours for the regression lines, you could mirror the type variable and colour based on the new variable, as below:

library(tidyverse)

df <- tibble(
  x = c(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6),
  y = c(1, 3, 2, 4, 1, 4, 2, 5, 3, 7, 5, 10),
  type = c("A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B")
)

ggplot(df, aes(x = x, y = y)) +
    geom_line(aes(colour = type), 
              size = 4) +
    # mirror the `type` variable
    geom_smooth(data = filter(df, x >= 3) %>% 
                       mutate(class = factor(ifelse(type == 'A', 0, 1))),
                # group and colour on `class` instead of `type` 
                aes(x = x, y = y, colour = class),
                method = "lm", se = FALSE, size = 2) +
    scale_colour_manual(name = 'Type',
                        values = c('A' = '#6703AA', 
                                   'B' = '#BB8901',
                                   '0' = '#FF2499',
                                   '1' = '#00BBFF'),
                        # add breaks to hide '0' and '1' in legend
                        breaks = c('A', 'B')) +
    scale_x_continuous(breaks = 1:6) +
    theme_minimal()

enter image description here

There may be an easier way that we are overlooking, but this is a clear, functioning method for what you need.

Note: don't forget to change the colours that I provided in the call to scale_colour_manual; they are truly horrible.

Upvotes: 2

Dave2e
Dave2e

Reputation: 24079

One way (sort of a hack) is to specify the color in the geom_smooth function. Since you are fitting a straight line only 2 points are needed for the curve. Use the n and color options and then create a vector of the desired colors

ggplot(df, aes(x = x, y = y)) +
  geom_line(aes(colour = type), size = 4) +
  scale_x_continuous(breaks = 1:6) +
  geom_smooth(data = filter(df, x >= 3), aes(x = x, y = y, group=type), method = "lm",
              se = FALSE, size = 2, n=2, col=rep(c("pink", "green"), each=2)) +
  scale_color_manual(values = c("A" = "dark red", "B" = "dark blue")) +
  theme_minimal()

enter image description here

Upvotes: 1

Related Questions