在ggplot2中显示频率和条形图

22

我想在条形图中显示频率...嗯,我希望它们出现在图表的某个地方:在条形下方、在条形内部、在条形上方或者在图例区域。我记得(也许我错了)可以用ggplot2来实现这一点。这可能是一个简单的问题...至少看起来很容易解决。以下是代码:

p <- ggplot(mtcars)
p + aes(factor(cyl)) + geom_bar()

我能否在图表中获取频率信息?

5个回答

27

geom_text 是基础图形的 text 的类比:

p + geom_bar() + stat_bin(aes(label=..count..), vjust=0, 
                          geom="text", position="identity")
如果您想调整标签的y轴位置,可以在stat_bin内使用y=美学:例如,y=..count..+1将标签放置在条形图上方一单位处。如果在内部使用geom_textstat="bin"也同样适用。

标签前后为什么有“..”?这是为了计数。 - Ankit Dhingra
2
“..count..” 是变量的名称,其中包含 stat_bin 自动创建的箱子频率。因此,在它前后的两个句点是变量名的一部分。 - Aniko
2
这个答案对我来说出现了错误 Error: stat_count requires the following missing aesthetics: x。然而,加入 aes(factor(cyl)) 并将 stat_bin 更改为 stat_count,就像在 p + aes(factor(cyl)) + geom_bar() + stat_count(aes(label=..count..), vjust=0, geom="text", position="identity") 中一样,确实可以工作。 - steveb
对我来说,+ geom_text(aes(label=..count..), stat="count") 起作用了(而不是 stat="bin")。 - Octopus

4
一种较为困难的方法。我相信有更好的解决方案。
ggplot(mtcars,aes(factor(cyl))) + 
geom_bar() + 
geom_text(aes(y=sapply(cyl,function(x) 1+table(cyl)[names(table(cyl))==x]),
label=sapply(cyl,function(x) table(cyl)[names(table(cyl))==x])))

12
通常最好的做法是在绘图代码之外创建数据。而将数据强行塞入美学映射中从来都不是一个好主意。 - hadley

1

当想要添加不同的信息时,可以使用以下方法:

ggplot(mydata, aes(x=clusterSize, y=occurence)) +
geom_bar() + geom_text(aes(x=clusterSize, y=occurence, label = mydata$otherinfo))

请问您能否提供一个示例来复制这个答案,该示例涉及到datasets包中可用的数据(或其他在CRAN存储库中可用的包)?我怀疑使用指定“原样”的y变量无法绘制条形图... - aL3xa

1

另外,我发现使用一些可用的注释函数非常有用:ggplot2::annotateggplot2::annotation_customcowplot::draw_label(这是annotation_custom的包装器)。

ggplot2::annotate只是回收了geom文本选项。更有优势的是,在画布上任何位置绘制的可能性由ggplot2::annotation_customcowplot::draw_label提供。

使用ggplot2::annotate的示例

library(ggplot2)

p <- ggplot(mtcars) + aes(factor(cyl)) + geom_bar()

# Get data from the graph
p_dt <- layer_data(p) # or ggplot_build(p)$data

p + annotate(geom = "text", label = p_dt$count, x = p_dt$x, y = 15)

或者允许y变化:

p + annotate(geom = "text", label = p_dt$count, x = p_dt$x, y = p_dt$y + 1)

使用ggplot2::annotation_custom的示例

ggplot2::annotate在尝试在更“非传统”位置绘图时存在限制,正如最初要求的那样(在图形的某个地方)。然而,ggplot2::annotation_custom设置裁剪关闭相结合,允许在画布/工作表的任何位置进行注释,如下面的示例所示:

p2 <- p + coord_cartesian(clip = "off")
for (i in 1:nrow(p_dt)){
  p2 <- p2 + annotation_custom(grid::textGrob(p_dt$count[i]), 
                               xmin = p_dt$x[i], xmax = p_dt$x[i], ymin = -1, ymax = -1)
}
p2

使用cowplot::draw_label的示例

cowplot::draw_labelggplot2::annotation_custom的一个包装器,相对来说更加简洁。它还需要进行裁剪才能在画布上任意绘制。

library(cowplot)
#> Warning: package 'cowplot' was built under R version 3.5.2
#> 
#> Attaching package: 'cowplot'
#> The following object is masked from 'package:ggplot2':
#> 
#>     ggsave
# Revert to default theme; see https://dev59.com/DVgR5IYBdhLWcg3woefW#41096936
theme_set(theme_grey())

p3 <- p + coord_cartesian(clip = "off")
for (i in 1:nrow(p_dt)){
  p3 <- p3 + draw_label(label = p_dt$count[i], x = p_dt$x[i], y = -1.8)
}
p3

请注意,draw_label也可以与cowplot::ggdraw结合使用,在相对坐标(从0到1,相对于整个画布,参见help(draw_label)中的示例)下进行切换。在这种情况下,不再需要设置coord_cartesian(clip = "off"),因为ggdraw会处理好一切。

reprex package (v0.2.1)创建于2019-01-16


-1

如果您不受限于ggplot2,您可以使用基本图形中的?text或plotrix包中的?boxed.labels。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接