Search code examples
rmatrixcolorsbar-chartgraphing

Color Dependent Bar Graph in R


I'm a bit out of my depth with this one here. I have the following code that generates two equally sized matrices:

MAX<-100
m<-5
n<-40

success<-matrix(runif(m*n,0,1),m,n)
samples<-floor(MAX*matrix(runif(m*n),m))+1

the success matrix is the probability of success and the samples matrix is the corresponding number of samples that was observed in each case. I'd like to make a bar graph that groups each column together with the height being determined by the success matrix. The color of each bar needs to be a color (scaled from 1 to MAX) that corresponds to the number of observations (i.e., small samples would be more red, for instance, whereas high samples would be green perhaps).

Any ideas?


Solution

  • Using @BrodieG's data.long, this plot might be a little easier to interpret.

    library(ggplot2)
    library(RColorBrewer)   # for brewer.pal(...)
    ggplot(data.long) +
      geom_bar(aes(x=x, y=success, fill=count),colour="grey70",stat="identity")+
      scale_fill_gradientn(colours=brewer.pal(9,"RdYlGn")) +
      facet_grid(group~.)
    

    Note that actual values are probably different because you use random numbers in your sample. In future, consider using set.seed(n) to generate reproducible random samples.

    Edit [Response to OP's comment]

    You get numbers for x-axis and facet labels because you start with matrices instead of data.frames. So convert success and samples to data.frames, set the column names to whatever your test names are, and prepend a group column with the "list of factors". Converting to long format is a little different now because the first column has the group names.

    library(reshape2)
    set.seed(1)
    success <- data.frame(matrix(runif(m*n,0,1),m,n))
    success <- cbind(group=rep(paste("Factor",1:nrow(success),sep=".")),success)
    samples <- data.frame(floor(MAX*matrix(runif(m*n),m))+1)
    samples <- cbind(group=success$group,samples)
    data.long <- cbind(melt(success,id=1), melt(samples, id=1)[3])
    names(data.long) <- c("group", "x", "success", "count")
    

    One way to set a threshold color is to add a column to data.long and use that for fill:

    threshold <- 25
    data.long$fill <- with(data.long,ifelse(count>threshold,max(count),count))
    

    Putting it all together:

    library(ggplot2)
    library(RColorBrewer)
    ggplot(data.long) +
      geom_bar(aes(x=x, y=success, fill=fill),colour="grey70",stat="identity")+
      scale_fill_gradientn(colours=brewer.pal(9,"RdYlGn")) +
      facet_grid(group~.)+
      theme(axis.text.x=element_text(angle=-90,hjust=0,vjust=0.4))
    

    Finally, when you have names for the x-axis labels they tend to get jammed together, so I rotated the names -90°.