title: Automatically adding letters of significance to a ggplot barplot using output from TukeyHSD
body: <p>Using this data...</p>
  <pre><code>hogs.sample&lt;-structure(list(Zone = c(&quot;B&quot;, &quot;B&quot;, &quot;B&quot;, &quot;B&quot;, &quot;B&quot;, &quot;B&quot;, &quot;B&quot;, &quot;B&quot;, 
  &quot;B&quot;, &quot;B&quot;, &quot;B&quot;, &quot;B&quot;, &quot;B&quot;, &quot;B&quot;, &quot;B&quot;, &quot;B&quot;, &quot;B&quot;, &quot;B&quot;, &quot;B&quot;, &quot;B&quot;, &quot;D&quot;, 
  &quot;D&quot;, &quot;D&quot;, &quot;D&quot;, &quot;D&quot;, &quot;D&quot;, &quot;D&quot;, &quot;D&quot;, &quot;D&quot;, &quot;D&quot;, &quot;D&quot;, &quot;D&quot;, &quot;D&quot;, &quot;D&quot;, 
  &quot;D&quot;, &quot;D&quot;, &quot;D&quot;, &quot;D&quot;, &quot;D&quot;, &quot;D&quot;), Levelname = c(&quot;Medium&quot;, &quot;High&quot;, 
  &quot;Low&quot;, &quot;Med.High&quot;, &quot;Med.High&quot;, &quot;Med.High&quot;, &quot;Med.High&quot;, &quot;Med.High&quot;, 
  &quot;Med.High&quot;, &quot;Medium&quot;, &quot;Med.High&quot;, &quot;Medium&quot;, &quot;Med.High&quot;, &quot;High&quot;, 
  &quot;Medium&quot;, &quot;High&quot;, &quot;Low&quot;, &quot;Med.High&quot;, &quot;Low&quot;, &quot;High&quot;, &quot;Medium&quot;, 
  &quot;Medium&quot;, &quot;Med.High&quot;, &quot;Low&quot;, &quot;Low&quot;, &quot;Med.High&quot;, &quot;Low&quot;, &quot;Low&quot;, 
  &quot;High&quot;, &quot;High&quot;, &quot;Med.High&quot;, &quot;High&quot;, &quot;Med.High&quot;, &quot;Med.High&quot;, &quot;Medium&quot;, 
  &quot;High&quot;, &quot;Low&quot;, &quot;Low&quot;, &quot;Med.High&quot;, &quot;Low&quot;), hogs.fit = c(-0.122, 
  -0.871, -0.279, -0.446, 0.413, 0.011, 0.157, 0.131, 0.367, -0.23, 
  0.007, 0.05, 0.04, -0.184, -0.265, -1.071, -0.223, 0.255, -0.635, 
  -1.103, 0.008, -0.04, 0.831, 0.042, -0.005, -0.022, 0.692, 0.402, 
  0.615, 0.785, 0.758, 0.738, 0.512, 0.222, -0.424, 0.556, -0.128, 
  -0.495, 0.591, 0.923)), row.names = c(NA, -40L), groups = structure(list(
      Zone = c(&quot;B&quot;, &quot;D&quot;), .rows = structure(list(1:20, 21:40), ptype = integer(0), class = c(&quot;vctrs_list_of&quot;, 
      &quot;vctrs_vctr&quot;, &quot;list&quot;))), row.names = c(NA, -2L), class = c(&quot;tbl_df&quot;, 
  &quot;tbl&quot;, &quot;data.frame&quot;), .drop = TRUE), class = c(&quot;grouped_df&quot;, 
  &quot;tbl_df&quot;, &quot;tbl&quot;, &quot;data.frame&quot;))
  </code></pre>
  <p>I'm trying to add letters of significance based on a Tukeys HSD to the plot below...</p>
  <pre><code>library(agricolae)
  library(tidyverse)
  hogs.plot &lt;- ggplot(hogs.sample, aes(x = Zone, y = exp(hogs.fit), 
                                       fill = factor(Levelname, levels = c(&quot;High&quot;, &quot;Med.High&quot;, &quot;Medium&quot;, &quot;Low&quot;)))) +  
    stat_summary(fun = mean, geom = &quot;bar&quot;, position = position_dodge(0.9), color = &quot;black&quot;) +  
    stat_summary(fun.data = mean_se, geom = &quot;errorbar&quot;, position = position_dodge(0.9), width = 0.2) + 
    labs(x = &quot;&quot;, y = &quot;CPUE (+/-1SE)&quot;, legend = NULL) + 
    scale_y_continuous(expand = c(0,0), labels = scales::number_format(accuracy = 0.1)) + 
    scale_fill_manual(values = c(&quot;midnightblue&quot;, &quot;dodgerblue4&quot;, &quot;steelblue3&quot;, 'lightskyblue')) + 
    scale_x_discrete(breaks=c(&quot;B&quot;, &quot;D&quot;), labels=c(&quot;Econfina&quot;, &quot;Steinhatchee&quot;))+
    scale_color_hue(l=40, c = 100)+
   # coord_cartesian(ylim = c(0, 3.5)) +
    labs(title = &quot;Hogs&quot;, x = &quot;&quot;, legend = NULL) + 
    theme(panel.border = element_blank(), panel.grid.major = element_blank(), panel.background = element_blank(),
          panel.grid.minor = element_blank(), axis.line = element_line(),
          axis.text.x = element_text(), axis.title.x = element_text(vjust = 0),
          axis.title.y = element_text(size = 8))+
    theme(legend.title = element_blank(), 
          legend.position = &quot;none&quot;)
  hogs.plot
  </code></pre>
  <p>My ideal output would be something like this...</p>
  <p><a href="https://i.stack.imgur.com/GG2uD.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/GG2uD.png" alt="enter image description here" /></a></p>
  <p>I'm not sure if these letters are 100% accurate on my sample plot, but they signify which groups are significantly different from each other. Zones are independent, so I don't want any comparisons between the two zones so I was running them seperate with the following code.</p>
  <pre><code>hogs.aov.b &lt;- aov(hogs.fit ~Levelname, data = filter(hogs.sample, Zone == &quot;B&quot;))
  hogs.aov.summary.b &lt;- summary(hogs.aov.b)
  hogs.tukey.b &lt;- TukeyHSD(hogs.aov.b)
  hogs.tukey.b
  
  hogs.aov.d &lt;- aov(hogs.fit ~ Levelname, data = filter(hogs.sample, Zone == &quot;D&quot;))
  hogs.aov.summary.d &lt;- summary(hogs.aov.d)
  hogs.tukey.d &lt;- TukeyHSD(hogs.aov.d)
  hogs.tukey.d
  </code></pre>
  <p>I tried this route but I have many species other than hogs to apply this to.
  <a href="https://stackoverflow.com/questions/46463301/show-statistically-significant-difference-in-a-graph">Show statistically significant difference in a graph</a></p>
  <p>I can get the letters for one zone at a time, but I'm not sure how to add both zones to the plot. They are also out of order. I modified this code from a webpage and the letters do not place atop the bars nicely.</p>
  <pre><code>library(agricolae)
  library(tidyverse)
  # get highest point overall
  abs_max &lt;- max(bass.dat.d$bass.fit)
  # get the highest point for each class
  maxs &lt;- bass.dat.d %&gt;%
    group_by(Levelname) %&gt;%
    # I like to add a little bit to each value so it rests above
    # the highest point. Using a percentage of the highest point
    # overall makes this code a bit more general
    summarise(bass.fit=max(mean(exp(bass.fit))))
  # get Tukey HSD results
  Tukey_test &lt;- aov(bass.fit ~ Levelname, data=bass.dat.d) %&gt;%
    HSD.test(&quot;Levelname&quot;, group=TRUE) %&gt;%
    .$groups %&gt;%
    as_tibble(rownames=&quot;Levelname&quot;) %&gt;%
    rename(&quot;Letters_Tukey&quot;=&quot;groups&quot;) %&gt;%
    select(-bass.fit) %&gt;%
    # and join it to the max values we calculated -- these are
    # your new y-coordinates
    left_join(maxs, by=&quot;Levelname&quot;)
  </code></pre>
  <p>There are lots of examples like this too <a href="https://www.staringatr.com/3-the-grammar-of-graphics/bar-plots/3_tukeys/" rel="nofollow noreferrer">https://www.staringatr.com/3-the-grammar-of-graphics/bar-plots/3_tukeys/</a> but they all just add text manually. It would be nice to have code that can take the Tukey output and add the significance letter to the plot automatically.</p>
  <p>Thanks</p>