Reputation: 269
I've created a stacked bar graph in ggplot2 with multiple variables:
using the following code:
library(ggplot2)
ggplot(meltd, aes(x=Burst, y=value, fill=variable)) +
geom_bar(stat="identity") + facet_grid(~samp,scales="free",space="free") +
theme_bw() + scale_fill_manual("Fertilization",values = c('#98FB98', '#FF6347')) +
scale_x_continuous(breaks = seq(1, 19, by = 1))
On this data (ordered):
Burst samp %Fert %Unfert
1 1 Nassau 1.0000000 0.000000000
5 2 Nassau 0.9793237 0.020676300
8 3 Nassau 0.9774301 0.022569886
16 4 Nassau 0.9750000 0.025000000
13 5 Nassau 0.9734843 0.026515719
12 6 Nassau 0.9651163 0.034883721
17 7 Nassau 0.9516807 0.048319328
4 8 Nassau 0.9444444 0.055555556
9 9 Nassau 0.9183673 0.081632653
14 10 Nassau 0.9106901 0.089309907
18 11 Nassau 0.9074555 0.092544547
7 12 Nassau 0.9017857 0.098214286
10 13 Nassau 0.8622995 0.137700535
3 14 Nassau 0.8559867 0.144013322
6 15 Nassau 0.8551978 0.144802240
15 16 Nassau 0.8389423 0.161057692
11 17 Nassau 0.7916667 0.208333333
19 18 Nassau 0.6976611 0.302338930
2 19 Nassau 0.4482759 0.551724138
25 1 Nassau PT 0.8896552 0.110344828
24 2 Nassau PT 0.1836735 0.816326531
20 1 Tiger 0.9980843 0.001915711
22 2 Tiger 0.9971968 0.002803175
21 3 Tiger 0.9934823 0.006517695
23 4 Tiger 0.8092784 0.190721649
26 1 Tiger PT 0.7407045 0.259295499
27 2 Tiger PT 0.5734797 0.426520270
28 3 Tiger PT 0.4337979 0.566202091
which was then melted to create this data frame for ggplot:
Burst samp variable value
1 1 Nassau %Fert 1.000000000
2 2 Nassau %Fert 0.979323700
3 3 Nassau %Fert 0.977430114
4 4 Nassau %Fert 0.975000000
5 5 Nassau %Fert 0.973484281
6 6 Nassau %Fert 0.965116279
7 7 Nassau %Fert 0.951680672
8 8 Nassau %Fert 0.944444444
9 9 Nassau %Fert 0.918367347
10 10 Nassau %Fert 0.910690093
11 11 Nassau %Fert 0.907455453
12 12 Nassau %Fert 0.901785714
13 13 Nassau %Fert 0.862299465
14 14 Nassau %Fert 0.855986678
15 15 Nassau %Fert 0.855197760
16 16 Nassau %Fert 0.838942308
17 17 Nassau %Fert 0.791666667
18 18 Nassau %Fert 0.697661070
19 19 Nassau %Fert 0.448275862
20 1 Nassau PT %Fert 0.889655172
21 2 Nassau PT %Fert 0.183673469
22 1 Tiger %Fert 0.998084289
23 2 Tiger %Fert 0.997196825
24 3 Tiger %Fert 0.993482305
25 4 Tiger %Fert 0.809278351
26 1 Tiger PT %Fert 0.740704501
27 2 Tiger PT %Fert 0.573479730
28 3 Tiger PT %Fert 0.433797909
29 1 Nassau %Unfert 0.000000000
30 2 Nassau %Unfert 0.020676300
31 3 Nassau %Unfert 0.022569886
32 4 Nassau %Unfert 0.025000000
33 5 Nassau %Unfert 0.026515719
34 6 Nassau %Unfert 0.034883721
35 7 Nassau %Unfert 0.048319328
36 8 Nassau %Unfert 0.055555556
37 9 Nassau %Unfert 0.081632653
38 10 Nassau %Unfert 0.089309907
39 11 Nassau %Unfert 0.092544547
40 12 Nassau %Unfert 0.098214286
41 13 Nassau %Unfert 0.137700535
42 14 Nassau %Unfert 0.144013322
43 15 Nassau %Unfert 0.144802240
44 16 Nassau %Unfert 0.161057692
45 17 Nassau %Unfert 0.208333333
46 18 Nassau %Unfert 0.302338930
47 19 Nassau %Unfert 0.551724138
48 1 Nassau PT %Unfert 0.110344828
49 2 Nassau PT %Unfert 0.816326531
50 1 Tiger %Unfert 0.001915711
51 2 Tiger %Unfert 0.002803175
52 3 Tiger %Unfert 0.006517695
53 4 Tiger %Unfert 0.190721649
54 1 Tiger PT %Unfert 0.259295499
55 2 Tiger PT %Unfert 0.426520270
56 3 Tiger PT %Unfert 0.566202091
Each column represents one egg sample, and the % fertilized and unfertilized eggs contained in that sample. What I would like to do is annotate each column on the very top to include the number of eggs in each sample, in the vector below.
[1] 20.0 29.0 619.0 36.0 970.0 443.0 112.0 1594.0 98.0 374.0 180.0 215.0 248.0
[14] 342.0 208.0 40.0 238.0 481.0 305.0 1045.0 457.0 1768.0 97.0 220.5 217.5 255.5
[27] 296.0 287.0
I'm having issues because of the bar plot being broken into 4 variables, and also because it's a stacked bar graph. For example, I tried to double the vector of egg numbers and cbind it on to the melted data frame, but then when I plotted the text using annotate it put an egg number in both the %Fert and %Unfert block of each column (so 2 values), while I only want one value representing the total number of eggs in each sample, or column, at the top of each column. Using the geom_text function is also a bit wacky, as when I try to add coordinates I can't seem to add specific coordinates for each variable (i.e. Nassau, Nassau PT, Tiger, Tiger PT), only universal coordinates which are then applied to each facet. Any suggestions??
Thanks!
Upvotes: 1
Views: 3976
Reputation: 206566
The easiest way may be just to make a new dataset rather than try to add to your egg-sisting data.frame.
Here I make a data.frame based off your meltd
frame that has the Burst and samp variables along with the counts. (You will want to make sure all the data is properly lined up.)
counts<-c(20.0, 29.0, 619.0, 36.0, 970.0, 443.0, 112.0, 1594.0, 98.0, 374.0, 180.0, 215.0, 248.0, 342.0, 208.0, 40.0, 238.0, 481.0, 305.0, 1045.0, 457.0, 1768.0, 97.0, 220.5, 217.5, 255.5, 296.0, 287.0)
eggcounts <- cbind(unique(meltd[, 1:2]), counts=as.integer(counts))
Now I move the fill and y aesthetic to the geom_bar()
since we don't need those for our text and then add the text
ggplot(meltd, aes(x=Burst)) +
geom_bar(stat="identity", aes(y=value, fill=variable)) +
geom_text(data=eggcounts, aes(y=1, label=counts), angle=45, size=4) +
facet_grid(~samp,scales="free",space="free") +
theme_bw() +
scale_fill_manual("Fertilization",values = c('#98FB98', '#FF6347')) +
scale_x_continuous(breaks = seq(1, 19, by = 1))
Upvotes: 3
Reputation: 98589
You can create new data frame that contains Burst
and samp
columns as in original data frame and column that contains number of samples. I made this data frame taking first 28 rows and first two columns of meltd
and added nsamp
column with number of samples.
df.text=cbind(meltd[1:28,1:2],nsamp=round(runif(28,10,200)))
head(df.text)
Burst samp nsamp
1 1 Nassau 64
2 2 Nassau 88
3 3 Nassau 57
4 4 Nassau 44
5 5 Nassau 59
6 6 Nassau 86
Then labels are added with geom_text()
where x values are Burst
, y value is set to some constant (1.1) and label are nsamp
. Angle of text is controled with argument angle=
. inherit.aes=FALSE
is used to ignore fill=variable
for geom_text()
.
ggplot(meltd, aes(x=Burst, y=value, fill=variable)) +
geom_bar(stat="identity") + facet_grid(~samp,scales="free",space="free") +
theme_bw() + scale_fill_manual("Fertilization",values = c('#98FB98','#FF6347')) +
scale_x_continuous(breaks = seq(1, 19, by = 1))+
geom_text(data=df.text,aes(x=Burst,y=1.1,label=nsamp),
inherit.aes=FALSE,angle=90,hjust=1)
Upvotes: 5