I am working with a dataset consisting of different plant genotypes, rates of fertilizer applications, and 5 different measurements. I am using ggplot2
to produce multiple bar graphs, and then using the gridExtra
package to combine multiple graphs onto a single page. The trouble I am having involves moving and resizing the scale so that there is only one scale for each of my graphs, and I would like to move it to the lower right corner of the graph. The data/code below should better explain what I mean.
Packages/Dataset
#Open packages
library(dplyr)
library(ggplot2)
library(gridExtra)
#Dataset
plantdata <- data.frame(genotype = c(1,
1,
1,
1,
2,
2,
2,
2,
3,
3,
3,
3,
2,
2,
1,
3,
3,
3,
1,
3,
2,
2,
1,
1,
1,
2,
2,
1,
3,
3,
3,
3,
2,
1,
2,
1),
rate=c(1,
2,
3,
4,
1,
2,
3,
4,
1,
2,
3,
4,
2,
4,
1,
1,
3,
2,
3,
4,
1,
3,
4,
2,
2,
1,
3,
3,
4,
1,
3,
2,
4,
1,
2,
4),
measure1=c(958,
309,
750,
43,
20,
868,
905,
674,
64,
151,
677,
144,
803,
485,
707,
881,
684,
222,
399,
507,
4,
690,
831,
574,
104,
238,
378,
897,
63,
154,
582,
641,
750,
855,
194,
55),
measure2=c(359,
728,
180,
614,
241,
989,
117,
101,
95,
156,
227,
355,
597,
50,
636,
912,
149,
862,
897,
601,
176,
7,
182,
214,
453,
569,
124,
113,
969,
781,
713,
613,
800,
334,
435,
748),
measure3=c(639,
304,
891,
317,
869,
901,
723,
267,
837,
923,
171,
991,
107,
309,
733,
705,
819,
807,
346,
447,
891,
957,
359,
323,
846,
944,
400,
548,
327,
48,
677,
624,
564,
854,
658,
343),
measure4=c(805,
24,
624,
675,
261,
437,
601,
129,
733,
172,
746,
586,
142,
243,
103,
779,
612,
870,
84,
881,
850,
456,
255,
52,
228,
492,
556,
66,
670,
682,
736,
178,
568,
501,
229,
500),
measure5=c(667,
105,
565,
724,
238,
861,
299,
13,
171,
759,
755,
557,
739,
228,
870,
595,
793,
790,
572,
590,
365,
974,
550,
766,
441,
265,
245,
909,
150,
88,
473,
245,
340,
378,
998,
121))
Function for standard error of the mean:
sem <- function(x) sd(x)/sqrt(length(x))
Generating the graphs:
#Measurement 1 graph
meas1 <- select(plantdata, genotype, rate, measure1)
#Aggregating data frame
meas1_mean <- aggregate(meas1, by=list(meas1$genotype, meas1$rate), mean)
meas1_sem <- aggregate(meas1, by=list(meas1$genotype, meas1$rate), sem)
g1 <- ggplot(meas1_mean, aes(x=Group.1, y=measure1, fill=factor(Group.2)))+
geom_bar(stat="identity",width=0.6, position="dodge", col="black")+
scale_fill_discrete(name= 'rate', labels=c("1","2","3","4"))+
xlab("Genotype")+ylab("Measurement")+
geom_errorbar(aes(ymin= meas1_mean$measure1, ymax=meas1_mean$measure1+meas1_sem$measure1), width=0.2, position = position_dodge(0.6))+
ggtitle("Plant Measurement 1")+
scale_fill_brewer(palette='PRGn', name= 'rate', labels=c("1","2","3","4"))+
theme(plot.title = element_text(hjust=0.5))
####################################################################
#Measurement 2 graph
meas2 <- select(plantdata, genotype, rate, measure2)
#Aggregating dataframe
meas2_mean <- aggregate(meas2, by=list(meas2$genotype, meas2$rate), mean)
meas2_sem <- aggregate(meas2, by=list(meas2$genotype, meas2$rate), sem)
#Generating graph
g2 <- ggplot(meas2_mean, aes(x=Group.1, y=measure2, fill=factor(Group.2)))+
geom_bar(stat="identity",width=0.6, position="dodge", col="black")+
scale_fill_discrete(name= 'rate', labels=c("1","2","3","4"))+
xlab("Genotype")+ylab("Measurement")+
geom_errorbar(aes(ymin= meas2_mean$measure2, ymax=meas2_mean$measure2+meas2_sem$measure2), width=0.2, position = position_dodge(0.6))+
ggtitle("Plant Measurement 2")+
scale_fill_brewer(palette='PRGn', name= 'rate', labels=c("1","2","3","4"))+
theme(plot.title = element_text(hjust=0.5))
####################################################################
#Measurement 3 graph
meas3 <- select(plantdata, genotype, rate, measure3)
#Aggregating dataframe
meas3_mean <- aggregate(meas3, by=list(meas3$genotype, meas3$rate), mean)
meas3_sem <- aggregate(meas3, by=list(meas3$genotype, meas3$rate), sem)
#Graph
g3 <- ggplot(meas3_mean, aes(x=Group.1, y=measure3, fill=factor(Group.2)))+
geom_bar(stat="identity",width=0.6, position="dodge", col="black")+
scale_fill_discrete(name= 'rate', labels=c("1","2","3","4"))+
xlab("Genotype")+ylab("Measurement")+
geom_errorbar(aes(ymin= meas3_mean$measure3, ymax=meas3_mean$measure3+meas3_sem$measure3), width=0.2, position = position_dodge(0.6))+
ggtitle("Plant Measurement 3")+
scale_fill_brewer(palette='PRGn', name= 'rate', labels=c("1","2","3","4"))+
theme(plot.title = element_text(hjust=0.5))
##############################################################
#Measurement 4 graph
meas4 <- select(plantdata, genotype, rate, measure4)
#Aggregating dataframe
meas4_mean <- aggregate(meas4, by=list(meas4$genotype, meas4$rate), mean)
meas4_sem <- aggregate(meas4, by=list(meas4$genotype, meas4$rate), sem)
#Graph
g4 <- ggplot(meas4_mean, aes(x=Group.1, y=measure4, fill=factor(Group.2)))+
geom_bar(stat="identity",width=0.6, position="dodge", col="black")+
scale_fill_discrete(name= 'rate', labels=c("1","2","3","4"))+
xlab("Genotype")+ylab("Measurement")+
geom_errorbar(aes(ymin= meas4_mean$measure4, ymax=meas4_mean$measure4+meas4_sem$measure4), width=0.2, position = position_dodge(0.6))+
ggtitle("Plant Measurement 4")+
scale_fill_brewer(palette='PRGn', name= 'rate', labels=c("1","2","3","4"))+
theme(plot.title = element_text(hjust=0.5))
################################################################
#Measurement 5 graph
meas5 <- select(plantdata, genotype, rate, measure5)
#Aggregate dataframe
meas5_mean <- aggregate(meas5, by=list(meas5$genotype, meas5$rate), mean)
meas5_sem <- aggregate(meas5, by=list(meas5$genotype, meas5$rate), sem)
#Graph
g5 <- ggplot(meas5_mean, aes(x=Group.1, y=measure5, fill=factor(Group.2)))+
geom_bar(stat="identity",width=0.6, position="dodge", col="black")+
scale_fill_discrete(name= 'rate', labels=c("1","2","3","4"))+
xlab("Genotype")+ylab("Measurement")+
geom_errorbar(aes(ymin= meas5_mean$measure5, ymax=meas5_mean$measure5+meas5_sem$measure5), width=0.2, position = position_dodge(0.6))+
ggtitle("Plant Measurement 5")+
scale_fill_brewer(palette='PRGn', name= 'rate', labels=c("1","2","3","4"))+
theme(plot.title = element_text(hjust=0.5))
Then, I arranged all the graphs onto one page, as follows:
grid.arrange(g1, g2, g3, g4, g5,
nrow=2, ncol=3)
Because the requirements for this graph are that it needs to be exported in a smaller format, I would like to re-arrange the scale so that there is only one scale for the whole combined image, and I would like to increase the size of it. See below:
How can I do this? If there is a better way to generate this than the way I did it, I am open to learning how to do it.
Consider the ggpubr
package and in there the ggarrange
function with the argument common.legend = TRUE
.
a <- data.frame(x = rnorm(100), y=rnorm(100), group = gl(5,20))
b <- data.frame(x = rnorm(100), y=rnorm(100), group = gl(5,20))
c <- data.frame(x = rnorm(100), y=rnorm(100), group = gl(5,20))
library(ggplot2)
library(ggpubr)
p1 <- ggplot(a, aes(x = x, y = y, color = group)) + geom_point()
p2 <- ggplot(b, aes(x = x, y = y, color = group)) + geom_point()
p3 <- ggplot(c, aes(x = x, y = y, color = group)) + geom_point()
ggarrange(p1, p2, p3, common.legend = TRUE)
Documentation: https://rpkgs.datanovia.com/ggpubr/reference/ggarrange.html