Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to plot a violin scatter boxplot (in R)?

I just came by the following plot:

alt text

And wondered how can it be done in R? (or other softwares)

Update 10.03.11: Thank you everyone who participated in answering this question - you gave wonderful solutions! I've compiled all the solution presented here (as well as some others I've came by online) in a post on my blog.

like image 834
Tal Galili Avatar asked Sep 01 '10 13:09

Tal Galili


2 Answers

Make.Funny.Plot does more or less what I think it should do. To be adapted according to your own needs, and might be optimized a bit, but this should be a nice start.

Make.Funny.Plot <- function(x){
    unique.vals <- length(unique(x))
    N <- length(x)
    N.val <- min(N/20,unique.vals)

    if(unique.vals>N.val){
      x <- ave(x,cut(x,N.val),FUN=min)
      x <- signif(x,4)
    }
    # construct the outline of the plot
    outline <- as.vector(table(x))
    outline <- outline/max(outline)

    # determine some correction to make the V shape,
    # based on the range
    y.corr <- diff(range(x))*0.05

    # Get the unique values
    yval <- sort(unique(x))

    plot(c(-1,1),c(min(yval),max(yval)),
        type="n",xaxt="n",xlab="")

    for(i in 1:length(yval)){
        n <- sum(x==yval[i])
        x.plot <- seq(-outline[i],outline[i],length=n)
        y.plot <- yval[i]+abs(x.plot)*y.corr
        points(x.plot,y.plot,pch=19,cex=0.5)
    }
}

N <- 500
x <- rpois(N,4)+abs(rnorm(N))
Make.Funny.Plot(x)

EDIT : corrected so it always works.

like image 56
Joris Meys Avatar answered Oct 19 '22 17:10

Joris Meys


I recently came upon the beeswarm package, that bears some similarity.

The bee swarm plot is a one-dimensional scatter plot like "stripchart", but with closely-packed, non-overlapping points.

Here's an example:

  library(beeswarm)
  beeswarm(time_survival ~ event_survival, data = breast,
    method = 'smile',
    pch = 16, pwcol = as.numeric(ER),
    xlab = '', ylab = 'Follow-up time (months)',
    labels = c('Censored', 'Metastasis'))
  legend('topright', legend = levels(breast$ER),
    title = 'ER', pch = 16, col = 1:2)


(source: eklund at www.cbs.dtu.dk)

like image 33
Shane Avatar answered Oct 19 '22 18:10

Shane