0

I am attempting to copy an answer from a previous stackoverflow post (Multi-row x-axis labels in ggplot line chart) however, I would like to apply this to a multi-facetted plot.

The toy data.

df <- data.frame(START = rep(seq(1:10),2),
                 SAMPLE = rep(c("A", "B"), each=10),
                 yaxis = runif(20, min = 1, max = 10),
                 xaxis1 = rep(c("E1", "E1", "E2", "E2", "E1", "E2", "E3", "E4", "E1", "E2"),2),
                 xaxis2 = rep(c("G1", "G1", "G1", "G1", "G2", "G2", "G2", "G2", "G3", "G3"),2))

Here I would like xaxis1 to be present for each tick, and xaxis2 to be appear only once - similar to how the YEAR-QRT plot looks in the post above.

Without any annotations the plots looks as so.

ggplot(data = df, aes(x = interaction(START,xaxis1, xaxis2), y = yaxis, 
                    group = 1, fill=yaxis)) +
geom_col(width = 1, position = "identity") +
facet_wrap(SAMPLE ~., ncol= 1, strip.position="left")

enter image description here

When I attempt to add the annotation code ontop of the plot I get unequal parameter length error.

ggplot(data = df, aes(x = START, y = yaxis, 
                      group = 1, fill=yaxis)) +
  geom_col(width = 1, position = "identity") +
  annotate(geom = "text", x = seq_len(nrow(df)), y = 34,
           label = df$xaxis1, size = 4)+
  annotate(geom = "text", x = seq_len(nrow(df)), y = 32,
           label = unique(df$xaxis2), size = 6)
Krutik
  • 461
  • 4
  • 13

1 Answers1

1

Borrowing the idea from the answer by @Henrik but taking a slightly different route in so far as I use two geom_text layers and separate data frames to place the annotations.

library(ggplot2)
library(dplyr, warn=FALSE)

axis1 <- df |> 
  distinct(START, xaxis1, SAMPLE = "B")

axis2 <- df |> 
  distinct(START, xaxis2, SAMPLE = "B") |> 
  group_by(xaxis2, SAMPLE) |> 
  summarise(START = mean(START))
#> `summarise()` has grouped output by 'xaxis2'. You can override using the
#> `.groups` argument.

ggplot(data = df, aes(x = START, y = yaxis, 
                      group = 1)) +
  geom_col(aes(fill =yaxis),width = 1, position = "identity") +
  facet_wrap(SAMPLE ~., ncol= 1, strip.position="left") +
  geom_text(data = axis1, aes(label = xaxis1), y = -2.5, size = 4) +
  geom_text(data = axis2, aes(label = xaxis2), y = -4, size = 6) +
  coord_cartesian(clip = "off") +
  theme(plot.margin = margin(5.5, 5.5, b = 55.5, 5.5, "pt"),
        axis.title.x = element_blank())

enter image description here

stefan
  • 90,330
  • 6
  • 25
  • 51