5

Suppose I have the following issue: having a set of data, generate a chart indicating how many datapoints are below any given threshold.

This is fairly easy to achieve

n.data <- 215

set.seed(0)
dt <- rnorm(n.data) ** 2
x <- seq(0, 5, by=.2)
y <- sapply(x, function(i) length(which(dt < i)))

ggplot() +
  geom_point(aes(x=x,y=y)) +
  geom_hline(yintercept = n.data)

Output

The question is, suppose I want to add a label to indicate what the total number of observation was (n.data). How do I do that, while maintaining the other breaks as default?

The outcome I'd like looks something like the image below, generated with the code

ggplot() +
  geom_point(aes(x=x,y=y)) +
  geom_hline(yintercept = n.data) +
  scale_y_continuous(breaks = c(seq(0,200,50),n.data))

However, I'd like this to work even when I change the value of n.data, just by adding it to the default breaks. (bonus points if you also get rid of the grid line between the last default break and the n.data one!)

enter image description here

ltr
  • 332
  • 2
  • 9
  • 1
    Possible duplicate of [ggplot2 - annotate outside of plot](https://stackoverflow.com/questions/12409960/ggplot2-annotate-outside-of-plot) – Henrik Nov 20 '17 at 10:24
  • Did you manage to get this done? (Not a duplicate at all BTW) – Dan Chaltiel Apr 21 '21 at 10:55
  • @DanChaltiel, thanks for reopening this. I've added an answer about how I would approach this today. – ltr Apr 27 '21 at 04:05

2 Answers2

4

Three years and some more knowledge of ggplot later, here's how I would do this today.

ggplot() +
  geom_point(aes(x=x,y=y)) +
  geom_hline(yintercept = n.data) +
  scale_y_continuous(breaks = c(pretty(y), n.data))
ltr
  • 332
  • 2
  • 9
  • Thanks. Based on this I made it work for a more general case, where `n.data` is not necessarily the last value, via `sort(unique(c(my_values, pretty(y))))` – Paul Schmidt Aug 25 '22 at 10:47
  • @PaulSchmidt I don't think you need to do this? Worked fine for me without sorting, but I also didn't have duplicate values. – John-Henry Feb 12 '23 at 23:06
0

Here is how you can get rid of the grid line between the last auto break and the manual one :

theme_update(panel.grid.minor=element_blank())

For the rest, I can't quite understand your question, as when you change n.data, your break is updated.

Boidot
  • 363
  • 1
  • 6
  • 18