2

I have a very simple dataset (2 groups, n=15 per group). Using ggplot2, I can easily plot a violin plot or a box plot of the two groups. However, I would like to graph a violin plot, but have the fill shade correspond to the 3 quartiles of my data.

There is an example done in SAS here but I would like to do this in R.

llrs
3,40541 silver badges72 bronze badges
asked Mar 9, 2014 at 5:52

1 Answer 1

11

Like this using ggplot_build() to get the outlines?

EDIT UPDATED TO SHOW QUANTILE OF THE ORIGINAL DATA

require(ggplot2) # for ggplot
require(dplyr) # for mutation 
df<-data.frame( # make sample data 
 grp=rep(1:6,each=15),
 val=c(rnorm(15,runif(1)*5,runif(1)),
 rnorm(15,runif(1)*5,runif(1)),
 rnorm(15,runif(1)*5,runif(1)),
 rnorm(15,runif(1)*5,runif(1)),
 rnorm(15,runif(1)*5,runif(1)),
 rnorm(15,runif(1)*5,runif(1))
 )
 )
g<-ggplot(df)+geom_violin(aes(x=grp,y=val,group=grp),color="darkred",fill="darkred",size=2) # build the base violins
coords<-ggplot_build(g)$data # use ggbuild to get the outline co-ords
d<-coords[[1]] # this gets the df in a usable form
groups<-unique(d$group) # get the unique "violin" ids
# function to create geom_ploygon calls
fill_viol<-function(v,gr){
 quants<-mutate(v,x.l=x-violinwidth/2,x.r=x+violinwidth/2,cuts=cut(y,quantile(df[df$grp==gr,"val"]))) # add 1/2 width each way to each x value
 plotquants<-data.frame(x=c(quants$x.l,rev(quants$x.r)), # left x bottom to top, then right x top to bottom
 y=c(quants$y,rev(quants$y)), # double up the y values to match
 id=c(quants$cuts,rev(quants$cuts)))# cut by quantile to create polygon id
 geom_polygon(aes(x,y,fill=as.factor(id)),data=plotquants) # return the geom_ploygon object
}
g + # plot g
 lapply(groups,function(x)fill_viol(d[d$group==x,],x)) + # plus polygon objects for each violin
 scale_fill_brewer(palette="Reds", # plus fill
 name="Quantile\n",
 labels=c("25","50","75","100")) +
 coord_flip()

enter image description here

answered Mar 9, 2014 at 7:05
Sign up to request clarification or add additional context in comments.

3 Comments

Yes, thank you! This is what I was looking for. I'm not so sure how the code works exactly, but is it possible to break up the polygons by quantile(df$grp) instead of just breaking up the vertical space in 25% blocks?
Yes - I'd actually meant to do this, but calculated the quantile of the violin coords which are regularly spaced, rather than the original values - oops. I've corrected the code, and flipped the chart so it looks more like your example.
Any idea of how to get this to work with facets? It seems quite strambled if I just add a facet_grid or facet_wrap.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.