purple1437
purple1437

Reputation: 313

How to color only for points above and below certain amounts in ggplot2?

So I have a reproducible code below, I only want to color the points below and above the dotted black lines and nothing in between. The points in between should be grey or whatever default color without aes(color = x)

color_above <- mean(iris$Sepal.Width) + sd(iris$Sepal.Width)
color_below <- mean(iris$Sepal.Width) - sd(iris$Sepal.Width)


ggplot(data=iris, aes(x = Sepal.Length, y = Sepal.Width)) + geom_point(aes(color=Species, shape=Species)) +
  xlab("Sepal Length") +  ylab("Sepal Width")+
  geom_hline(yintercept = color_above, linetype = "dashed", color = "black") +
  geom_hline(yintercept = color_below, linetype = "dashed", color = "black")

enter image description here

Upvotes: 1

Views: 3708

Answers (3)

TarJae
TarJae

Reputation: 79164

We could also use gghighlight package: I think this made for such situations:

p +  gghighlight::gghighlight(Sepal.Width > 3.5 | Sepal.Width < 2.6)

enter image description here

Upvotes: 2

Waldi
Waldi

Reputation: 41240

You could add a new layer:

grey <- iris[iris$Sepal.Width < color_above & iris$Sepal.Width > color_below,]

ggplot(data=iris, aes(x = Sepal.Length, y = Sepal.Width)) + geom_point(aes(color=Species, shape=Species)) +
  xlab("Sepal Length") +  ylab("Sepal Width")+
  geom_hline(yintercept = color_above, linetype = "dashed", color = "black") +
  geom_hline(yintercept = color_below, linetype = "dashed", color = "black") +
  geom_point(data=grey,aes(x = Sepal.Length, y = Sepal.Width),color='grey')

enter image description here

Upvotes: 2

stefan
stefan

Reputation: 125038

One option would be to add a column to your dataframe where using an ifelse assigns an NA to obs. between your threshold lines and map this new column on the color aes. These values will automatically be assigned the na.value of scale_color_discrete. To get rid of the NA entry in the legend I use the breaks argument and set the name for the color legend to Species so that it still gets merged with the shape legend.

library(ggplot2)

color_above <- mean(iris$Sepal.Width) + sd(iris$Sepal.Width)
color_below <- mean(iris$Sepal.Width) - sd(iris$Sepal.Width)

iris$color <- ifelse(iris$Sepal.Width > color_above | iris$Sepal.Width < color_below, as.character(iris$Species), NA_character_)

ggplot(data=iris, aes(x = Sepal.Length, y = Sepal.Width, color = color)) + 
  geom_point(aes(shape=Species)) +
  scale_color_discrete(breaks = unique(iris$Species), name = "Species") +
  xlab("Sepal Length") +
  ylab("Sepal Width")+
  geom_hline(yintercept = color_above, linetype = "dashed", color = "black") +
  geom_hline(yintercept = color_below, linetype = "dashed", color = "black")

Upvotes: 4

Related Questions