Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combining violin plot with box plot

Tags:

plot

r

ggplot2

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.

like image 892
Josh Avatar asked Feb 20 '26 14:02

Josh


1 Answers

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

like image 152
Troy Avatar answered Feb 22 '26 04:02

Troy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!