2

I'm trying to add significance tests' letters from a two way ANOVA in a two faceted graph. The problem is, if a try using geom_text, the function works well until it reaches the level 5 of my plots, i.e., the end of the first facet. After this, it repeats the same 5 values for the second facet, but I need to have new values there.

I have tried annotation and ggpub, but both don't seem to solve the problem.

Here is an example:

The data frame:

ex=structure(list(Trat = c("C", "C", "C", "C", "Ca", "Ca", "Ca", 
"Ca", "N", "N", "N", "N", "NP", "NP", "NP", "NP", "P", "P", "P", 
"P", "C", "C", "C", "C", "Ca", "Ca", "Ca", "Ca", "N", "N", "N", 
"N", "NP", "NP", "NP", "NP", "P", "P", "P", "P"), Ano = structure(c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("2009", "2015"), class = 
"factor"), 
Trat.Ano = c("C . 2009", "C . 2009", "C . 2009", "C . 2009", 
"Ca . 2009", "Ca . 2009", "Ca . 2009", "Ca . 2009", "N . 2009", 
"N . 2009", "N . 2009", "N . 2009", "NP . 2009", "NP . 2009", 
"NP . 2009", "NP . 2009", "P . 2009", "P . 2009", "P . 2009", 
"P . 2009", "C . 2015", "C . 2015", "C . 2015", "C . 2015", 
"Ca . 2015", "Ca . 2015", "Ca . 2015", "Ca . 2015", "N . 2015", 
"N . 2015", "N . 2015", "N . 2015", "NP . 2015", "NP . 2015", 
"NP . 2015", "NP . 2015", "P . 2015", "P . 2015", "P . 2015", 
"P . 2015"), Especie = c("Sp", "Sp", "Sp", "Sp", "Sp", "Sp", 
"Sp", "Sp", "Sp", "Sp", "Sp", "Sp", "Sp", "Sp", "Sp", "Sp", 
"Sp", "Sp", "Sp", "Sp", "Sp", "Sp", "Sp", "Sp", "Sp", "Sp", 
"Sp", "Sp", "Sp", "Sp", "Sp", "Sp", "Sp", "Sp", "Sp", "Sp", 
"Sp", "Sp", "Sp", "Sp"), cobertura = c(0, 0, 0, 7, 11, 0, 
8, 314, 0, 0, 0, 0, 451, 1398, 1400, 712, 1305, 1063, 1068, 
161, 0, 0, 0, 0, 810, 325, 511, 678, 0, 0, 0, 0, 326, 1043, 
57, 229, 701, 1488, 62, 987)), row.names = c(1L, 4L, 7L, 
10L, 13L, 16L, 19L, 22L, 25L, 28L, 31L, 34L, 37L, 40L, 43L, 46L, 
49L, 52L, 55L, 58L, 61L, 64L, 67L, 70L, 73L, 76L, 79L, 82L, 85L, 
88L, 91L, 94L, 97L, 100L, 103L, 106L, 109L, 112L, 115L, 118L), class = 
"data.frame")

ANOVA:

fitMelinis1<- aov(cobertura~Trat*Ano, data=ex) ## Two Way anova
TukeyMelinis1=TukeyHSD(fitMelinis1) # PairWise test
teste=multcompView::multcompLetters4(fitMelinis1, TukeyMelinis1) # the letters I want in my graph

See that the letters are repeated in both facets.

Paleta=c("#339900", "#FF0000", "#000099", "#DAA523", "#000000")

plotMelinis=ggplot(ex,aes(x=Trat,y=cobertura,fill=Trat))+
geom_boxplot() + scale_fill_manual(values=Paleta)+
ylab("cobertura")+ggtitle("Melinis")+facet_wrap(~Ano,ncol=2)+
geom_text(data = ex, x = 1, y = 1500, label = "c", color = "black", 
family="serif", size = 4)+
geom_text(data = ex, x = 2, y = 1500, label = "bc", color = "black", 
family="serif", size = 4)+
geom_text(data = ex, x = 3, y = 1500, label = "c", color = "black", 
family="serif", size = 4)+
geom_text(data = ex, x = 4, y = 1500, label = "a", color = "black", 
family="serif", size = 4)+
geom_text(data = ex, x = 5, y = 1500, label = "a", color = "black", 
family="serif", size = 4)+
geom_text(data = ex, x = 6, y = 1500, label = "c", color = "black", 
family="serif", size = 4)+
geom_text(data = ex, x = 7, y = 1500, label = "abc", color = "black", 
family="serif", size = 4)+
geom_text(data = ex, x = 8, y = 1500, label = "c", color = "black", 
family="serif", size = 4)+
geom_text(data = ex, x = 9, y = 1500, label = "abc", color = "black", 
family="serif", size = 4)+
geom_text(data = ex, x = 10, y = 1500, label = "ab", color = "black", 
family="serif", size = 4)

