某所で「ggplot2で文字をど真ん中に入れるようなgeomを作るべし」とのミッションを受けたので、試行錯誤してなんとか走るものができたのでメモ。
なおこれは個人的な勉強とメモのためのもので、実用性は低いです。以下の資料を参考にしました:
ggprotoオブジェクト作成ようするに、以下のような計算をしてくれるようなものがあればいい:
StatLabelCenter <- ggproto("StatLabelCenter", Stat,
compute_group = function(data, scales) {
rngx <- range(data$x, na.rm = TRUE)
rngy <- range(data$y, na.rm = TRUE)
grid <- data.frame(x = mean(rngx), y = mean(rngy))
grid
},
required_aes = c("x", "y")
)
参考資料の内容からちょっと編集して作りました。
geom_label_center()の作成ラベルをプロットするのはgeom_label()なので、そのソースコードをベースに作りました:
geom_label_center <- function(mapping = NULL, data = NULL, stat = "identity", position = "identity",
parse = FALSE, ..., nudge_x = 0, nudge_y = 0,
label.padding = unit(0.25, "lines"), label.r = unit(0.15, "lines"),
label.size = 0.25,na.rm = FALSE, show.legend = NA, inherit.aes = TRUE)
{
if (!missing(nudge_x) || !missing(nudge_y)) {
if (!missing(position)) {
stop("Specify either `position` or `nudge_x`/`nudge_y`",
call. = FALSE)
}
position <- position_nudge(nudge_x, nudge_y)
}
layer(data = data, mapping = mapping, stat = StatLabelCenter, geom = GeomLabel,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(parse = parse, label.padding = label.padding,
label.r = label.r, label.size = label.size, na.rm = na.rm,
...))
}
修正箇所は、layer()内の引数で、stat = StatLabelCenterと、先ほど作ったggprotoオブジェクトを指定しています。よって、関数の引数にstat = "identity"とありますが思いっきり無視します。
試してみます:
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
geom_label_center(aes(label="kosaki"))
geom_label()がベースなので、ラベルの書式などはそれと同じように設定できます。
なんとなくggplot2の仕組みに触れられた気がした。でもまだ私には難しすぎる…。あとコードが雑過ぎる。任せたよ未来の自分。
Enjoy!