简体   繁体   中英

horizontal ggplot2::geom_violin without coord_flip

I want to draw horizontal violin plots (because my labels are long). My design constraints are:

  • multiple facets ( f1 ), multiple categories per facet ( f2 ) (so I want to use aes(x=f2) and facet_wrap(~f1)
  • different scales per facet (so I want scales="free" )
  • 4 different facets which I want to arrange via facet_wrap() (ruling out some faceting tricks)

Unfortunately scales="free" and coord_flip() are currently (and for the foreseeable future) incompatible.

The answers to this related question suggest (1) hacking a new horizontal geom; (2) exchanging x and y (which as pointed out there works only with symmetric geoms like scatterplots); (3) giving up and going with the conventional layout.

Ideas?

set.seed(101)
library("plyr")
dd <- expand.grid(f1=factor(1:2),
     f2=paste("inconveniently long label",1:2))
dd2 <- ddply(dd,c("f1","f2"),
             function(x)
                 data.frame(y=rnorm(100,
                         mean=10*(as.numeric(x$f2)), 
                         sd=10^(as.numeric(x$f1)))))
library("ggplot2")

My choices seem to be (1) with scale="free" , inconvenient (horizontal) labels:

ggplot(dd2,aes(x=f2,y=y))+facet_wrap(~f1,scale="free")+geom_violin()

在此输入图像描述

(2) with coord_flip() , inconvenient scales

ggplot(dd2,aes(x=f2,y=y))+facet_wrap(~f1)+geom_violin()+coord_flip()

在此输入图像描述

Trying both ( ggplot(dd2,aes(x=f2,y=y))+facet_wrap(~f1,scale="free")+geom_violin()+coord_flip() ) gives

ggplot2 does not currently support free scales with a non-cartesian coord or coord_flip.

Other ideas:

  • There are explicitly horizontal versions of some geoms ( geom_errorbarh ); I could hack my own geom_violinh ...
  • There is some discussion of horizontal geoms in a pull request on ggplot2
  • This (rather old) example uses facets + geom_ribbon() to hack a violin plot, but it uses up faceting, making it incompatible with facet_wrap()

For what it's worth, this is what my real plot looks like (at the moment):

在此输入图像描述

Not sure if this helps, but it's an adaptation of this answer where we 'hacked' the vertical violin.

dd2_violin <- ddply(dd2,.(f1,f2),function(chunk){
  d_y <- density(chunk$y)
  top_part <- data.frame(x=d_y$x, y=d_y$y)
  bottom_part <- top_part[nrow(top_part):1,]
  bottom_part$y <- 0 - bottom_part$y
  return(rbind(top_part,bottom_part))
})
#weird trick to get spacing right
dd2_violin$y2 <- as.numeric(dd2_violin$f2)*(2*max(dd2_violin$y))+dd2_violin$y

p1 <- ggplot(dd2_violin, aes(x=x,y=y2,group=interaction(f1,f2))) + geom_path()
#apply same weird trick to get labels

p1 + facet_grid(~f1,scales="free")+labs(x="y")+
scale_y_continuous(breaks=unique(as.numeric(dd2_violin$f2)*(2*max(dd2_violin$y))),labels=unique(dd2_violin$f2))

在此输入图像描述

This can now be done with the new (Jan 2016) ggstance package , which provides horizontal versions of a variety of geoms.

## if necessary
devtools::install_github("lionel-/ggstance")
## ... data generation stuff from above
require("ggplot2")
require("ggstance")
ggplot(dd2,aes(y=f2,x=y))+facet_wrap(~f1,scale="free")+
    geom_violinh()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM