stewart6
stewart6

Reputation: 269

Add custom labels to bars in ggplot stacked bar graph with multiple variables

I've created a stacked bar graph in ggplot2 with multiple variables:

enter image description here

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

Answers (2)

MrFlick
MrFlick

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))

enter image description here

Upvotes: 3

Didzis Elferts
Didzis Elferts

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)

enter image description here

Upvotes: 5

Related Questions