【问题标题】:positioning labels on geom_bar在 geom_bar 上定位标签
【发布时间】:2015-01-07 08:30:30
【问题描述】:

我正在尝试使用 ggplot 创建一个带有类别标签的水平条形图。

我已经能够毫不费力地创建情节,并且可以贴上标签,但是我遇到了格式问题。最终,如果合适,我希望将我的标签放在条内,否则就在条外而不截断标签。

以下是我目前尝试过的。

数据

dt1 <- data.table(x=c("a","b","c","d","e"), y=c(43,52,296,102,157), y2=c(50,10,100,45,80))

图表 1

ggplot() + geom_bar(data=dt1, aes(x=x, y=y), stat="identity",fill="red") + coord_flip() +
  geom_text(data=dt1, aes(x=x, y=y, label=paste0("$",y," from ",y2," records")),hjust=0)

正如您在下面看到的,标签被截断了。

图表 2

然后我遇到了这个question,它很有帮助,让我意识到我正在根据我的 y 变量设置标签位置,所以我现在已经硬编码它并使用 hjust 从轴上填充它。

ggplot() + geom_bar(data=dt1, aes(x=x, y=y), stat="identity",fill="red") + coord_flip() +
  geom_text(data=dt1, aes(x=x, y=0, label=paste0("$",y," from ",y2," records")),hjust=-0.1)

但是您可以在下面看到只有 2 个标签适合条形图,所以我希望其他标签放在最后,在条形图的外侧,如图 1 所示。

有没有一种编程方式可以让我从图表 1 和图表 2 中获得两全其美?

【问题讨论】:

    标签: r ggplot2 geom-bar geom-text


    【解决方案1】:

    我会把程序化误读为“实用主义”。添加“+ scale_y_continuous(limits=c(0,max(dt1$y)+100))”为标签创造了足够的空间。我缺乏上传情节的声誉。

    ggplot() + geom_bar(data=dt1, aes(x=x, y=y), stat="identity",fill="red") + coord_flip() + geom_text(data=dt1, aes(x=x, y=y, label=paste0("$",y," from ",y2," records")),hjust=0) + scale_y_continuous(limits=c(0,max(dt1$y)+100))
    

    编辑 2;我更改了代码以检索最大值并将其添加 100。它仍然不适合专门包含文本的情节,但它可以使用固定标签。

    【讨论】:

    • 它有帮助,但它并没有解决与两全其美有关的主要问题。我也追求一种编程方式来做事,因为我并不总是知道 y 的最大值是多少,我不希望硬编码限制
    【解决方案2】:

    这是一种方法。这是一个有点冗长的方法,但您可以将数据子集化为geom_text。这样,您可以手动为每个条分配您想要的位置。

    ggplot() + 
    geom_bar(data = dt1, aes(x=x, y=y), stat="identity",fill="red") +
    coord_flip() +
    geom_text(data = filter(dt1, x == "e" | x == "c"),
         aes(x=x, y=0, label=paste0("$",y," from ",y2," records")),hjust = -0.1) +
    geom_text(data = filter(dt1, x == "d"),
         aes(x=x, y=0, label=paste0("$",y," from ",y2," records")),hjust = - 1.1) +
    geom_text(data = filter(dt1, x == "b"),
         aes(x=x, y=0, label=paste0("$",y," from ",y2," records")),hjust = - 0.6) +
    geom_text(data = filter(dt1, x == "a"),
         aes(x=x, y=0, label=paste0("$",y," from ",y2," records")),hjust = - 0.5) 
    

    【讨论】:

    • 手动调整很麻烦,标签的相对位置以显示为准。
    • @KFB 是的,我知道你的意思。如果图形是这样的,我不介意做手工。但是,如果一个人有很多组,他/她就必须考虑其他事情。
    • 我认为这可能有点困难。到目前为止,我认为我的问题中的图表 2 将是避免手动干预绘图的最佳方法。
    • @Dan 我认为选择是使标签位置与更少的行一致或随着更多的行而变化。我喜欢你的图表 2。如果我是你,我会坚持下去。
    【解决方案3】:

    hjust 移动到aes 中,这样我们就可以改变值,然后如果条形图超过最大值,则移动它。它仍然有点老套,因为它对缩放做了假设,但看起来相当不错。除数可能需要调整:

    library(tidyverse)
    
    dt1 <- data.frame(x=c("a","b","c","d","e"), y=c(43,52,296,102,157), y2=c(50,10,100,45,80))
    
    ggplot() +
      geom_bar(data=dt1, aes(x=x, y=y), stat="identity",fill="red") +
      coord_flip() +
      geom_text(
        data=dt1,
        aes(
          x=x, y=y,
          label=paste0("$",y," from ",y2," records"),
          hjust=ifelse(y < max(dt1$y) / 1.5, -0.1, 1.1), # <- Here lies the magic
        ),
      )
    

    此图中的结果:

    【讨论】:

    • 这是迄今为止我遇到的最好的方法。完全调整除数,但这是整个图表中的一个数字。
    猜你喜欢
    • 2014-12-19
    • 2017-04-24
    • 2021-07-24
    • 2022-11-23
    • 2018-01-05
    • 2011-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多