MultBar : Advanced multiple barplot with SEM
[This article was first published on [R] tricks, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Producing this kind of graphs (below) in R can be a pain in the a*s.

Here is a simple code that requires that data are presented in lists (see the example below).
multbar <- function(list.of.lists,...,condnames=0,pal=colorRampPalette(c('grey','cornsilk')),seriesnames=0,legendpos='topleft',legh=TRUE,do.pty='s')
{
par(pty=do.pty,mgp=c(1.9,0.8,0),oma=c(0,0,0,0),mar=c(4,3,2,1),bg='transparent',bty='o',tck=0.02,yaxs='i')
NofList <- length(list.of.lists)
NofSubList <- length(list.of.lists[[1]])
if(condnames==0){condnames=c(1:NofList)}
if(seriesnames==0){seriesnames=c(1:NofSubList)}
dim.mat.treat <- (NofList+1)*NofSubList
pos <- c(1:dim.mat.treat)
pos <- matrix(pos,nrow=(NofList+1))
nbreaks <- dim.mat.treat+1
par(xaxs='i',yaxs='i',bty='o')
plot(0,0,pch=NA,xlim=c(0,nbreaks),ylim=c(min(pretty(range(list.of.lists))),max(pretty(range(list.of.lists)))),xaxt='n',yaxt='n',...)
calc.ylab <- pretty(range(list.of.lists))
lab.ylab <- round(calc.ylab,2)
abline(h=pretty(range(list.of.lists)),lty=3,col='grey',lwd=2)
abline(h=0,col='darkgrey',lwd=1.4)
palette <- pal(NofList)
for(condition in 1:NofList)
{
for(treatment in 1:NofSubList)
{
CD <- list.of.lists[[condition]][[treatment]]
CDm <- mean(CD)
CDv <- sd(CD)
x.coord <- pos[condition,treatment]
rect(x.coord,0,x.coord+1,CDm,col=palette[condition])
arrows(x.coord+0.5,CDm+CDv,x.coord+0.5,CDm-CDv,angle=90,code=3,length=0.05)
}
}
axis(side=2,at=calc.ylab,labels=lab.ylab,tick=TRUE)
#abline(h=calc.ylab[1])
abline(h=pretty(range(list.of.lists))[1])
fills <- c(1:NofList)
legend(legendpos,legend=condnames,fill=palette[fills],bty='n',horiz=legh,cex=1)
cl.tab <- (c(1:NofSubList)-1)*NofSubList + NofList/2 +1
lab.cond <- NULL
int.lab.cond <- pos[c(1:(nrow(pos)-1)),]
for(COL in 1:ncol(int.lab.cond))
{
lab.cond[COL] <- mean(int.lab.cond[,COL])+0.5
}
axis(side=1,at=lab.cond,labels=seriesnames,tick=FALSE)
par(xaxs='r')
if(min(pretty(range(list.of.lists)))<0){abline(h=0,lwd=1.1)}
box()
}
list.1 <- list(rnorm(10,mean=3.4),rnorm(10,mean=6.8))
list.2 <- list(rnorm(10,mean=4),rnorm(10,mean=8.8))
list.3 <- list(rnorm(10,mean=3.1),rnorm(10,mean=7.4))
data <- list(list.1,list.2,list.3)
png()
par(family='serif')
multbar(data,main='Faked data',seriesnames=c('Control','Stress'),condnames=c('Ind. 1','Ind. 2','Ind. 3'),xlab='Treatment',ylab='Response')
dev.off()
To leave a comment for the author, please follow the link and comment on their blog: [R] tricks.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.