Добавить текст в ggplot с гранеными плотностями

Я столкнулся с проблемой при попытке построить график плотности с помощью ggplot. Данные выглядят немного как в примере здесь.

require(ggplot2)
require(plyr)
mms <- data.frame(deliciousness = rnorm(100),
                  type=sample(as.factor(c("peanut", "regular")), 100, replace=TRUE),
                  color=sample(as.factor(c("red", "green", "yellow", "brown")), 100, replace=TRUE))


mms.cor <- ddply(.data=mms, .(type, color), summarize, n=paste("n =", length(deliciousness)))

plot <- ggplot(data=mms, aes(x=deliciousness)) + geom_density() + facet_grid(type ~ color) + geom_text(data=mms.cor, aes(x=1.8, y=5, label=n), colour="black", inherit.aes=FALSE, parse=FALSE)

Маркировка каждого аспекта с помощью ярлыков работает достаточно хорошо, если только масштаб для каждого аспекта не меняется. У кого-нибудь есть идея, как мне добиться размещения меток в одном и том же месте, когда шкалы для одного фасета отличаются?

Бест, Даниэль

1 ответ

Решение

Что-то вроде этого?

plot <- ggplot(data=mms, aes(x=deliciousness)) +
  geom_density(aes(y=..scaled..)) + facet_grid(type ~ color) +
  geom_text(data=mms.cor, aes(x=1.2, y=1.2, label=n), colour="black")
plot

Есть способ получить внутренние ограничения с помощью ggplot с помощью scales="free", но это включает в себя взлом grob (графический объект). Поскольку вы, кажется, хотите, чтобы графики плотности имели одинаковую высоту (???), вы можете сделать это с aes(y=..scaled...), Тогда установить местоположение для ярлыков просто.

РЕДАКТИРОВАТЬ (ответ на комментарий ОП)

Это то, что я имел в виду, взломав grob, Обратите внимание, что это использует преимущества внутренней структуры, используемой gglpot, Проблема состоит в том, что это может измениться в любое время с новой версией (и фактически это уже отличается от более старых версий). Таким образом, нет никаких гарантий, что этот код будет работать в будущем.

plot <- ggplot(data=mms, aes(x=deliciousness)) +
  geom_density() + 
  facet_grid(type ~ color, scales="free")
panels <- ggplot_build(plot)[["panel"]]
limits <- do.call(rbind,lapply(panels$ranges,
                               function(range)c(range$x.range,range$y.range)))
colnames(limits) <- c("x.lo","x.hi","y.lo","y.hi")
mms.cor <- cbind(mms.cor,limits)
plot + 
  geom_text(data=mms.cor, aes(x=x.hi, y=y.hi, label=n), hjust=1,colour="black")

Основная идея заключается в создании plot без текста, а затем построить графический объект с помощью ggplot_build(plot), Из этого мы можем извлечь x- и y-ограничения и связать их с метками в вашем mms.cor фрейм данных. Теперь визуализируйте сюжет с текстом, используя эти ограничения.

Обратите внимание, что графики отличаются от моего предыдущего ответа, потому что вы не использовали set.seed(...) в вашем коде для создания набора данных (и я забыл добавить его...).

Другие вопросы по тегам