1

I have an issue with aligning categorical x axis labels using facet_grid Its out of alignment and I cannot figure out how to force it to align.

enter image description here

my code:

ggplot(data=dataset, aes(x=Question)) + 
facet_grid(~Indicator,scales = "free_x")+
scale_x_discrete(labels = function(x) lapply(strwrap(x, width = 45, simplify = FALSE),paste, collapse="\n"))+
coord_cartesian(ylim = c(20, 90))+
  geom_line(aes(y = Result))+ geom_point(aes(y = Result))+
  geom_line(aes(y = Result_2))+ geom_point(aes(y = Result_2))+
  theme_minimal()+
  theme(
    axis.title.x=element_blank(),
    axis.text.x=element_text(angle = 90, hjust = 0, vjust = 0.5))

Data:

structure(list(Question = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 
7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 
20L, 21L, 22L, 23L, 24L, 25L, 26L, 32L, 33L, 34L, 35L, 36L, 37L, 
38L, 39L, 27L, 28L, 29L, 30L, 31L, 40L, 44L, 45L, 46L, 47L, 48L, 
49L, 50L, 51L, 41L, 42L, 43L), .Label = c("A.1 long label", "A.2 long label", 
"A.3 long label", "A.4 long label", "A.5 long label", "A.6 long label", 
"A.7 long label", "A.8 long label", "B.1 very long label", "B.2 very long label", 
"B.3 very long label", "B.4 very long label", "B.5 very long label", 
"B.6 very long label", "B.7 very long label", "B.8 very long label", 
"C.1 very long label", "C.2 very long label", "C.3 very long label", 
"C.4 very long label", "C.5 very long label", "C.6 very long label", 
"C.7 very long label", "C.8 very long label", "C.9 very long label", 
"D.1 very very long label", "D.10 very very long label", "D.11 very very long label", 
"D.12 very very long label", "D.13 very very long label", "D.14 very very long label", 
"D.2 very very long label", "D.3 very very long label", "D.4 very very long label", 
"D.5 very very long label", "D.6 very very long label", "D.7 very very long label", 
"D.8 very very long label", "D.9 very very long label", "E.1 very very long label", 
"E.10 very very long label", "E.11 very very long label", "E.12 very very long label", 
"E.2 very very long label", "E.3 very very long label", "E.4 very very long label", 
"E.5 very very long label", "E.6 very very long label", "E.7 very very long label", 
"E.8 very very long label", "E.9 very very long label"), class = "factor"), 
    Indicator = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
    3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
    5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L), .Label = c("A", 
    "B", "C", "D", "E"), class = "factor"), Index = c(47L, 44L, 
    48L, 46L, 50L, 45L, 49L, 51L, 37L, 36L, 38L, 39L, 40L, 41L, 
    43L, 42L, 30L, 28L, 32L, 27L, 29L, 31L, 33L, 34L, 35L, 14L, 
    15L, 16L, 17L, 18L, 19L, 20L, 21L, 23L, 13L, 22L, 25L, 26L, 
    24L, 4L, 5L, 2L, 3L, 1L, 7L, 9L, 8L, 10L, 12L, 6L, 11L), 
    Result = c(67.1, 62.9, 50.7, 59, 56.4, 50.4, 41.6, 65.9, 
    82.4, 84.8, 83.2, 87.1, 85.6, 79.3, 86.8, 78.9, 62, 73.7, 
    70.3, 81, 77, 55.1, 64.2, 62.2, 64.1, 62.7, 64.8, 62.3, 60.5, 
    49.4, 50.6, 72.6, 43.7, 49.3, 73.4, 56, 54.4, 56.1, 58.4, 
    72.1, 66.7, 78.2, 79.6, 80.7, 65.6, 59.5, 66.4, 53.5, 68, 
    76.3, 70.8), Result_2 = c(54.8, 61.4, 52.1, 58.5, 63.8, 47.4, 
    50.4, 69.8, 77.7, 79.3, 78.8, 82.1, 80.3, 72.6, 84.1, 74.2, 
    59.8, 68.6, 65.3, 75.8, 71.1, 49.1, 61.5, 53.3, 55.4, 54.4, 
    57.2, 57.5, 53.7, 41.2, 40.2, 65, 31.2, 37.3, 62.2, 47.3, 
    45.2, 47.2, 42.8, 65.5, 58.7, 70.6, 72.5, 73.9, 57.5, 52.6, 
    60.7, 44.3, 63.6, 69.7, 63.5)), class = "data.frame", row.names = c(NA, 
-51L))

