I'm trying to annotate a ggplot
that shows multiple results of the same response on different days. When I plot the data, I set col = day
in the aes
command. How do I annotate the ggplot
with mean values of the response on each day using the same colours that ggplot
used to draw the plot and for the legend?
Here's a simple example
library(ggplot2)
# generate some dummy data - col_var in this example takes the place of day in the real example
data <- data.frame ( col_var = rep(c('A', 'B', 'C'), each = 10), x = rep(1:10, 3), y = rep(rnorm(10, 3, 1), each = 3))
# establish means for each response (y)
data_means <- data.frame ( col_var = unique(data$col_var), means = tapply(data$y,list(data$col_var),mean,na.rm=T))
# plot the data
p <- ggplot(data, aes(x = x, y = y, col = col_var)) +
geom_line()+
ylim(0, 10)
Here's where I get stuck. I would like to add the mean values, stacked one on top of each other in the same order as they appear in the legend from data_means
to the plot and colour them the same as the geom_line
for each col_var
p + geom_text(data_means, aes(label = means, col = col_var ), x = 2, y = 5)
p + annotate(data_means, aes(label = means, col = col_var ), x = 2, y = 5)
Update:
libray(dplyr)
library(ggplot2)
data %>%
group_by(col_var) %>%
mutate(means = mean(y)) %>%
ggplot(aes(x = x, y = y, group = means, color = col_var)) +
geom_line() +
ylim(0,10)+
scale_x_discrete(expand=c(0, 1)) +
geom_text(data = data_means, aes(label = paste0("Mean ", col_var[1], " = ", round(means[1],2)), x = 4, y=8.5, color = factor(means)[1]))+
geom_text(data = data_means, aes(label = paste0("Mean ", col_var[2], " = ", round(means[2],2)), x = 4, y=8, color = factor(means)[2]))+
geom_text(data = data_means, aes(label = paste0("Mean ", col_var[3], " = ", round(means[3],2)), x = 4, y=7.5, color = factor(means)[3]))+
scale_color_manual(values = c("red", "green", "blue", "red", "green", "blue"))+
theme(legend.position = "none")
First answer:
Annotating geom_line
is not as trivial as one might think. This is discussed and handled very well here: Plot labels at ends of lines
I think in your case directlabels
package is appropriate:
We first add a column with the means to the data
.
library(ggplot2)
#install.packages("directlabels")
library(directlabels)
library(dplyr)
data %>%
group_by(col_var) %>%
mutate(means = mean(y)) %>%
ggplot(aes(x = x, y = y, group = means , colour = col_var)) +
geom_line() +
ylim(0,10)+
scale_x_discrete(expand=c(0, 1)) +
geom_dl(aes(label = round(means, 3)), method = list(dl.combine("last.points")),
position = position_nudge(y = c(0.2, 0, 0)))