A violin plot is a combination of a boxplot and a kernel density plot. Lattice includes the panel.violin function for this graphical tool. This example draws a violin and a boxplot together.

First, let’s download some solar radiation data from the NASA webpage:

nasafile <- 'http://eosweb.larc.nasa.gov/sse/global/text/global_radiation'
nasa <- read.table(file=nasafile, skip=13, header=TRUE)

Now, I plot a violin plot and a boxplot of the yearly average of daily solar radiation for latitudes between -60º and 60º. I have to convert this numeric vector to a factor with the combination of cut and pretty. It is possible to plot the violin plot and the boxplot together (example included in the help of panel.violin). I choose the pch='|' in order to get an horizontal line at the median. Last, the plot.symbol component in par.settings defines the symbol of the outliers of the boxplot and the box.rectangle component configures the box of the boxplot:


bwplot(Ann~cut(Lat, pretty(Lat, 40)),
 data=nasa, subset=(abs(Lat)<60),
 xlab='Latitude', ylab='G(0) (kWh/m²)',
 horizontal=FALSE,
 panel = function(..., box.ratio) {
 panel.violin(..., col = "lightblue",
 varwidth = FALSE, box.ratio = box.ratio)
 panel.bwplot(..., col='black',
 cex=0.8, pch='|', fill='gray', box.ratio = .1)
 },
 par.settings = list(box.rectangle=list(col='black'),
 plot.symbol = list(pch='.', cex = 0.1)),
 scales=list(x=list(rot=45, cex=0.5))
 )

Now, I plot a violin plot (without a boxplot) of the monthly means of daily solar radiation. First, I have to build the formula:


x <- paste(names(nasa)[3:14], collapse='+')
formula <- as.formula(paste(x, '~cut(Lat, pretty(Lat, 20))', sep=''))

And then I can print the plot. I have to choose outer=TRUE in order to get individual panels for each month, and as.table=TRUE if I want January to be at the upper left corner:


bwplot(formula, data=nasa, subset=(abs(Lat)<60),
 xlab='Latitude', ylab='G(0) (kWh/m²)',
 outer=TRUE, as.table=TRUE, horizontal=FALSE,
 col='lightblue',
 panel=panel.violin,
 scales=list(x=list(rot=70, cex=0.5)))

About these ads