1

I am trying to add horizontal lines to a ggplot, based on intercepts given in a vector. Since the length of this vector will vary, and this vector will not necessarily follow any sequence, I am putting this inside a for loop, but I can only see that last line added. When I add without the for loop (which will imply a fixed vector size), I get the plot that I want.

library(ggplot2)
library(viridis)
dat = data.frame(x=runif(10), y=runif(10))
lines = c(0.1,0.2,0.3)
nlines = length(lines)
vpal = viridis(nlines,end=0.9)

## I only see the last line added:
p <- ggplot(dat,aes(x,y)) + geom_point()
for(i in 1:nlines){
    p <- p + geom_hline(aes(yintercept=lines[i]), colour=vpal[i], linetype="dashed")
}

## I see all lines:
p <- ggplot(dat,aes(x,y)) + geom_point()
p <- p + geom_hline(aes(yintercept=lines[1]), colour=vpal[1], linetype="dashed")
p <- p + geom_hline(aes(yintercept=lines[2]), colour=vpal[2], linetype="dashed")   
p <- p + geom_hline(aes(yintercept=lines[3]), colour=vpal[3], linetype="dashed")

Maybe I am missing something obvious, but how can I add a variable number of lines to a ggplot? Thanks!

csolle
  • 11
  • 2
  • Another "right" way to do this: use `p + geom_hline(aes(yintercept=y), data=data.frame(y=lines))` (no `for` loop at all) ... you don't have to deal with the indirection of the `for` loop lazy evaluation, `geom_hline` is called exactly once (efficiency of code), and it is more declarative in what you intend to do. – r2evans Mar 12 '18 at 21:03
  • Another way to avoid the loop: `+ geom_hline(yintercept=lines, colour=vpal, linetype="dashed")` – eipi10 Mar 12 '18 at 21:05
  • Thank you @eipi10 for pointing at the other question! I had not seen it, but it does not help me because I am not taking subsets of my data in the for loop. I am simply looping over an outside vector, unrelated to my data. Am I understanding this correctly in that I would need to somehow include this vector in my data frame to make the for loop work? – csolle Mar 12 '18 at 21:07
  • Thanks for the comments! I had not seen them when I wrote my previous comment! I will try these! – csolle Mar 12 '18 at 21:08
  • My previous comments shows how to add the lines without a loop or a data frame. You can do it with a data frame frame as well, as shown by @r2evans. The key point is that is can be a *different* data frame than the main data you're plotting. You just have to specify the different data frame within `geom_hline`. Also, to get colors, you could do: `+ geom_hline(data=data.frame(y=lines), aes(yintercept=y, colour=factor(y)), linetype="dashed") + scale_colour_manual(values=vpal)`. – eipi10 Mar 12 '18 at 21:39
  • (continued) But in this case it's just easier to directly specify the `yintercept` and `colour` without and `aes` mpaaing a data frame. – eipi10 Mar 12 '18 at 21:41
  • Thank you! Your first comment worked fine. It took me a while to add the colors to @r2evans suggestion, but it also works fine. Thanks! – csolle Mar 12 '18 at 22:49
  • csolle, "adding colors" should be as simple as assigning another column in the second data.frame, and using that within the hline aes. – r2evans Mar 12 '18 at 22:59

0 Answers0