-3

Stephen Few has recently introduced Bandlines which are an extension to Edward Tufte’s Sparklines. Is there an easy way to produce these kinds of plots using ggplot2?

jrara
  • 16,239
  • 33
  • 89
  • 120
  • 9
    Put a bit of meat on this bone. How about giving us some possible code that you would like to be able to type in, and then a mockup image of the graphic you'd like to get out. The first `g` in `ggplot` is grammar - you've told us what you want for the second `g`, but how about the first? Ppl seem to think `ggplot` is just for pretty graphics with nice shaded backgrounds and sensible colours, but forget about the grammar... – Spacedman Jan 29 '13 at 08:21

1 Answers1

10

Since this was introduced this month, I doubt there is already an implementation. But the concept seems simple enough that you can make one fairly easily. Here is a very simple implementation using base graphics (I'm not an expert of ggplot2).

bandline<-function(x, low.col, high.col, axis=TRUE){
    l <- max(unlist(lapply(x, length)), na.r=TRUE)
    r <- range(unlist(x), na.rm=TRUE)
    par(mfcol=c(length(x), 1))
    for(i in 1:length(x)){
        y <- boxplot.stats(x[[i]])
        ifelse(i==1, par(mar=c(0,3,3,3)), 
                     ifelse(i==length(x), par(mar=c(3,3,0,3)), 
                                          par(mar=c(0,3,0,3))))
        plot(NA, axes=F, bty="n", xlim=c(1,l), ylim=r, xaxs="i")
        rect(1,y$stats[2], l, y$stats[1], col="grey80", border=NA)
        rect(1,y$stats[4], l, y$stats[2], col="grey60", border=NA)
        rect(1,y$stats[5], l, y$stats[4], col="grey40", border=NA)
        abline(h=y$stats[3],col="white", lwd=2)
        lines(seq_along(x[[i]]), x[[i]])
        zhigh <- zlow <- x[[i]]
        zhigh[zhigh<=y$stats[5]]<-NA
        zlow[zlow>=y$stats[1]]<-NA
        points(seq_along(x[[i]]), zlow, bg=low.col, pch=21,cex=2)
        points(seq_along(x[[i]]), zhigh, bg=high.col, pch=21, cex=2)
        if(axis==TRUE){
            axis(2, at=pretty(x[[i]]), las=2)
            ifelse(i==1, axis(3, at=seq_len(l)), 
                         ifelse(i==length(x),axis(1, at=seq_len(l)),""))
            }
        mtext(names(x)[i], side=4, srt=270, line=1)
    }
}

And here is an example:

set.seed(1)
dat<-list(a=rnorm(100), b=rnorm(100), c=rnorm(100), d=rnorm(100))
bandline(dat, "black", "white", axis=FALSE)

enter image description here

plannapus
  • 18,529
  • 4
  • 72
  • 94
  • Well, to be fair, he's not the only one ;-) – SlowLearner Jan 30 '13 at 01:47
  • @Spacedman Wrong. I do understand also base graphics, but I love ggplot2 so much that I would like to see someone to show me how to do this using ggplot2. I don't know how to do it by myself. I gave +1 for plannapus for his implementation. – jrara Jan 30 '13 at 06:22
  • I was being a bit sarcastic. But it would still be nice of you to show us how a hypothetical `geom_bandplot` might work. I don't expect the code for the function, just a few lines of example R input of how you might call it and what you expect to get. Its always good practice to spell out your requirements as fully as possible. – Spacedman Jan 30 '13 at 07:55