user1614062
user1614062

Reputation: 182

r producing multiple violin plots with one graphic device

I have a data frame that looks like that:

bin_with_regard_to_strand CLONE3
 31                      0.14750872 
 33                      0.52735917
 28                      0.48559060
 .                            .
 .                            .

I want to use this data frame to generate violin plots in such a way that all of the values in CLONE3 corresponding to a given value of bin_with_regard_to_strand will generate one plot. Further, I want all of the plots to appear in the same graphic device (I'm using R-studio, and I want all of the plots to appear in one plot window). Theoretically I could do this with:

vioplot(df$CLONE3[which(df$bin_with_regard_to_strand==1)], 
  df$CLONE3[which(df$bin_with_regard_to_strand==2)]...)

but since bin_with_regard_to_strand has 60 different values, this seems a bit ridiculous. I tried using tapply:

tapply(df$CLONE3, df$bin_with_regard_to_strand,vioplot)

But that would open 60 different windows (one for each plot). Or, if I used the add parameter:

 tapply(df$CLONE3, df$bin_with_regard_to_strand,vioplot(add=TRUE))

generated a single plot with the data from all values bin_with_regard_to_strand (seperated by lines).

Is there a way to do this?

Upvotes: 1

Views: 1104

Answers (3)

epurdom
epurdom

Reputation: 55

This is an old question, but though I would put out a different solution for getting vioplot to make multiple violin plots on the same graph (i.e. same axes), rather than on different graphics objects like the above answers.

Basically use do.call to apply vioplot to a list of data. Ultimately, vioplot is not very well written (can't even set the title, axis names, etc.). I usually prefer base R, but this is a case where ggplot2 options is probably the way to go.

x<-rnorm(1000)
fac<-rep(c(1:10),each=100)
listOfData<-tapply(x,fac,function(x){x},simplify=FALSE)
names(listOfData)[[1]]<-"x" #because vioplot requires a 'x' argument
do.call(vioplot,listOfData)

resultingImage

Upvotes: 0

agstudy
agstudy

Reputation: 121568

Another alternative to mfrow, is to use layout. It is very handy to organize your plots. You just create a matrix with plots index. Here what you can do. It seems that 60 boxplots is a huge number. Maybe you should organize them in 2 pages.

enter image description here

The code below in function of N (number of plots)

library(vioplot)
N <- 60
par(mar=rep(2,4))  
layout(matrix(c(1:N),
              nrow=10,byrow=T))
dat <- data.frame(bin_with_regard_to_strand=gl(N,10),CLONE3=rnorm(10*N))
with(dat , 
     tapply(CLONE3,bin_with_regard_to_strand ,vioplot))

Upvotes: 0

sgibb
sgibb

Reputation: 25736

You could use par(mfrow=c(rows, columns)) (see ?par for details).

(see also ?layout for complexer arrangements)

d <- lapply(1:6, function(x)runif(100)) # generate some example data

library("vioplot")

par(mfrow=c(3, 2)) # use a 3x2 (rows x columns) layout

lapply(d, vioplot) # call plot for each list element

par(mfrow=c(1, 1)) # reset layout

vioplots

Upvotes: 2

Related Questions