I have repeatedly measured a given behavior in male and female animals over four different reproductive states (virgin, mated, expecting and parent). I would like to represent my data (x: reproductive state, y: behavior value) in the following manner:
- dot plot where dots of the same behavior value spread horizontally instead of overlapping
- each subgroup (e.g. virgin males) should also have a segment showing the mean value of the behavior
- each individual animal should also be tractable with thin lines connecting the dots that correspond to that individual in each reproductive state
I have managed to do 1) and 2), but couldn't combine them with my 3)rd objective. Can someone help me?
Here is an example:
library(ggplot2)
Function to obtain a mean segment for each group
MinMeanSEMMax <- function(x) {
v <- c(min(x), mean(x) - sd(x)/sqrt(length(x)), mean(x), mean(x) + sd(x)/sqrt(length(x)), max(x))
names(v) <- c("ymin", "lower", "middle", "upper", "ymax")
v
}
# Mock dataframe:
Sex<-rep(c("M","F"), times=12)
ID<-rep(seq(from=1, to=6), times=4)
Behavior<-rnorm(24, mean=10, sd=3)
State<-rep(c("virgin", "virgin", "mated", "mated", "expecting", "expecting", "parent", "parent"), times=3)
d<-data.frame(ID,Sex,Behavior,State)
# Prepare mean value for plotting of mean segments
g<-ggplot(d, aes(x=factor(State), y=Behavior, colour=Sex))+
stat_summary(fun.data=MinMeanSEMMax, geom="boxplot", position=position_dodge(), outlier.shape = 21, outlier.size = 3, size=1)+
scale_x_discrete(limits=c("virgin", "mated", "expecting", "parent"), labels=c("virgin"="Virgin", "mated"="Mated", "expecting"="Expecting", "parent"="Parent"))+
dat.g <- ggplot_build(g)$d[[1]]
g
# The plot
b<-ggplot(d, aes(x=factor(State), y=Behavior, colour=factor(Sex)))+
geom_segment(data=dat.g, aes(x=xmin, xend=xmax,y=middle, yend=middle), colour=c("blue3","brown2","blue3","brown2","blue3","brown2","blue3","brown2"), size=1)+
geom_dotplot(aes(fill=Sex),binaxis="y", stackdir="center", position=position_dodge(width=1), binwidth = 0.3)+
labs(x="",y="Behavior")+
theme_classic()+
theme(axis.line.x = element_line(color="black", size = 1),
axis.line.y = element_line(color="black", size = 1))+
theme(legend.position="none")+
theme(axis.text.x =element_text(size=10),axis.text.y=element_text(size=10), axis.title=element_text(size=11,face="bold"))+
scale_fill_manual(name="Sex", values=c("brown2", "blue3"), breaks=c("F", "M"))+
scale_colour_manual(name="Sex",values=c("brown2","blue3"),breaks=c("F", "M"),labels=c("Female", "Male"))+
scale_x_discrete(limits=c("virgin", "mated", "expecting", "parent"), labels=c("virgin"="Virgin", "mated"="Mated", "expecting"="Expecting", "parent"="Parent"))+
theme(text=element_text(family="serif"))
b