change position of tick marks of a single graph, using ggplot2

前端 未结 1 661
余生分开走
余生分开走 2020-12-18 10:56

Anybody knows how to draw the X-axis tickmarks at the top of a single plot in R, using ggplot2? I ve been looking at tutorials and mail lists and Rhelp without success.

相关标签:
1条回答
  • 2020-12-18 11:03

    Use position = 'top'

    library(ggplot2)
    
    # Generate some data
    df = data.frame(x = 1:10, y = 1:10)
    
    # x-axis breaks
    breaks = 1:10
    
    # base plot
    p <- ggplot(df, aes(x,y)) + geom_point() +
         scale_x_continuous(breaks = breaks, position = 'top') +
         scale_y_continuous(limits = c(0, 11), expand = c(0,0)) +
         theme_bw()
    

    Original solution available using gtable (with some updating to ggplot 2.1.0). See here

    library(ggplot2)
    library(gtable)
    library(grid)
    
    # Generate some data
    df = data.frame(x = 1:10, y = 1:10)
    
    # x-axis breaks
    breaks = 1:10
    
    # base plot
    p <- ggplot(df, aes(x,y)) + geom_point() +
         scale_x_continuous(breaks = breaks) +
         scale_y_continuous(limits = c(0, 11), expand = c(0,0)) +
         theme_bw() 
    
    
    # Get ggplot grob
    g1 <- ggplotGrob(p)  
    
    ## Get the position of the plot panel in g1
    pp <- c(subset(g1$layout, name == "panel", se = t:r))
    
    # Title grobs have margins. 
    # The margins need to be swapped.
    # Function to swap margins - 
    # taken from the cowplot package:
    # https://github.com/wilkelab/cowplot/blob/master/R/switch_axis.R
    vinvert_title_grob <- function(grob) {
      heights <- grob$heights
      grob$heights[1] <- heights[3]
      grob$heights[3] <- heights[1]
      grob$vp[[1]]$layout$heights[1] <- heights[3]
      grob$vp[[1]]$layout$heights[3] <- heights[1]
    
      grob$children[[1]]$hjust <- 1 - grob$children[[1]]$hjust 
      grob$children[[1]]$vjust <- 1 - grob$children[[1]]$vjust 
      grob$children[[1]]$y <- unit(1, "npc") - grob$children[[1]]$y
      grob
    }
    
    # Get  xlab  and swap margins
    index <- which(g1$layout$name == "xlab-b")
    xlab <- g1$grobs[[index]]
    xlab <- vinvert_title_grob(xlab)
    
    # Put xlab at the top of g1
    g1 <- gtable_add_rows(g1, g1$heights[g1$layout[index, ]$t], pp$t-1)
    g1 <- gtable_add_grob(g1, xlab, pp$t, pp$l, pp$t, pp$r, clip = "off", name="topxlab")
    
    # Get x axis (axis line, tick marks and tick mark labels)
    index <- which(g1$layout$name == "axis-b")
    xaxis <- g1$grobs[[index]]
    
    # Swap axis ticks and tick mark labels
    ticks <- xaxis$children[[2]]
    ticks$heights <- rev(ticks$heights)
    ticks$grobs <- rev(ticks$grobs)
    
    # Move tick marks
      #  Get tick mark length
      plot_theme <- function(p) {
        plyr::defaults(p$theme, theme_get())
      }
      tml <- plot_theme(p)$axis.ticks.length   # Tick mark length
    
    ticks$grobs[[2]]$y <- ticks$grobs[[2]]$y - unit(1, "npc") + tml
    
    # Swap tick mark labels' margins and justifications
    ticks$grobs[[1]] <- vinvert_title_grob(ticks$grobs[[1]])
    
    # Put ticks and tick mark labels back into xaxis
    xaxis$children[[2]] <- ticks
    
    # Add axis to top of g1
    g1 <- gtable_add_rows(g1, g1$heights[g1$layout[index, ]$t], pp$t)
    g1 <- gtable_add_grob(g1, xaxis, pp$t+1, pp$l, pp$t+1, pp$r, clip = "off", name = "axis-t")
    
    # Remove original x axis and xlab
    g1 = g1[-c(9,10), ]
    
    # Draw it
    grid.newpage()
    grid.draw(g1)
    
    0 讨论(0)
提交回复
热议问题