3
votes

I would like to create a chart with ggplot2 using a conditional color so that if the data point respect a condition on another column it will be "green", otherwise, it will follow a predefined color palette.

The answers I've seen in SO about conditional color in ggplot2 suggest to manually indicate colors using scale_fill_manual or scale_color_manual here and here.

and this is not really ideal if you have many color categories to assess or just want to use a one of those nice-looking predefined color palettes from RColorBrewer or Viridis.

Here is my reproducible example with my attempt:

library(ggplot2)
library(RColorBrewer)

# get data
  data("mtcars")

ggplot(mtcars, aes(x=qsec, y=hp,  color= ifelse( cyl < 6, "green", factor(carb)) )) +
  scale_colour_brewer( type = "seq", palette = "Reds") +
  geom_point() +
  theme_bw()

enter image description here

2

2 Answers

4
votes

How about adding an additional points layer with just the subset of data you want in the specific color?

mtcars$condition <- with(mtcars, ifelse(cyl < 6, 1, 0))

ggplot(mtcars, aes(x=qsec, y=hp,  color= factor(carb))) +
  geom_point() + 
  geom_point(data = subset(mtcars, condition == 1), color = "green") +
  scale_colour_brewer( type = "seq", palette = "Reds") +
  theme_bw()

enter image description here

1
votes

Another option, it's not as short as adding another layer, but I think the plot is a little cleaner (you aren't overlapping points).

df <- mtcars
df$col <- ifelse( df$cyl < 6, "cyl < 6", as.character(df$carb))
non_green <- unique(df$col[df$col != "cyl < 6"])
non_green <- non_green[order(non_green)]

ggplot(df, aes(x=qsec, y=hp,  colour= col )) +
  scale_color_manual(values = c(setNames(brewer.pal(length(non_green), name = "Reds"), non_green), "cyl < 6" = "green")) +
  geom_point() +
  theme_bw()

enter image description here