Search code examples
rggplot2axisx-axis

Add secondary x-axis at the bottom in ggplot


I want to create a plot and add a secondary z-axis. The problem is that I don't want the secondary axis on the top, but I want both x axis at the bottom of the graph. any ideas how to do it?

I have this data frame:

df <- read.table(text="Control     Stress days sd_control  sd_stress
-0.2866667 -0.2833333   X1 0.11846237 0.05773503
-0.2566667 -1.0333333   X2 0.08144528 0.15275252
-0.4766667 -1.4500000   X3 0.09291573 0.10000000
-0.4900000 -1.2766667   X4 0.21517435 0.22501852
-0.4600000 -1.2666667   X5 0.07549834 0.40722639
-0.2633333 -1.0833333   X6 0.12662280 0.10408330
-0.2833333 -1.0333333   X7 0.03511885 0.07767453", header=T)

I create a simple plot and add a secondary x-axis as follors:

ggplot(data=df,aes(x=Control, y=Stress))+geom_point()+scale_x_continuous(sec.axis = sec_axis(~ .+50,))

and get the following plot:

enter image description here

Now, how do I move the axis from top to bottom?

not sure if its possible in ggplot, but R has a function called axis() that can add a secondary axis with whatever characteristics to a regular plot.


Solution

  • another possibility:

    ggplot(data=df,aes(x=Control, y=Stress))+geom_point() +
      scale_x_continuous(labels = ~paste(., .+50, sep = "\n"),
                         name = "Primary axis\nSecondary axis")
    

    enter image description here


    With some more effort this could be extended to any arbitrary set of scales:

    labels <- data.frame(
      x = c(
        seq(-0.5, -0.25, length.out = 10),
        seq(-0.5, -0.25, length.out = 11)
      ),
      label = c(
        format(seq(-0.5, -0.25, length.out = 10), digits = 2),
        paste0("\n", LETTERS[1:11])
      )
    )
    
    
    ggplot(data=df,aes(x=Control, y=Stress))+geom_point() +
      scale_x_continuous(breaks = labels$x,
                         labels = labels$label,
                         minor_breaks = NULL)
    

    enter image description here

    Or we could overlay the 2nd axis as labels:

    ggplot(data=df,aes(x=Control, y=Stress))+geom_point() +
      scale_x_continuous(breaks = seq(-0.5, -0.25, length.out = 10),
                         labels = format(seq(-0.5, -0.25, length.out = 10), digits = 2)) +
      annotate("text", 
               x = seq(-0.5, -0.25, length.out = 11),
               y = -1.62,
               size = 2.5,
               label = LETTERS[1:11]) +
      coord_cartesian(ylim = c(-1.5, NA), clip = "off")
    

    (I haven't bothered to tweak the margin spacing to make room, but you get the idea.)

    enter image description here