54
votes

Last year I posted an analysis of user activity to Meta Stack Overflow, including a series of ggplot2 graphs. However, Wooble greatly shamed me by pointing out a fatal flaw with my plots:

enter image description here

Freehand red circles are of course necessary in any plot on Meta Stack Overflow, but to my dismay I could not find a way to add them to a ggplot2 graph. I know how to add a circle, but such an artificial construct has no personality and would never pass muster on Meta.

As a reproducible example, consider this plot of my own answering activity over time, created using the stackr package:

# devtools::install_github("dgrtwo/stackr")
library(ggplot2)
library(dplyr)
library(lubridate)
library(stackr)

answers <- stack_users(712603, "answers", num_pages = 10, pagesize = 100)
answers_per_month <- answers %>%
    mutate(month = round_date(creation_date, "month")) %>%
    count(month)

ggplot(answers_per_month, aes(month, n)) + geom_line()

without freehand

This plot is informative enough, but it has no soul. How can I add freehand red circles to it?

1
I'd upvote the question as well, but it seems a bit unfair to the rating system to give points twice for the same topic :-)Carl Witthoft

1 Answers

58
votes

You can use my ggfreehand package, which provides the geom_freehand layer that was so carelessly omitted from ggplot2.

For example, if you wanted to circle the top two most active months in the plot above, you could follow the code with:

top_2_months <- answers_per_month %>% top_n(2)

library(ggfreehand)
ggplot(answers_per_month, aes(month, n)) + geom_line() +
    geom_freehand(data = top_2_months)

with freehand

And just like that, the plot is now worthy of being posted on Meta Stack Overflow.

The geom_freehand layer takes additional options to customize the circle, including radius and noisiness. You could also make the circle not red, as though that were something you would ever want to do.

p <- ggplot(answers_per_month, aes(month, n)) + geom_line()

p + geom_freehand(data = top_2, radius = .5)
p + geom_freehand(data = top_2, noisiness = 10)
p + geom_freehand(data = top_2, noisiness = 1)
p + geom_freehand(data = top_2, color = "blue")

enter image description here