0

I am trying to add a text element with further information on the x-axis (once) on the left side of my x-axis text of a faceted ggplot (not repeat it every facet):

enter image description here

I failed until now having tried several approaches:

  • geom_text (appears within the plot)
  • annotating function (appears within the plot in every facet)
  • axis.title.x (can't customize the position as desired, namely x=- 1 and y=-1 more or less)
  • mtext (not suitable for ggplot)

My code:

#1.1 create labels for x-axis:
cfutypes_labels <- c("native\n-\n-", "native\n-\n+",
                     "aliquot\n-\n-", "aliquot\n-\n+",
                     "aliquot\n+\n-", "aliquot\n+\n+")

names(cfutypes_labels) <- c("no.0.native", "yes.0.native", 
                            "no.0.aliquot","yes.0.aliquot", 
                            "no.20.aliquot", "yes.20.aliquot")

extra_axis <- c("storagetype\nglycerol\nfreeze-thaw-cycle")

#1.2 plotting

plot_t1calc1 <- thawcycles_long %>%
  filter(dilution_potency<5,
         count >0, cfutype =="cfuperml") %>%
  ggplot(aes(x=interaction(thawcycle,
                           glycerol_content,
                           storagetype), 
             y=count,
             color=interaction(thawcycle,
                               glycerol_content,
                               storagetype))) +
  geom_jitter(width=0.2,
              alpha=0.8,
              show.legend = FALSE)+
  stat_summary(geom = "crossbar",
               fun = "geometric.mean",
               width = 0.3,
               show.legend = FALSE)+
  scale_y_log10(breaks = trans_breaks("log10", function(x) 10^(x+1)),
                labels = trans_format("log10", math_format(10^.x))) +
  scale_x_discrete(labels = cfutypes_labels)+
  ylab("CFU per mL") + 
  xlab("")+
  facet_grid(~timepoint,
             scales="free_x",
             space="free")+
  theme_minimal()+
  theme(panel.background = element_rect(fill = "white"),
      #  axis.title.x = element_text(hjust = -0.5, 
       #                             vjust= 0.9,
        #                            size=9),
        axis.line = element_line(color="black",
                                 size=0.2),
        strip.text = element_text(face="bold"))

A tibble of my dataset:

> tibble(thawcycles_long)
# A tibble: 567 x 9
     sid timepoint storagetype thawcycle glycerol_content dilution_potency cfutype       dotnumber    count
   <dbl> <chr>     <chr>       <chr>                <dbl>            <dbl> <chr>         <chr>        <dbl>
 1     4 t0        native      no                       0                3 dill1_cfu     1              104
 2     4 t0        native      no                       0                3 dill1_cfu     2               83
 3     4 t0        native      no                       0                3 dill1_cfu     3              106
 4     4 t0        native      no                       0                3 cfuperml      1         10400000
 5     4 t0        native      no                       0                3 cfuperml      2          8300000
 6     4 t0        native      no                       0                3 cfuperml      3         10600000
 7     4 t0        native      no                       0                3 auxv_cfuperml 1         10400000
 8     4 t0        native      no                       0                3 auxv_cfuperml 2          8300000
 9     4 t0        native      no                       0                3 auxv_cfuperml 3         10600000
10     4 t0        native      no                       0                4 dill1_cfu     1                7

Does anybody have an idea how to fix this? Many thanks in advance!

1 Answer 1

1

One option would be to make use of geom_text like so:

Important is to add coord_cartesian(clip = "off", ylim = c(1, NA)) to fix the y scale and to prevent the label from being clipped off.

Additionally you have to make some space for the label which I did by increasing the plot margins.

extra_axis <- c("storagetype\nglycerol\nfreeze-thaw-cycle")

library(ggplot2)

ggplot(thawcycles_long, aes(x = var, y = count, color = var)) +
  geom_jitter(width = 0.2, alpha = 0.8, show.legend = FALSE) +
  scale_x_discrete(labels = cfutypes_labels) +
  scale_y_log10(breaks = scales::trans_breaks("log10", function(x) 10^(x+1)),
                labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  labs(y = "CFU per mL", x = NULL) +
  facet_grid(~timepoint, scales = "free_x",  space = "free") +
  theme_minimal() +
  theme(
    panel.background = element_rect(fill = "white"),
    axis.line = element_line(color = "black",size = 0.2),
    strip.text = element_text(face = "bold"),
    plot.margin = margin(5.5, 5.5, 16.5, 55, unit = "pt")
  ) +
  geom_text(data = data.frame(timepoint = "t0"), aes(label = extra_axis), x = -1, y = -.1, 
            inherit.aes = FALSE, color = "red", hjust = .5, vjust = 1, size = 8 / .pt) +
  coord_cartesian(clip = "off", ylim = c(1, NA))

DATA

set.seed(42)

thawcycles_long <- data.frame(
  thawcycle = sample(c("yes", "no"), 20, replace = TRUE),
  glycerol_content = sample(c(0, 20), 20, replace = TRUE),
  storagetype = sample(c("native", "aliquot"), 20, replace = TRUE),
  count = 1:20,
  timepoint = sample(c("t0", "t1"), 20, replace = TRUE)
)
thawcycles_long$var <- interaction(
  thawcycles_long$thawcycle,
  thawcycles_long$glycerol_content,
  thawcycles_long$storagetype
)
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the quick response @stefan Do you know how to adapt the coord_cartesian(clip = "off", ylim = c(0, NA)) to the logarithmic scale? Taking your suggested code gives me an error message: Error in grid.Call.graphics(C_setviewport, vp, TRUE) : non-finite location or/and size of the viewport.
Hi Anika. Not a big deal. Issue is of course that there is no log(0). I just made an edit added the log scale and set ylim = c(1, NA). Depending on your desired result and the range of your data you probably have adjust the lower bound for the limits.
Hi Stefan, thank you! sorryt to bother you, one more question: when I set the ylim as suggested, my plot becomes unnecessarily large, as the first values appear from about 10^5 on. Hence I adapted the coord_cartesian limits and the x/y values for the geom_text element. Unfortunately, I get an error message here: Error in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : Polygon edge not found" Any idea how to deal with this?
Hm. Unfortunately I can't reproduce the issue. What I tried was to increase the range of my example data to 10^5 * c(1:20). Then I set ylim = c(10^5, NA) and y = 4.9 (= 5 -.1). Worked fine.

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.