So, as said, I'd like to have different letters on each facet.

Repeated letters in each facet

2
  • This is an example of why you want to work with data in a long format for ggplot. Instead of hard-coding your x, y, and label for each piece of text, just make a data frame of that information and treat it as you would any other data in ggplot Commented Apr 24, 2019 at 14:29
  • It's also hard to tell what's what. Does the ANOVA-related stuff occur in the plotting? If not, we don't need it in the question. Commented Apr 24, 2019 at 14:31

2 Answers 2

1

Use stat_summary:

#labels need to be ordered based on the year and Trat to line in the plot

ltlbl <- teste$`Trat:Ano`$Letters
ltlbl <- cbind(ltlbl, as.data.frame(do.call(rbind, str_split(names(ltlbl),":"))))
ltlbl <- ltlbl[order(ltlbl$V2, ltlbl$V1), ]


ggplot(ex,aes(x=Trat,y=cobertura,fill=Trat))+
  geom_boxplot() + scale_fill_manual(values=Paleta)+
  ylab("cobertura")+ggtitle("Melinis")+facet_wrap(~Ano,ncol=2)+
  stat_summary(geom = 'text', label = ltlbl$ltlbl, fun.y = max, aes(y = 1450))

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

1

The easiest way to plot the compact letter display these is to get everything in a dataset that contains the facet and axis variables as well as the labels for plotting.

I have used the emmeans package for this sort of thing, partially because the package makes it very easy to get the compact letter display results into a data.frame for plotting.

Here's an example of that using your model. I use cld() after emmeans(), which does a Tukey adjustment for the ten groups by default.

library(emmeans)

( cld_dat = as.data.frame( cld(emmeans(fitMelinis1, ~ Trat*Ano),
                   Letters = letters ) ) )

   Trat  Ano        emmean       SE df   lower.CL  upper.CL .group
6     C 2015 -2.224887e-13 165.7846 30 -338.57726  338.5773    a  
3     N 2009  4.507505e-14 165.7846 30 -338.57726  338.5773    a  
8     N 2015  7.860379e-14 165.7846 30 -338.57726  338.5773    a  
1     C 2009  1.750000e+00 165.7846 30 -336.82726  340.3273    a  
2    Ca 2009  8.325000e+01 165.7846 30 -255.32726  421.8273    ab 
9    NP 2015  4.137500e+02 165.7846 30   75.17274  752.3273    abc
7    Ca 2015  5.810000e+02 165.7846 30  242.42274  919.5773    abc
10    P 2015  8.095000e+02 165.7846 30  470.92274 1148.0773     bc
5     P 2009  8.992500e+02 165.7846 30  560.67274 1237.8273      c
4    NP 2009  9.902500e+02 165.7846 30  651.67274 1328.8273      c

I can now use this dataset in a geom_text() layer to add the labels. I'll still set y to a constant like you did.

ggplot(ex, aes(x=Trat, y=cobertura, fill=Trat)) +
  geom_boxplot() + 
  scale_fill_manual(values=Paleta) +
  ylab("cobertura") +
  ggtitle("Melinis") +
  facet_wrap(~Ano,ncol=2) +
  geom_text(data = cld_dat, aes(y = 1500, label = .group))

enter image description here

You can see that each letter is in the same position over each boxplot (so some aren't centered). If you wanted them all centered you can use trimws() to remove the spaces. The geom_text() line would look like:

geom_text(data = cld_dat, aes(y = 1500, label = trimws(.group) ) )

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.