I am trying to generate a (grouped) density plot labelled with sample sizes.
Sample data:
set.seed(100)
df <- data.frame(ab.class = c(rep("A", 200), rep("B", 200)),
val = c(rnorm(200, 0, 1), rnorm(200, 1, 1)))
The unlabelled density plot is generated and looks as follows:
ggplot(df, aes(x = val, group = ab.class)) +
geom_density(aes(fill = ab.class), alpha = 0.4)
What I want to do is add text labels somewhere near the peak of each density, showing the number of samples in each group. However, I cannot find the right combination of options to summarise the data in this way.
I tried to adapt the code suggested in this answer to a similar question on boxplots: https://stackoverflow.com/a/15720769/1836013
n_fun <- function(x){
return(data.frame(y = max(x), label = paste0("n = ",length(x))))
}
ggplot(df, aes(x = val, group = ab.class)) +
geom_density(aes(fill = ab.class), alpha = 0.4) +
stat_summary(geom = "text", fun.data = n_fun)
However, this fails with Error: stat_summary requires the following missing aesthetics: y
.
I also tried adding y = ..density..
within aes()
for each of the geom_density()
and stat_summary()
layers, and in the ggplot()
object itself... none of which solved the problem.
I know this could be achieved by manually adding labels for each group, but I was hoping for a solution that generalises, and e.g. allows the label colour to be set via aes()
to match the densities.
Where am I going wrong?
The
y
in the return offun.data
is not the aes.stat_summary
complains that he cannot findy
, which should be specificed in global settings atggplot(df, aes(x = val, group = ab.class, y =
orstat_summary(aes(y =
if global setting ofy
is not available. Thefun.data
compute where to display point/text/... at eachx
based ony
given in the data throughaes
. (I am not sure whether I have made this clear. Not a native English speaker).Even if you have specified
y
throughaes
, you won't get desired results becausestat_summary
compute ay
at eachx
.However, you can add text to desired positions by
geom_text
orannotate
: