Search code examples
rggplot2viridis

Using ggplot2 and viridis, fill histogram based on other variable


I am trying to create the top left graph in this figure in ggplot, using viridis to make the colour gradient. enter image description here

Here is my sample data:

# simulate t-values
data = data.frame(sim =1:10000,
                  t_0= rt(n = 10000,df =12, ncp=0), 
                  t_1 = rt(n = 10000,df =12, ncp=1.2))
# compute p-values
data = data %>% 
  mutate(p_0 = 2* pt(t_0, df=12, lower.tail = ifelse(t_0 > 0,FALSE ,TRUE)),
         p_1 = 2* pt(t_1, df=12, lower.tail = ifelse(t_1 > 0,FALSE ,TRUE)))

# convert from wide to long
data.long = data %>% 
  gather(condition,measurement, t_0:p_1) %>%
  separate(col=condition, into=c("para","hyp"), sep = "_")

# convert to wide repeated measures format
data.wide = data.long %>% spread(key = para, measurement)

To create the graphs on the left, I need to colour the histogram according to the corresponding values in the right graphs. If t = 0 (corresponding to a p close to 1), the graph should be yellow, if t>4 (corresponding to a p close to 0), the fill should be dark blue. This post shows how to create a similar graph using scale_fill_gradientn, which does unfortunately does not work with the discrete values I have created using cut().

This is the closest I have come, however I want the graph to have yellow for x=0 blending to dark blue at the edges.

# create bins based on t-values
t0bins <- seq(-12, 12, by = 1)
# compute corresponding p-values
pt0bins <- 2*pt(t0bins, df = 12, lower.tail = FALSE)



 ggplot(data.wide, aes(x=t, fill=cut(..x.., breaks=get("t0bins", envir=.GlobalEnv)))) +
  geom_histogram(binwidth=0.1)+
  scale_fill_viridis(discrete=T)

which gives: enter image description here


Solution

  • You can try

    library(tidyverse)
    library(viridis)
    data.wide %>% 
      mutate(bins=cut(t, breaks=t0bins)) %>% 
    {ggplot(.,aes(x=t, fill=bins)) +
      geom_histogram(binwidth=0.1)+
      scale_x_continuous(limits =c(-12,12)) +
      scale_fill_manual(drop=FALSE,values = c(viridis(nlevels(.$bins)/2), viridis(nlevels(.$bins)/2, direction = -1)))}
    

    enter image description here