Home > Back-end >  Multi-row x-axis labels with breaks in R
Multi-row x-axis labels with breaks in R

Time:05-20

I would like to add 2-row x-axis labels on my line plot, but not sure how to also incorporate the continuous labels and breaks I have for my 1st x-axis (Column "CYR" - short for calendar year). I'd like to have the 2nd axis (WYR) start half-way between the first label and the second (WYR = 2010 starts between CYR = 2009 -> 2010). I also wasn't sure how to add 2 x-axis titles either, maybe at the beginning of each x-axis row?

My data:

> dput(wet_pivot)
structure(list(WYR = c("WR_2010", "WR_2011", "WR_2012", "WR_2013", 
"WR_2014", "WR_2015", "WR_2016", "WR_2017", "WR_2018", "WR_2019", 
"WR_2020", "WR_2021", "WR_2022"), CYR = c(2009, 2010, 2011, 2012, 
2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021), Season = structure(c(2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("DRY", 
"WET"), class = "factor"), N = c(59L, 63L, 69L, 70L, 72L, 71L, 
71L, 72L, 71L, 68L, 70L, 48L, 72L), n_mean = c(0.00696806934430411, 
0.000649730847004026, 0.00288256551918419, 0.01141088388474, 
0.000536174103147671, 0.00349584646220785, 0.000482925207291882, 
0.00245359625194744, 0.00292096956686587, 0.00252817293686805, 
0.00196286772014134, 0.00501799463867351, 0.00132244297252478
), n_median = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), sd = c(0.030946706350869, 
0.00248965525641742, 0.0100973832581282, 0.051577934580242, 0.00331468784320076, 
0.0266064084754242, 0.00212505905295283, 0.00675243933898364, 
0.0119729983336735, 0.00639785127193391, 0.00930625647382774, 
0.0136275258272549, 0.00543420856675111), se = c(0.00402891799826298, 
0.000313667078988821, 0.00121558209746373, 0.0061647423020683, 
0.000390639708573979, 0.00315759975690469, 0.000252198110662322, 
0.000795782607691024, 0.00142093348159893, 0.000775853428563995, 
0.00111231039833223, 0.00196696392618855, 0.000640427621321956
)), row.names = c(NA, -13L), class = "data.frame")

My attempt:

years <- seq(2009,2021,1)
labs <- seq(2009,2021,by=1)

myplot <- ggplot(wet_pivot, aes(x = CYR, y = n_mean))  
  geom_errorbar(aes(ymin=n_mean-se, ymax=n_mean se), width=.2, color = "black")  
  geom_point(color = "black", shape = 1, size = 2)  
geom_line(color = "black")  
  scale_y_continuous(limits = c(0, 0.04), expand = expansion(mult = c(0, 0.05)))  
  scale_x_continuous(breaks= years, labels = labs)

myplot  
annotate(geom = "text",
             x = 1:nrow(wet_pivot),
             y = min(wet_pivot$n_mean),
             label = labs,
             vjust = 3.5)  
annotate(geom = "text",
             x = 1:nrow(wet_pivot),
             y = min(wet_pivot$n_mean),
             label = wet_pivot$WYR,
             vjust = 5)

CodePudding user response:

You indeed can use text annotations to substitute for x-axis labels. A few recommendations:

  • Set y = -Inf to automatically place text as bottom, independent of whatever data is on the plot. vjust can indeed be used to place it further down.
  • You'd need coord_cartesian(clip = "off") to actually show the text.
  • You can place 'titles' with an extra annotation layer, with x = -Inf to place it on the left.

I used the above for the example below. Maybe the text is still to big, so you could set the 8.8 / .pt to something smaller. (The / .pt translates between mm, which geom_text() uses, to points, which is used in theme)

library(ggplot2)

# wet_pivot <- structure(...) # omitted for previty

ggplot(wet_pivot, aes(x = CYR, y = n_mean))  
  geom_errorbar(aes(ymin=n_mean-se, ymax=n_mean se), width=.2, color = "black")  
  geom_point(color = "black", shape = 1, size = 2)  
  geom_line(color = "black")  
  scale_y_continuous(limits = c(0, 0.04), expand = expansion(mult = c(0, 0.05)))  
  scale_x_continuous(breaks= years, labels = ~ rep("", length(.x)))  
  annotate(geom = "text",
           x = wet_pivot$CYR,
           y = -Inf,
           label = labs, 
           size = 8.8 / .pt,
           vjust = 2.5)  
  annotate(geom = "text",
           x = wet_pivot$CYR,
           y = -Inf,
           label = wet_pivot$WYR, 
           size = 8.8 / .pt,
           vjust = 4)  
  # Titles
  annotate(geom = "text",
           x = -Inf,
           y = -Inf,
           label = c("CYR", "WYR"),
           vjust = c(2.5, 4), hjust = 1,
           size = 8.8 / .pt
           )  
  coord_cartesian(clip = "off")  
  theme(
    # Make extra space between axis ticks and axis title
    axis.text.x.bottom = element_text(margin = margin(t = 8.8, b = 8.8))
  )

Created on 2022-05-19 by the reprex package (v2.0.1)

  • Related