【问题标题】:Labeling individual bars in stacked ggplot bar graph在堆叠的 ggplot 条形图中标记单个条形图
【发布时间】:2013-03-03 09:32:24
【问题描述】:

有没有一种简单的方法可以在“堆叠”条形图中标记单个“块”,如下所示。我希望将标签放置在每个块的顶部附近,但我最新的方法导致以某种方式将文本交换为美国和墨西哥,如下所示。

四处寻找解决方案,我只找到了必须在外部预先计算文本的 y 值的方法,除了额外的逻辑之外,这带来了控制顺序的问题积木堆积...
我还发现了这个stackoverflow question,在那里我想到了在stat_bin 中使用geom="text"(见下面的代码)
这是一个精简的代码 sn-p 用于说明我当前的方法。 我不一定要修复这个 sn-p,任何标记堆栈条形图区域的通用习语都可以!
编辑:(鉴于这个问题到目前为止得到的两个答案)
我想强调的是,我更喜欢不暗示预先计算文本的 y 位置的解决方案。

# sample data source
df.StackData <- data.frame(
    QType = c("A4-1", "A4-1", "A4-1",  "B3", "B3", "B3"),
    Country = c("Canada", "USA", "Mexico", "Canada", "USA", "Mexico"),
    NbOfCases = c(1000, 1320, 380, 400, 1000, 812),
    AvgRate = c(17.2, 11.4, 44.21, 17.3, 15.3, 39.7),
    Comment = c("Can", "US", "Mex", "Can", "US", "Mex")
)

