Using bar plots to show Q-PCR results hides part of the information, which is un-necessary. In this post, I demonstrate the use of ggplot2 to build informative plots from Q-PCR results. The example data that will be used in the following example consists of four replicate experiments (“exp1” to “exp4”) for three different conditions that were tested (mutant “A” to “C”). The numerical values represent the change in the level of a specific RNA in the different mutant conditions, as compared with a wild-type strain:
experiment mutantA mutantB mutantC
exp1 exp1 6.5 1.1 1.6
exp2 exp2 7.4 1.3 1.6
exp3 exp3 7.4 1.3 1.8
exp4 exp4 7.3 1.2 1.7
First, we convert the data to a “long-form” type, using the reshape2 package. We will use the first column, containing the identifier for replicated experiments, as the “variable” (see parameter of the melt function):
require(reshape2)
Loading required package: reshape2
melted <- melt(data = mydata, id.vars = 1)
names(melted) <- c("experiment", "mutant", "value")
melted$experiment <- as.factor(melted$experiment) #make sure we have factors
print(melted)
experiment mutant value
1 exp1 mutantA 6.5
2 exp2 mutantA 7.4
3 exp3 mutantA 7.4
4 exp4 mutantA 7.3
5 exp1 mutantB 1.1
6 exp2 mutantB 1.3
7 exp3 mutantB 1.3
8 exp4 mutantB 1.2
9 exp1 mutantC 1.6
10 exp2 mutantC 1.6
11 exp3 mutantC 1.8
12 exp4 mutantC 1.7
We can use the long-format data to make a first version of a plot:
require(ggplot2)
Loading required package: ggplot2
baseplot <- ggplot(data=melted, aes(x=mutant, y=value, color=experiment))
print(baseplot+geom_point())
As expected, the dots are overlapping. If we had plenty of replicates, a jittering can be useful, since it scatters the dots and we can see most of them, for example:
plot <- baseplot+
geom_point(position = position_jitter(w = 0.7, h = 0.0))
print(plot)
This is better, but jittering scatters the dots and does not preserve any order. In our case, it is better to try to make the add regular spaces that preserve the order of experiments in the plot, using position_dodge:
plot <- baseplot+
geom_point(position=position_dodge(width=0.7))
print(plot)
A potential difference between mutantB and mutantC, can be seen better on a log scale, using the scale_y_continous variable:
plot <- baseplot+
geom_point(position=position_dodge(width=0.7))+
scale_y_continuous(trans='log10', breaks=c(1:10))
print(plot)
Adding descriptive statistics, like mean and standard deviation is done like this:
plot <- baseplot+
geom_point(position=position_dodge(width=0.7))+
scale_y_continuous(trans='log10', breaks=c(1:10))+
stat_summary(fun.data="mean_cl_boot", geom="errorbar",width=0.05, colour="red")
print(plot)
mean_cl_boot is a wrapper of the smean.cl.boot function from the Hmisc package, and uses a bootstrap procedure to obtain cofidence intervals. You can also use other descriptive statistics, for example, mean and standard deviation. Easy to incorporate in stat_summary:
meanminsd <- function(x){
return(mean(x)-sd(x))
}
meanplussd <- function(x){
return(mean(x)+sd(x))
}
plot <- baseplot+
geom_point(position=position_dodge(width=0.7))+
scale_y_continuous(trans='log10', breaks=c(1:10))+
stat_summary(fun.y="mean", fun.ymin="meanminsd", fun.ymax="meanplussd",
geom="errorbar",width=0.05, colour="red")
print(plot)
A few more options later, this is the complete graph, that can be exported with ggsave("filename.svg", width=xinches, height=yinches):
plot <- ggplot(data=melted, aes(x=mutant, y=value, color=experiment))+
geom_point(position=position_dodge(width=0.7), size=2)+
scale_colour_manual(values=rep("black", 5))+
theme(axis.text.y=element_text(size=10))+
xlab("")+
ylab("Fold change X mRNA vs. wt (log scale)")+
theme_bw()+theme(panel.grid.major = element_line(colour = "grey"))+
theme(panel.grid.minor=element_blank())+
theme(legend.position="none")+
theme(panel.grid.major.x=element_blank())+
scale_y_continuous(trans='log10', breaks=c(1:10))+
scale_x_discrete(labels=c("mut. A", "mut. B", "mut. C"))+
theme(panel.border=element_blank())+
stat_summary(fun.y=mean, fun.ymax=meanplussd, fun.ymin =meanminsd, colour="red", geom="errorbar", width=0.1)+
stat_summary(fun.y=mean, fun.ymax=mean, fun.ymin =mean, colour="red", geom="crossbar", width=0.2)
print(plot)
This final plot can be edited in Inkscape.
Any comment is wellcome.