我认为,实现这一目标的最简单的方法是你创建的情节之前准备数据。我定义一个函数abi()
即计算从stuff.dat
给予大陆苹果香蕉指数:
abi <- function(cont) {
with(stuff.dat,
num[continent == cont & stuff == "apples"]/num[continent == cont & stuff == "bananas"]
)
}
然后,我创建了所有必要的数据的数据帧:
conts <- levels(stuff.dat$continent)
abi_df <- data.frame(continent = conts,
yf = aggregate(num ~ continent, sum, data = stuff.dat)$num + 5,
abi = round(sapply(conts, abi), 1))
现在,我可以这些信息添加到情节:
library(ggplot2)
ggplot(stuff.dat, aes(x = continent, y = num, fill = stuff)) +
geom_col() +
geom_text(position = position_stack(vjust = 0.5), aes(label = num)) +
geom_text(data = abi_df, aes(y = yf, label = paste0("f = ", abi), fill = NA))
将fill = NA
添加到geom_text()
是有点破解并导致警告。但是,如果未设置fill
,则绘图将失败,并显示消息stuff
未找到。我也尝试将fill = stuff
从ggplot()
移动到geom_col()
,但是这打破了条内文本标签的y坐标。可能有更清晰的解决方案,但我还没有找到它。
不幸的是,添加额外的图例并不简单,因为不能轻易地在绘图区域之外添加文本。这实际上需要两个步骤:第一个使用annotation_custom()
添加文本。然后,您需要关闭裁剪以使文字可见(请参阅,例如,here)。这是一个可能的解决方案:
p <- ggplot(stuff.dat, aes(x = continent, y = num, fill = stuff)) +
geom_col() +
geom_text(position = position_stack(vjust = 0.5), aes(label = num)) +
geom_text(data = abi_df, aes(y = yf, label = paste0("f = ", abi), fill = NA)) +
guides(size = guide_legend(title = "f: ABI", override.aes = list(fill = 1))) +
annotation_custom(grob = textGrob("f: ABI\n(Apple-\nBanana-\nIndex",
gp = gpar(cex = .8), just = "left"),
xmin = 3.8, xmax = 3.8, ymin = 17, ymax = 17)
# turn off clipping
library(grid)
gt <- ggplot_gtable(ggplot_build(p))
gt$layout$clip[gt$layout$name == "panel"] <- "off"
grid.draw(gt)
你知道正常的柱状图中不需要的文本?这个数字太难以掌握,现在你需要这些附加信息 – PoGibas