和 ggplot 调用。 它产生了上面显示的图表,带有奇怪的标签交换(还有一个额外的图例,'虽然这个图例问题很容易处理;我只是在准备这个问题时注意到它)。

ggplot(data=df.StackData,
       aes(x=QType, y=NbOfCases, fill=Country))+
  geom_bar(stat="identity", width=1) +
  stat_bin(geom="text", aes(label=paste("R coef =",
                                        formatC(AvgRate, format="f", digits=3),
                                        "(", Comment, ")" ),
                            vjust=1.5, size=3 
                        )
  )

我最初的尝试如下添加了一个 geom_text() 到图表中,但是 y 值当然是错误的(将文本相对于图表的最底部而不是单个块的底部)...

  ... +
  geom_text(mapping=aes(x=QType, y=NbOfCases, 
                        label=paste("R coef =",
                                    formatC(AvgRate, format="f", digits=3),
                                    "(", Comment, ")" ),
                         vjust=1.5),
            size=3)

【问题讨论】:

    标签: r ggplot2 label stacked-area-chart


    【解决方案1】:

    这里有一个解决方案。这里有两件事。首先,你应该reorderdata.frame 的级别与你在数据df.StackData 中的顺序相同。其次,创建另一个data.frame,通过计算数据的累积和来计算y-position

    # reorder levels of factor to the same order as found in data
    df.StackData$Country <- factor(df.StackData$Country, 
              levels=c("Canada", "USA", "Mexico"), ordered=TRUE)
    p <- ggplot(data=df.StackData, aes(x=QType, fill=Country))
    p <- p + geom_bar(aes(weights=NbOfCases))
    
    # compute corresponding y-axis positions by cumulative sum
    require(plyr)
    df <- ddply(df.StackData, .(QType), function(x) {
        x$NbOfCases <- cumsum(x$NbOfCases)
        x
    })
    
    # then use geom_text with data = df (the newly created data)
    p + geom_text(data = df,  aes(x=QType, y=NbOfCases, 
            label=paste("R coef =", 
            formatC(AvgRate, format="f", digits=3), 
            "(", Comment, ")" ), vjust=1.5), size=3)
    

    编辑:如果您不想自己计算 y-pos,则必须使用 stat_bin。只需重新排列Country 列的级别即可:

    # data
    df.StackData <- data.frame(
        QType = c("A4-1", "A4-1", "A4-1",  "B3", "B3", "B3"),
        Country = c("Canada", "USA", "Mexico", "Canada", "USA", "Mexico"),
        NbOfCases = c(1000, 1320, 380, 400, 1000, 812),
        AvgRate = c(17.2, 11.4, 44.21, 17.3, 15.3, 39.7),
        Comment = c("Can", "US", "Mex", "Can", "US", "Mex")
    )
    
    # just add this: reorder the level 
    df.StackData$Country <- factor(df.StackData$Country, 
              levels=c("Canada", "USA", "Mexico"), ordered=TRUE)
    
    # your code again using stat_bin (just changed the width to 0.75)
    ggplot(data=df.StackData,
           aes(x=QType, y=NbOfCases, fill=Country))+
      geom_bar(stat="identity", width=.75) +
      stat_bin(geom="text", size=4, aes(label=paste("R coef =",
                                            formatC(AvgRate, format="f", digits=3),
                                            "(", Comment, ")" ),
                                vjust=1.5))
    

    【讨论】:

    • 谢谢你,Arun,我试图远离所有暗示预先计算 y 位置并将其提供给 geom_text 的解决方案,但似乎不可能......你知道其他不需要预计算的习语吗?
    • 在执行此操作后尝试您的第一个解决方案:df.StackData$Country &lt;- factor(df.StackData$Country, levels=c("Canada", "USA", "Mexico"), ordered=TRUE)
    • 宾果游戏做到了。我只剩下删除不受欢迎的 Legend 了,但这应该很容易。谢谢!
    • 当然,如果我设法找到删除图例,我会进行编辑。
    • 你很善良。我不能在这台 ATM 上工作,但这通常发生在 ggplot 认为它具有额外/不同的美学时。我会等待几个小时,以防其他 R 向导来教我们一个漂亮的技巧,但否则我一定会接受你的回答。这很有帮助。
    【解决方案2】:

    这里有一个解决方案

    df2 = ddply(df.StackData, .(QType), transform, 
     pos = cumsum(NbOfCases) - 0.5 * NbOfCases)
    
    ggplot(data = df2, aes(x = QType, y = NbOfCases, fill = Country)) +
      geom_bar(stat = "identity") +
      geom_text(aes(y = pos, label = paste("R coef =", 
       formatC(AvgRate, format="f", digits=3), "(", Comment, ")" ))
      )
    

    【讨论】:

    • 谢谢你,Ramnath,我试图远离所有暗示预先计算 y 位置并将其提供给 geom_text 的解决方案,但似乎这可能是不可能的。 ..你知道其他不需要预计算的习语吗?
    【解决方案3】:

    这是另一种选择 - 因为默认情况下您的因子将按字母顺序排序,所以我建议重新排序您的数据框以匹配此,而不是重新排序因子以匹配数据框的顺序。在我看来,这将允许一个更通用的解决方案。你得到一个你不想要的图例的唯一原因是你在 aes 里面有大小 - 我已经在下面修复了。

    使用您的数据:

    df.StackData <- with(df.StackData, df.StackData[order(Country),])
    

    然后您可以将原始解决方案与stat_bin 一起使用。我用一些更复杂的数据集对其进行了测试,只是为了检查它是否有效:

    df.StackData <- data.frame(
      QType = rep(c("A4-1","B3"), each = 6),
      Country = rep(c("Canada", "USA", "Mexico", "UK", "Sweden", "Australia"), times = 2),
      NbOfCases = c(1000, 1320, 380, 400, 1000, 812, 542, 531, 674, 328, 795, 721),
      AvgRate = c(17.2, 11.4, 44.21, 17.3, 15.3, 39.7, 21.1, 25.3, 24.1, 31.3, 38.4, 36.1),
      Comment = rep(c("Can", "US", "Mex", "UK", "Aus", "Swe"), times = 2)
    )
    

    没有排序:

    ggplot(data=df.StackData,
           aes(x=QType, y=NbOfCases, fill=Country))+
      geom_bar(stat="identity", width=1) +
      stat_bin(geom="text", aes(label=paste("R coef =", formatC(AvgRate, format="f", digits=3),
    "(", Comment, ")" ),  vjust = 1),size=3)
    geom_text(aes(label = Comment), stat="identity")
    

    排序后:

    df.StackData

    【讨论】:

    • 谢谢 Alex,这也是一个好方法。是的,关于在美学对象内部和外部放置各种格式属性......这当然是 - 从 ggplot 的角度来看 - 引入更多图例的原因。
    【解决方案4】:

    要删除多余的图例,您可以使用show_guide=FALSE。在您的示例中:

    ggplot(data=df.StackData,
           aes(x=QType, y=NbOfCases, fill=Country))+
      geom_bar(stat="identity", width=.75) +
      stat_bin(geom="text", size=4, aes(label=paste("R coef =",
                                            formatC(AvgRate, format="f", digits=3),
                                            "(", Comment, ")" ),
                                vjust=1.5), show_guide=FALSE)
    

    【讨论】:

      猜你喜欢
      • 2018-04-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-06
      • 2023-01-21
      • 1970-01-01
      • 1970-01-01
      • 2022-11-23
      • 1970-01-01
      相关资源
      最近更新 更多