【问题标题】:ggplot2 bar plot, no space between bottom of geom and x axis keep space aboveggplot2条形图,geom底部和x轴之间没有空间保持上方空间
【发布时间】:2013-12-11 19:02:50
【问题描述】:

当我在 ggplot2 中绘制条形图时,我想将条形底部和 x 轴之间的空间减少到 0,但保持条形和绘图框上方的空间。我在下面有一个技巧。它很脏,我想再次清洁。有没有办法在没有肮脏的小技巧的情况下实现这种行为?

默认(希望上方有空格,但不希望下方有空格):

ggplot(mtcars, aes(x=as.factor(carb))) + 
    geom_bar()

使用扩展(上面不需要 0 个空格,但在条形下面得到了 0 个空格):

ggplot(mtcars, aes(x=as.factor(carb))) + 
    geom_bar() + 
    scale_y_continuous(expand = c(0,0)) 

Dirty Hack(我喜欢它,但它......好吧,很脏):

ggplot(mtcars, aes(x=as.factor(carb))) + 
    geom_bar() + 
    scale_y_continuous(expand = c(0,0)) +
    geom_text(aes(x=1, y=10.3, label="Stretch it"), vjust=-1)

【问题讨论】:

  • 我假设您也考虑使用coord_cartesian 进行大量硬编码?
  • @baptise 您可以添加为未来搜索者的解决方案。这也有效。
  • 好问题,这也让我在 ggplot2 图中感到恼火,因为 y 轴不是从相框底部开始的。
  • 有一个新的(呃)问题指向这个问题,really great solutionexpand() 概括为上限扩展和下限扩展列表。

标签: r ggplot2


【解决方案1】:

R 文档包含一个名为 expansion 的新便利函数,用于 expand 参数,因为 expand_scale()ggplot2 v3.3.0 release 起已弃用。

ggplot(mtcars) +
  geom_bar(aes(x = factor(carb))) + 
  scale_y_continuous(expand = expansion(mult = c(0, .1)))

【讨论】:

  • 这是正确答案,应该打勾。
  • 诀窍是使用扩展组合 .1 这在我查找的许多答案中并未提及
【解决方案2】:

ggplot2 3.0.0 开始,有一个 expand_scale() 函数可以与 expand 参数一起使用来做到这一点。您分别定义顶部和底部扩展。

ggplot(mtcars, aes(x=factor(carb))) + 
     geom_bar() +
     scale_y_continuous(expand = expand_scale(mult = c(0, .1)))

【讨论】:

    【解决方案3】:

    这是一种自动生成顶部间距的方法,但会删除底部间距。我使用 3 % 的填充,因为那是你硬编码的。

    plot1 <- ggplot(mtcars, aes(x=as.factor(carb))) +
        geom_bar()
    
    plotInfo <- print(plot1)
    yMax <- max(plotInfo$data[[1]]$ymax)
    yLimitMax <- 1.03 * yMax
    
    plot2 <- plot1 +
        scale_y_continuous(expand = c(0,0),
                           limits = c(0,yLimitMax))
    

    如果您想删除绘图之间的三行,只需将其写入plot2

    limits = c(0, 1.03 * max(print(plot1)$data[[1]]$ymax))
    

    【讨论】:

      【解决方案4】:

      我可能错过了你真正想要的东西,但不使用 geom_text hack 你仍然可以设置限制

      ggplot(mtcars, aes(x = as.factor(carb))) + 
          geom_bar() + 
          scale_y_continuous(expand = c(0, 0), limits = c(0, 10.3)) 
      
      # marginally cleaner
      

      【讨论】:

      • 是的,正是我想要的。我尝试在scale_y_continuous 之后使用:ylim(c(0,10.3)),但这是不行的。我现在明白了。很简单。谢谢。
      • 我删除了支票并在此时授予了更好的答案。我知道你的回答很有价值,所以没有丢分。谢谢你。在 ggplot2 团队解决之前,您的原始解决方案非常有用。
      【解决方案5】:

      您可以手动扩展限制,例如使用expand_limits(y=10.1),或者使用这个技巧添加一个带有放大数据的不可见层,

      ggplot(mtcars, aes(x=as.factor(carb))) + 
          geom_bar() + 
          scale_y_continuous(expand = c(0,0)) +
          geom_blank(aes(y=1.1*..count..), stat="bin")
      

      【讨论】:

      • 啊哈,那些..变量...+1!
      • 有没有办法在没有硬编码(1.1)的情况下做到这一点?
      • 我的意思是在这种情况下乘以 1.1 是有效的,但是如果您动态更改 y 轴并且您事先不知道比例。在这种情况下,您必须以某种方式使用参数而不是硬编码这个乘法因子。如果 ggplot 可以根据数据(y 轴刻度)自动执行此操作,那就太好了。
      • 我还是不明白 - ..count.. 变量负责 y 轴的这种自动调整,但在某些时候,用户可以定义应该在上面添加什么边距条形图(这里是整个数据范围的 10%),这就是乘法因子的作用。这与 base R 和 ggplot2 中的默认轴相同。
      【解决方案6】:

      因为您似乎对一些硬编码感到满意...

      ggplot(mtcars, aes(x = as.factor(carb))) + 
        geom_bar() +
        coord_cartesian(ylim = c(0, 10.3))
      

      【讨论】:

      • 我之前没有意识到这个答案有多么强大,并且也可以推广到分类尺度。