add median/mean to violin/boxplot

2,679 views
Skip to first unread message

skifond

unread,
Mar 26, 2012, 5:48:04 PM3/26/12
to ggplot2
Hi all!
This is my first post on ggplot2.

I am trying to add the mean to a violin/boxplot graphic. When I have
only one factor it is working fine but when I have two factors the
mean of each factor appears only in the middle (not in the box or
violin plots). I played with alpha and width with no luck. My second
problem is that the boxplots are not inside the violin plots.

Any help would be really appreciated.
martin


library(ggplot2)
library(scales)
library(plyr)

A reproductible example (data=test in the code below):

structure(list(Site = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), .Label =
c("Site1",
"Site2", "Site3"), class = "factor"), Treatment = structure(c(1L,
1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L,
1L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L,
2L, 2L, 2L), .Label = c("Control", "test"), class = "factor"),
Value = c(4L, 3L, 11L, 22L, 6L, 7L, 3L, 9L, 6L, 10L, 20L,
30L, 40L, 2L, 4L, 5L, 8L, 10L, 21L, 30L, 2L, 5L, 8L, 10L,
3L, 4L, 5L, 6L, 7L, 8L, 22L, 21L, 20L, 14L, 5L, 3L)), .Names =
c("Site",
"Treatment", "Value"), class = "data.frame", row.names = c(NA,
-36L))


My code:
ggplot(test, aes(Site, Value)) + geom_violin(aes(fill=Treatment))
+ geom_boxplot (aes(fill=Treatment), alpha=1, width=0.5) + ylim(0,50)
+ opts(legend.position=c(0.1,0.7)) + opts(axis.title.x =
theme_blank())
+ stat_summary(aes(group=Treatment), fun.y=mean, geo="point",
fill="black", shape=21, size=3)

David Kahle

unread,
Mar 26, 2012, 9:15:43 PM3/26/12
to skifond, ggplot2
I think this is a rigged version of what you want, I'm sure Winston will have a better solution :

ggplot(aes(x = Site, y = Value), data = test) + 
  geom_violin(aes(fill=Treatment), alpha = .25) +
  geom_boxplot (aes(fill=Treatment), alpha=.25, width=0.5, position = position_dodge(width = .9)) + 
  stat_summary(aes(group=Treatment), fun.y=mean, geom="point",
    fill="black", shape=21, size=3, position = position_dodge(width = .9)) + 
  ylim(0,50) + 
  opts(
    legend.position=c(0.1,0.7),
    axis.title.x = theme_blank()
  )

Strangely,  the following doesn't work (it only moves one of the groups, and not both).  It may be a bug...

w <- .2
ggplot(aes(x = Site, y = Value), data = test) + 
  geom_violin(aes(fill=Treatment), alpha = .25, position = position_dodge(width = w)) +
  geom_boxplot (aes(fill=Treatment), alpha=.25, width=0.5, position = position_dodge(width = w)) + 
  stat_summary(aes(group=Treatment), fun.y=mean, geom="point",
    fill="black", shape=21, size=3, position = position_dodge(width = w)) + 
  ylim(0,50) + 
  opts(
    legend.position=c(0.1,0.7),
    axis.title.x = theme_blank()
  )

    

You can probably get what you want from there.

Cheers
david.



--
You received this message because you are subscribed to the ggplot2 mailing list.
Please provide a reproducible example: http://gist.github.com/270442

To post: email ggp...@googlegroups.com
To unsubscribe: email ggplot2+u...@googlegroups.com
More options: http://groups.google.com/group/ggplot2

Winston Chang

unread,
Mar 26, 2012, 10:23:50 PM3/26/12
to David Kahle, skifond, ggplot2
The dodging does indeed look buggy when width was set to 0.5... I believe it was related to a bug that's now been fixed:
Reply all
Reply to author
Forward
0 new messages