1

I have a boxplot that I've created using ggboxplot. On it I have a horizontal line at the mark y=50. I want to be able to add a label at y=50, x=0 saying "50" in dark green to match the line. Currently the label overlaps the axis line and the boxplots have shifted to the right. Any suggestions?

Problem

enter image description here

Current Code

symnum.args <- list(cutpoints = c(0, 0.0001, 0.001, 0.01, 0.05, 1), symbols = c("", "", "", "", "ns"))

my_comparisons<- list(c('BVR3', 'BVR4'), c('BVR6', 'BVR1'), c('BVR6', 'BVR2'), c('BVR6', 'BVR4'), c('BVR6', 'BVR5'))
plot <- ggboxplot(TPdat, x = "loc", y = "TP", 
          ylab = "Median Annual Total Phosphorus (\U00B5g/L)", xlab = "Sampling Site", 
          outlier.shape=NA, ylim=c(0, 925)) +
          scale_x_discrete(labels=c('1','2','3','4','5','6')) +
  theme(axis.text=element_text(size=16, family='Calibri'),
        axis.title=element_text(size=16, family='Calibri')) +
  geom_hline(yintercept=50, col='dark green', linetype=2) +
  coord_cartesian(clip='off', ylim=c(0, NA)) +
  annotate("text", x=0, y=50, label="50", colour='dark green', size=5) +
  stat_compare_means(comparisons=my_comparisons, label='p.signif', 
                     symnum.args = symnum.args, 
                     tip.length = c(0.01,0.01,0.01,0.01,0.01), 
                     label.y=c(800, 825, 850, 875, 900)) +
  stat_compare_means(label.y=930, family='Calibri', size=5)

head of dataframe

structure(list(loc = structure(c(1L, 1L, 1L, 1L, 1L, 1L), levels = c("BVR1", 
"BVR2", "BVR3", "BVR4", "BVR5", "BVR6"), class = "factor"), TP = c(76L, 
71L, 86L, 48L, 58L, 73L)), row.names = c(NA, 6L), class = "data.frame")
zx8754
  • 52,746
  • 12
  • 114
  • 209
Melanie Baker
  • 449
  • 1
  • 13

2 Answers2

3

Based on alistaire's answer suggested here Change color of specific tick in ggplot2 we could do:

library(ggplot2)

    ggplot(iris, aes(x=Species, y=Sepal.Length)) + 
      geom_boxplot() +
      scale_y_continuous(breaks=c(5,6,7,7.5,8), 
                         labels=expression("5", "6", "7", "7.5", "8")) +
      geom_hline(yintercept=7.5, col='dark green', linetype=2) +
      theme(axis.text.y = element_text(colour = c('black', 'black','black', 'dark green', 'black')))

I used the iris dataset to ilustrate how to get one specifick tickmark colored green. Hope it helps

Boxplot with one tickmark green:

enter image description here

This method works with ggpubr, too:

ggboxplot(iris, x = "Species", y = "Sepal.Length") +
  scale_y_continuous(breaks=c(5,6,7,7.5,8), 
                     labels=expression("5", "6", "7", "7.5", "8")) +
  geom_hline(yintercept=7.5, col='dark green', linetype=2) +
  theme(axis.text.y = element_text(colour = c('black', 'black','black', 'dark green', 'black')))
zx8754
  • 52,746
  • 12
  • 114
  • 209
juan_bzt
  • 224
  • 5
1

As in the answer by @juan_bzt the easiest approach to add your annotation would be to add it as an (probably additional) axis break. Doing so will avoid the overlapping with the axis line and will not affect the range of the scale.

However, besides the option of passing a vector of colors to the color argument of element_text a second option would be to use ggtext::element_markdown which also for styling via some HTML, CSS and/or markdown. In the code below I pass an ifelse to the labels argument of scale_y_continuous which wraps a break at y=50 in a span tag with a dark green color:

library(ggpubr)
library(ggtext)

ggboxplot(TPdat,
  x = "loc", y = "TP",
  ylab = "Median Annual Total Phosphorus (\U00B5g/L)", xlab = "Sampling Site",
  outlier.shape = NA, ylim = c(0, 925)
) +
  scale_x_discrete(labels = c("1", "2", "3", "4", "5", "6")) +
  theme(
    axis.text = element_text(size = 16, family = "Calibri"),
    axis.title = element_text(size = 16, family = "Calibri")
  ) +
  geom_hline(yintercept = 50, col = "dark green", linetype = 2) +
  coord_cartesian(clip = "off", ylim = c(0, NA)) +
  scale_y_continuous(
    labels = ~ ifelse(
      .x == 50,
      paste0("<span style='color: \"dark green\"'>", .x, "</span>"),
      as.character(.x)
    )
  ) +
  stat_compare_means(
    comparisons = my_comparisons, label = "p.signif",
    symnum.args = symnum.args,
    tip.length = c(0.01, 0.01, 0.01, 0.01, 0.01),
    label.y = c(800, 825, 850, 875, 900)
  ) +
  stat_compare_means(label.y = 930, family = "Calibri", size = 5) +
  theme(axis.text.y = ggtext::element_markdown())

enter image description here

stefan
  • 90,330
  • 6
  • 25
  • 51