Question

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?

Was it helpful?

Solution 2

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°.

OTHER TIPS

Here is an example with ggplot. First, get data into long format with melt:

library(reshape2)
data.long <- cbind(melt(success), melt(samples)[3])
names(data.long) <- c("group", "x", "success", "count")
head(data.long)
#   group x    success count
# 1     1 1 0.48513473     8
# 2     2 1 0.56583802    58
# 3     3 1 0.34541582    40
# 4     4 1 0.55829073    64
# 5     5 1 0.06455401    37
# 6     1 2 0.88928606    78

Note melt will iterate through the row/column combinations of both matrices the same way, so we can just cbind the resulting molten data frames. The [3] after the second melt is so we don't end up with repeated group and x values (we only need the counts from the second melt). Now let ggplot do its thing:

library(ggplot2)
ggplot(data.long, aes(x=x, y=success, group=group, fill=count)) +
  geom_bar(position="stack", stat="identity") + 
  scale_fill_gradient2(
    low="red", mid="yellow", high="green", 
    midpoint=mean(data.long$count)
  )

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top