【问题标题】:Constant width in ggplot barplotsggplot条形图中的恒定宽度
【发布时间】:2013-08-28 01:32:32
【问题描述】:

如何使用ggplot 固定多个条形图的条形宽度和它们之间的空间,每个条形图上的条数不同?

这是一次失败的尝试:

m <- data.frame(x=1:10,y=runif(10))
ggplot(m, aes(x,y)) + geom_bar(stat="identity")

ggplot(m[1:3,], aes(x,y)) + geom_bar(stat="identity")

width=1 添加到geom_bar(...) 也无济于事。我需要第二个绘图自动具有较小的宽度和与第一个绘图相同的条形宽度和空间。

【问题讨论】:

    标签: r ggplot2 bar-chart geom-bar


    【解决方案1】:

    编辑:

    看来 OP 只是想要这个:

    library(gridExtra)
    grid.arrange(p1,arrangeGrob(p2,widths=c(1,2),ncol=2), ncol=1)
    

    我不确定是否可以将绝对宽度传递给geom_bar。所以,这是一个丑陋的黑客:

    set.seed(42)
    m <- data.frame(x=1:10,y=runif(10))
    p1 <- ggplot(m, aes(x,y)) + geom_bar(stat="identity")
    p2 <- ggplot(m[1:3,], aes(x,y)) + geom_bar(stat="identity")
    g1 <- ggplotGrob(p1)
    g2 <- ggplotGrob(p2)
    

    我使用str 找到了正确的 grob 和 child。如有必要,您可以使用更复杂的方法来概括这一点。

    #store the old widths
    old.unit <- g2$grobs[[4]]$children[[2]]$width[[1]]
    
    #change the widths
    g2$grobs[[4]]$children[[2]]$width <- rep(g1$grobs[[4]]$children[[2]]$width[[1]],
                                             length(g2$grobs[[4]]$children[[2]]$width))
    
    #copy the attributes (units)
    attributes(g2$grobs[[4]]$children[[2]]$width) <- attributes(g1$grobs[[4]]$children[[2]]$width)
    
    #position adjustment (why are the bars justified left???)
    d <- (old.unit-g2$grobs[[4]]$children[[2]]$width[[1]])/2
    attributes(d) <- attributes(g2$grobs[[4]]$children[[2]]$x)
    g2$grobs[[4]]$children[[2]]$x <- g2$grobs[[4]]$children[[2]]$x+d
    
    #plot
    grid.arrange(g1,g2)
    

    【讨论】:

    • 谢谢,无论如何只是为了缩小绘图的宽度 - 让条形宽度和空格保持不变?
    • 我不太确定你想要达到什么目标。也许调整规模限制?
    • 我已经更新了这个问题。我需要两个图中的条形宽度和条形之间的空间相同(因此第二个图宽度自动约为第一个图的 0.3)。调整规模限制如何帮助我实现目标?你有例子吗?
    • grid.arrange(p1,arrangeGrob(p2,widths=c(1,2),ncol=2), ncol=1) 会满足您的需求吗?我确信它可以通过编程方式完成,但坦率地说,我没有看到你的任何努力,这并没有激励我。
    • 谢谢,您的评论非常完美。您可以将其添加到您的答案中,我很乐意将其标记为已接受
    【解决方案2】:

    将其他建议包装在一个只需要一个图表的函数中。

    fixedWidth <- function(graph, width=0.1) {
      g2 <- graph
    
      #store the old widths
      old.unit <- g2$grobs[[4]]$children[[2]]$width[[1]]
      original.attibutes <- attributes(g2$grobs[[4]]$children[[2]]$width)
    
      #change the widths
      g2$grobs[[4]]$children[[2]]$width <- rep(width,
                                               length(g2$grobs[[4]]$children[[2]]$width))
    
      #copy the attributes (units)
      attributes(g2$grobs[[4]]$children[[2]]$width) <- original.attibutes
    
      #position adjustment (why are the bars justified left???)
      d <- (old.unit-g2$grobs[[4]]$children[[2]]$width[[1]])/2
      attributes(d) <- attributes(g2$grobs[[4]]$children[[2]]$x)
      g2$grobs[[4]]$children[[2]]$x <- g2$grobs[[4]]$children[[2]]$x+d
    
      return(g2)
    }
    

    【讨论】: