Search code examples
rggplot2

Increase distance between x axis ticks with discrete data and facets


I have the following dataset:

structure(list(x = c(75, 77, 84, 73, 62, 74, 55, 20, 73, 89, 
36, 49, 72, 92, 54, 76, 40, 40, 46, 85, 19, 25, 75, 16, 84, 58, 
85, 26, 87, 20, 39, 61, 88, 89, 81, 73, 60, 87, 95, 86), variable = c("Var1", 
"Var1", "Var1", "Var1", "Var1", "Var1", "Var1", "Var1", "Var1", 
"Var1", "Var1", "Var1", "Var1", "Var1", "Var1", "Var1", "Var1", 
"Var1", "Var1", "Var1", "Var2", "Var2", "Var2", "Var2", "Var2", 
"Var2", "Var2", "Var2", "Var2", "Var2", "Var2", "Var2", "Var2", 
"Var2", "Var2", "Var2", "Var2", "Var2", "Var2", "Var2"), value = c("A", 
"A", "A", "A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", 
"B", "B", "B", "B", "B", "B", "C", "C", "C", "C", "C", "C", "C", 
"C", "C", "C", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D"
)), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-40L), groups = structure(list(value = c("A", "B", "C", "D"), 
    .rows = structure(list(1:10, 11:20, 21:30, 31:40), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), row.names = c(NA, -4L), .drop = TRUE, class = c("tbl_df", 
"tbl", "data.frame")))

I wish to increase the distance between the two x axis ticks so that the points in each plot does not overlap, as shown with the orange arrows in the figure below.

I have tried to do the following:

library(ggplot2)
library(ggdist)

ggplot(testdata, aes(value, x)) +
  stat_halfeye(
    adjust = 0.5,
    justification = -0.15,
    .width = 0,
    point_color = NA
  ) +
  geom_boxplot(
    width = 0.12,
    outlier.color = NA
  ) +
  stat_dots(
    side = "left",
    justification = 1.15,
    size = 0.01,
    fill = "red"
  ) +
  facet_wrap(~variable, scales = "free_x") +
  scale_x_discrete(
    expand = expansion(mult = c(0.5, 0.5)) 
  )

But this makes no difference in the distance between the two axis ticks. I have also tried to play around with position = position_dodge() and position_dodgejust() from ggdist, but none of them seem to work. How do I increase the distance between them?

enter image description here


Solution

  • And yet another option would be to the ggh4x package which via ggh4x::scale_x_manual gives some more fine control to place the breaks of a discrete scale, i.e. we can increase the distance between breaks. However, to make this work with facet_wrap I had to combine with ggh4x::facetted_pos_scales to individually set the breaks per panel. Additionally, it took me some experimentation to set the right values for the breaks per panel. Hence, I'm not sure whether this approach can be easily applied for more general cases. But perhaps I only miss something about ggh4x::scale_x_manual:

    library(ggplot2)
    library(ggdist)
    
    ggplot(testdata, aes(value, x)) +
      stat_halfeye(
        adjust = 0.5,
        justification = -0.15,
        .width = 0,
        point_color = NA
      ) +
      geom_boxplot(
        width = 0.12,
        outlier.color = NA
      ) +
      stat_dots(
        side = "left",
        justification = 1.15,
        size = 0.01,
        fill = "red"
      ) +
      facet_wrap(~variable, scales = "free_x") +
      ggh4x::facetted_pos_scales(
        x = list(
          ggh4x::scale_x_manual(
            values = c(1, 3)
          ),
          ggh4x::scale_x_manual(
            values = c(2, 4)
          )
        )
      )
    

    enter image description here