Search code examples
rggplot2x-axis

In R, how to combine date and number unit in x-axis?


I have one data as below.

dataA = data.frame(structure(list(Sampling_date = structure(c(1684368000, 1685318400, 
                                           1685923200, 1686528000, 1687737600, 1688256000, 1688774400, 1689552000, 
                                           1690156800, 1691366400, 1691971200, 1693094400, 1694131200, 1694908800, 
                                           1695340800), class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
               Day = c(0, 11, 18, 25, 39, 45, 51, 60, 67, 81, 88, 101, 113, 
                       122, 127), Gas_Flux = c(2, 2.54, 1.96, 0.65, 0.88, 0.93, 
                                               0, 0.75, 0.68, 0.84, 0.78, 0.91, 3.42, 2.3, 0.94)), class = c("tbl_df", 
                                                                                                             "tbl", "data.frame"), row.names = c(NA, -15L)))

   Sampling_date Day Gas_Flux
1     2023-05-18   0     2.00
2     2023-05-29  11     2.54
3     2023-06-05  18     1.96
4     2023-06-12  25     0.65
5     2023-06-26  39     0.88
6     2023-07-02  45     0.93
7     2023-07-08  51     0.00
8     2023-07-17  60     0.75
9     2023-07-24  67     0.68
10    2023-08-07  81     0.84
11    2023-08-14  88     0.78
12    2023-08-27 101     0.91
13    2023-09-08 113     3.42
14    2023-09-17 122     2.30
15    2023-09-22 127     0.94

and I made a line graph over date.

ggplot(data=dataA, aes(x=Sampling_date, y=Gas_Flux))+
  geom_line (size=0.5)+
  geom_point(size=5, alpha=0.5) +
  scale_x_datetime(date_breaks = "14 day", date_labels = "%b/%d") +
  scale_y_continuous(breaks = seq(0,5,1), limits = c(0,5)) +
  theme_classic (base_size=20, base_family="serif")+
  theme(legend.position=c(0.93,0.10),
        legend.title=element_blank(),
        legend.key=element_rect(color=alpha("grey",.05), fill=alpha("grey",.05)),
        legend.background= element_rect(fill=alpha("grey",.05)),
        axis.line=element_line(linewidth=0.5, colour="black"))+
windows(width=12, height=8)

enter image description here

But I also need to show the experiment day corresponding to each date. So, what I want is like a below graph.

Could you tell me how to combine date and number unit in x-axis?

Always thanks!!

enter image description here


Solution

  • This might be possible with some annotations or the right addon package, but I suspect simplest to make a dummy plot with the extra axis and combine them with patchwork, which does the heavy lifting for alignment.

    library(patchwork)
    a <- ggplot(data=dataA, aes(x=Sampling_date, y=Gas_Flux))+
      geom_line (size=0.5)+
      geom_point(size=5, alpha=0.5) +
      scale_x_datetime(date_breaks = "14 day", date_labels = "%b/%d") +
      scale_y_continuous(breaks = seq(0,5,1), limits = c(0,5)) +
      theme_classic (base_size=20, base_family="serif")+
      theme(legend.position=c(0.93,0.10),
            legend.title=element_blank(),
            legend.key=element_rect(color=alpha("grey",.05), fill=alpha("grey",.05)),
            legend.background= element_rect(fill=alpha("grey",.05)),
            axis.line=element_line(linewidth=0.5, colour="black"))
    
    b <- ggplot(data=dataA, aes(x=Day, y=Gas_Flux))+
      scale_x_continuous(breaks = scales::breaks_width(14)) +
      theme_classic (base_size=20, base_family="serif")+
      theme(axis.line.y = element_blank(),
            axis.text.y = element_blank(),
            axis.ticks.y = element_blank(),
            axis.title.y =element_blank(),
            axis.line=element_line(linewidth=0.5, colour="black"))
    
    a/b + plot_layout(heights = c(30,1)) 
    # "30" = some big number to minimize any extra space for the bottom plot.
    # Reduce plot.margin etc to squeeze closer together.
    

    enter image description here

    Or with just the experiment days shown:

    b <- ...
       scale_x_continuous(breaks = dataA$Day) +
    

    enter image description here