The labels are seem to be stepped no matter how I seem to format them

Keelin
  • 367
  • 1
  • 10
  • 2
    Welcome to Stack Overflow! Could you make your problem reproducible by sharing a sample of your data so others can help (please do not use `str()`, `head()` or screenshot)? You can use the [`reprex`](https://reprex.tidyverse.org/articles/articles/magic-reprex.html) and [`datapasta`](https://cran.r-project.org/web/packages/datapasta/vignettes/how-to-datapasta.html) packages to assist you with that. See also [Help me Help you](https://speakerdeck.com/jennybc/reprex-help-me-help-you?slide=5) & [How to make a great R reproducible example?](https://stackoverflow.com/q/5963269) – Tung Mar 14 '20 at 01:03
  • Can you try `theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5))`? – Tung Mar 14 '20 at 01:13
  • @Tung thanks for this, hjust = 1 doesn't appear to work. I will try to follow the instructions for uploading the data.... – Keelin Mar 14 '20 at 01:23
  • 1
    The above code that I posted works for me on your data using the [latest development version of `ggplot2`](https://github.com/tidyverse/ggplot2). Here is the [output](https://i.imgur.com/t79Enqh.png). What version of `ggplot` do you have? – Tung Mar 14 '20 at 03:03
  • hi @Tung Yes thats it, you see the x axis in your output, its not aligned properly, its still stepped in the output you provided, thats the issue I am trying to address. Ideally I would like the axis labels all to be aligned – Keelin Mar 14 '20 at 03:05
  • 1
    How do you want them to look like? They perfectly align horizontally to me. Maybe you should draw the output by hand? – Tung Mar 14 '20 at 03:29
  • Thansk @Tjebo, I cant seem to modify the plot margins to work with this one but I like the hack in your previous question. The other thing I was trying to do (unsuccessfully) is to get the max number of characters and then pad them out `z <- row.names(dataset) z2 <- stri_pad_both(z, width = max(stri_width(z)))` but I cant then seem to successfully pad out the labels – Keelin Mar 14 '20 at 21:42
  • @Tjebo do you think you could help with the hack on the other page? I cant seem to get it to work – Keelin Mar 15 '20 at 03:12
  • 1
    @Tung just thought you may also be interested that there is now a nice solution for that see here https://stackoverflow.com/a/60815317/7941188 – tjebo Mar 24 '20 at 11:08
  • Great. Thanks @Tjebo! – Tung Mar 24 '20 at 14:20

1 Answers1

1

As per request - using the moderate hack from my other answer

I have also changed your plot code mildly. I'd suggest to have a look and understand what the advantages are - most importantly bringing the data into long format. Other convenience based changes was to define the aesthetics in the ggplot main call.

the data frame for the geom_text call needs the same values/ variabel for faceting !

May I also make a suggestion - if every x for each of your categories has the same long label - why don't you just bring this label into the facet strip, and then each x can have only the index as a label. long x labels don't really help visualisation. Long labels are generally much easier to read if you flip the graph, so they would be horizontal, but in most cases one really doesn't need long x labels.


library(tidyverse)

ann_x <- data.frame(Question = unique(dataset$Question), Indicator = str_sub(unique(dataset$Question), 1, 1))

dataset_l <- dataset %>% pivot_longer(names_to = "key", values_to = "value", cols = contains("result"))

ggplot(data = dataset_l, aes(x = Question, y = value)) +
  geom_line(aes(group = key)) +
  geom_point() +
  geom_text(data = ann_x, aes(y = -35, label = Question), angle = 90, hjust = 0, size = 5 / 14 * 10) +
  facet_grid(~Indicator, scales = "free_x") +
  coord_cartesian(ylim = c(20, 90), clip = "off") +
  theme(
    axis.title.x = element_blank(),
    axis.text.x = element_blank(),
    plot.margin = margin(0.1, 0.1, 2, 0.1, "in")
  )

Created on 2020-03-15 by the reprex package (v0.3.0)

tjebo
  • 21,977
  • 7
  • 58
  • 94
  • thank-you so very much for this, greatly appreciated works great in the real data. The labels are all different lengths some quite long. I simply used 3 different lengths to illustrate the problem. Thanks again! – Keelin Mar 15 '20 at 19:01