54

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?

Community
  • 1
  • 1
David Robinson
  • 77,383
  • 16
  • 167
  • 187
  • 2
    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 Apr 01 '15 at 19:06

1 Answers1

58

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

David Robinson
  • 77,383
  • 16
  • 167
  • 187
  • 11
    OT comment. (I did upvote.) One of the things that the ggplot2 package is deficient in is an adequate help page for `?layer`. It is particularly annoying that so many links in other help pages point to that page. You obviously understand the ggplot2 layer paradigm. Now that you have dazzled and amused us, may I request that your next expenditure of wasted time be a submission of an expanded layer page? – IRTFM Apr 01 '15 at 18:38
  • Don't forget to use `set.seed` to make the shapes of your freehand circles *irreproducible*: `set.seed(sample(0:.Machine$integer.max, size=1))`. (Make sure you have enough memory, or else use this low-memory alternative: `set.seed(as.integer(runif(1, 0, .Machine$integer.max)))`.) – Ryan C. Thompson Apr 01 '15 at 19:35
  • @RyanThompson but that won't work! If the user sets the seed before, that `sample` operation becomes deterministic and it is still reproducible! (Instead, you could set it to the current time!) – David Robinson Apr 01 '15 at 21:38
  • 10
    Yep, you're absolutely right. I tried to squeeze as many mistakes and abuses as I could into that comment for April Fools Day. For instance, the first seed method will create an enormous integer vector containing all the positive integers just to sample a single number from it, and the floating point solution won't necessarily guarantee a uniform sampling. If there's any part of that comment that isn't a mistake, that's a mistake. – Ryan C. Thompson Apr 02 '15 at 01:06
  • @BondedDust I [dusted off](https://github.com/hadley/ggplot2/pull/1082) an attempt of mine along those lines. I'm not terribly optimistic, though. – joran Apr 02 '15 at 19:28
  • @joran Well; here's a belated recognition that someone at some point did improve that help page significantly. Perhaps it was you, and I thank you for whatever efforts were made in that effort. – IRTFM Mar 07 '21 at 17:54
  • Is there a way to get back the coordinates of a free hand drawing on a ggplot. – Hirak Sarkar Jul 28 '21 at 16:17