# Annotating graphs in R

This is more of a "how to use R" question than an actual hardcore statistics question, but I think the concentration of R masters here makes this a good forum for it. I'm refreshing a time series graphing package that currently uses gnuplot. The first step is getting somewhere close to the current graphs, and then I hope to be able to add more statistical analysis from R later.

Currently, the gnuplot-generated graphs look like this:

The corresponding graph from R looks like this:

I'm reasonably happy with this. What's missing is the legend stuff from below the gnuplot graph. I can add a legend saying "In" and "Out", but how to best present the average, maximal and minimal values? I could add horizontal lines to the graph and print the values inside the graph area, but the placement might interfere with the actual graph.

-
So... why don't you write it as in the top graph? –  nico Dec 30 '10 at 15:59
@nico Lack of expertise on how to do it in R, basically. –  Jakob Borg Dec 30 '10 at 17:39
paste is your friend. Just construct a string like legend.string <- paste("In traffic [Max", max(values),"]") and then pass that as the legend parameter of legend –  nico Dec 30 '10 at 17:53

A quick and dirty way to paste some text and numerical results along the labels of your legend is to simply rename the factor levels. For instance,

df <- data.frame(x=rnorm(100), y=rnorm(100), f=gl(2,50))
df$f2 <- df$f
levels(df$f2) <- paste(levels(df$f), tapply(df$y, df$f, mean), sep=": ")
p <- ggplot(data=df) + geom_point(aes(x=x, y=y, color=f2))
p + opts(legend.position = 'bottom', legend.title=NULL)


You can add whatever you want into the new labels, such as mean, min, max, etc. (e.g., create a custom function, inspired from summary() that returns the values you want, and append them to c("In","Out")).

-
Thanks, this will work nicely I think. –  Jakob Borg Dec 30 '10 at 17:38

I'm sure that there's a more elegant way to do this but you can try this :

Data <- data.frame(serie1 = cumsum(rnorm(100)), serie2 = rnorm(100), temps = as.Date(1:100, origin = "2000-01-01"))

label <- c("In traffic [max 2.0G bps] [Avg 1.1G bps] [95% 1.8G bps] [Min 569.4M bps]", "Out traffic [max 2.0G bps] [Avg 672M bps] [95% 2.1G bps] [Min 154.3M bps]")

p <- ggplot(melt(Data, id = "temps"), aes(temps, value, group = variable, colour = variable))
p <- p + geom_line() +xlab("") + opts(legend.position = "bottom", legend.title = NULL)
p <- p + scale_colour_manual(values = c("red", "blue"), breaks = c("serie1", "serie2"), labels = label)

print(p)

-
Thanks, that's also a solution. –  Jakob Borg Dec 30 '10 at 17:39
(+1) Your solution is at least more elegant than mine because you don't duplicate the grouping variable! –  chl Dec 30 '10 at 18:20
Related question here, I am trying to remix this. Beautiful +1! –  hhh Jan 5 '12 at 2:07

Sorry this is an answer -- I guess I haven't earned the "comment" button yet...

All I was going to suggest is that "how to" questions like this one might be a better fit for StackOverflow. There are R pros there who answer these sorts of questions before you can hit 'send'!

I don't know if there's an official FAQ or guidance on SO vs. CV, but since Hadley himself answers a lot of the ggplot2 questions on SO, that's where I go first.

-
Thanks, I'll take that into account for the future. –  Jakob Borg Dec 30 '10 at 17:37