rggplot2

Trying to plot every 4th label on the x-axis in ggplot2


I have this figure, and as you can see, the x-axis is labelled every 2nd year. Now, since it is visibly congested, I am trying to make it every 4th year, i.e. 1990, 1994, 1998 and so on. How do I go about doing this? The following is the relevant code:

  ggplot(YLLs_and_YLDs_data, aes(x = year, y = val, color = measure)) +
    geom_line(aes(group = measure)) +
    geom_point(aes(color = measure), position = position_dodge(0.4)) +
    scale_x_discrete(guide = guide_axis(check.overlap = TRUE)) +
    scale_y_continuous(labels = function(x) format(x, big.mark = ",", scientific = FALSE), sec.axis = sec_axis(~ . /10, labels = label_number(big.mark = ","), name = "Years Lived with Disability (count)"))+
    geom_errorbar(aes(ymin = lower, ymax = upper), width = 0.2, size = 1.0, position = position_dodge(0.4)) +
    labs(x = "Year", y = "Years of Life Lost (count)") +
    theme_classic() +
    theme(axis.title = element_text(face = "bold"), axis.line = element_line(linewidth = 0.9, colour = "black"),
          axis.text.x = element_text(face = "bold", size = 10), axis.text.y = element_text(face = "bold", size = 10),
          panel.grid.major.x = element_line())


Solution

  • Here are two ways. I've included a bit of sample data for reproducibility, and excluded the formatting that doesn't relate as directly to your question. I'm assuming your years are factors, but they could be character and I expect it would work out the same.

    Keeping your discrete axis and using a function to pick out the labels we want to show (here, those values two less than multiples of 4). Note, in this variation there are breaks at every value (resulting in tick marks), but only every fourth break is labeled.

    data.frame(year = factor(1990:2022), val = 8E6 * 1.1 ^(0:32)) |>
      ggplot(aes(x = year, y = val)) +
      geom_line(group = 1) +
      geom_point() +
      scale_x_discrete(labels = \(x) ifelse((as.numeric(x) + 2) %% 4 == 0, x, ""))
    

    enter image description here Or we could translate years to numbers before we use them, or in the mapping, and use a normal continuous axis. This method arguably gives us more flexibility as to how the labels and ticks and minor breaks work.

    data.frame(year = factor(1990:2022), val = 8E6 * 1.1 ^(0:32)) |>
      ggplot(aes(x = as.numeric(as.character(year)), y = val)) +
      geom_line(group = 1) +
      geom_point() +
      scale_x_continuous(breaks = seq(1990, 2022, 4),
                         minor_breaks = 1990:2022)
    

    enter image description here

    We could use scale_x_continuous(breaks = 1990:2022, minor_breaks = NULL, label = \(x) ifelse((x + 2) %% 4 == 0, x, "")) to get a result more similar to the one above, with ticks & major break lines at every year.

    enter image description here