我認爲,實現這一目標的最簡單的方法是你創建的情節之前準備數據。我定義一個函數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