Harry M
Harry M

Reputation: 2088

How to color a ggplot histogram differently based on precise cut off points?

I'm trying to color a ggplot histogram differently based on precise boundaries along the x axis. However, the colors are not accurate because a bin that contains values from both colors will show up as a mixed color bin split up horizontally. Example minimal code and problem chart below.

I would like to split the bin by color vertically. So that all values to the left of the cutoff line are one color and all values to the right of the cutoff line are the other color.

How can I accomplish this?

I think geom_density would not have this problem, but I would prefer to use geom_histogram instead of geom_density because the histogram shows actual counts on the y axis.

cutoff_point <- 3.9
mtcars %>% 
  mutate(wt_color = ifelse(wt < cutoff_point, "red", "blue")) %>% 
  select(wt, wt_color) %>% 
  ggplot(aes(x=wt, fill = wt_color)) +
  geom_histogram(bins = 5) +
  geom_vline(xintercept=cutoff_point, colour="black")

enter image description here

The boundary argument works well when I have just one cutoff point, but it doesn't work when I have two cutoff points like below

cutoff_point1 <- 2.5
cutoff_point2 <- 5.4

mtcars %>% 
  mutate(wt_color = case_when(
    wt < cutoff_point1 ~ "blue",
    wt > cutoff_point1 & wt < cutoff_point2 ~ "red",
    TRUE ~ "green"
    )) %>% 
  select(wt, wt_color) %>% 
  ggplot(aes(x=wt, fill = wt_color)) +
  geom_histogram(bins = 5, boundary=cutoff_point) +
  geom_vline(xintercept=cutoff_point, colour="black")

enter image description here

Upvotes: 0

Views: 2489

Answers (1)

f.lechleitner
f.lechleitner

Reputation: 3812

Maybe this'll work for you. You can specify the bin-breaks in geom_histogram. So we first create an evenly spaced bin-vector and add some cutoff points to it:

n.bins <- 5 # number of bins
additional.cutoffs <- c(3.9, 2.9) # additional bins

bins <- seq(min(mtcars$wt), max(mtcars$wt), length.out = n.bins)    
bins <- c(bins, additional.cutoffs) %>% sort()

mtcars %>% 
  mutate(wt_color = ifelse(wt < cutoff_point, "red", "blue")) %>% 
  select(wt, wt_color) %>% 
  ggplot(aes(x=wt, fill = wt_color)) +
  geom_histogram(breaks = bins) +
  geom_vline(xintercept=additional.cutoffs, colour="black")

enter image description here

Upvotes: 4

Related Questions