2

My question is an exact duplicate of this one [1], but the provided answer isn't working on my system.

Question: How can I add geom_segment() layers within a for loop? If I use aes, as the OP of the referenced question does, I also get only the last layer. If, as the answerer suggests, I don't use aes, I don't get any segments at all.

Here is a minimal example:

  ga <- 2.39996322972865332
  p <- ggplot()
  p <- p + scale_y_continuous(limits = c(-1, 1))
  p <- p + scale_x_continuous(limits = c(-1, 1))
  for (i in 0:2) {
    #     p <- p + geom_segment(x = -cos(i*ga), y = -sin(i*ga), xend = cos(i*ga), yend = sin(i*ga)) # No segments
    p <- p + geom_segment(aes(x = -cos(i*ga), y = -sin(i*ga), xend = cos(i*ga), yend = sin(i*ga))) # Only last segment
  }
  p

I'm using R version 3.1.2 and (apparently) ggplot2 version 1.0.0 on Ubuntu.

(Note: I get the same result if I use repeat or while.)

[1] Enriching a ggplot2 plot with multiple geom_segment in a loop?

3 Answers 3

4

Skip the loop. Pass a vector to the i variable:

 p <- p + geom_segment(
                aes(x = -cos((0:2)*ga), y = -sin((0:2)*ga),
                    xend = cos((0:2)*ga), yend = sin((0:2)*ga))
                       )

Just a check to see that you can use a variable as well as a numeric constant:

 i <- 0:2
 p <- p + geom_segment(aes(x = -cos(i*ga), y = -sin(i*ga), 
                           xend = cos(i*ga), yend = sin(i*ga)) )

enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

Ahhh brilliant! I need to start vectorizing things in my head by default. Thanks so much!
This the cleanest and useful solution. I found so many melting and data.frame "casting" and they were always suboptimal and often broken (e.g. if you use a different data for the main plotting).
1

I had a very similar problem, but could not avoid using a for loop. I solved it by

adding inherit.aes = TRUE

after the aes() statement within the geom_segment() statement.

Comments

-1

I just wanted to add one point to @BondedDust's answer.

If you try to put this into a function, something like this...

  draw.golden.angle <- function(n) {

  ga <- 2.39996322972865332
  p <- ggplot()
  p <- p + scale_y_continuous(limits = c(-1, 1))
  p <- p + scale_x_continuous(limits = c(-1, 1))
  i <- 0:n
  p <- p + geom_segment(aes(x = -cos(i*ga), y = -sin(i*ga), xend = cos(i*ga), yend = sin(i*ga))) # Only last segment
  p

  }

  draw.golden.angle(7)

...you will get an error saying that the variable i isn't recognized. You can fix this by assigning i to a global variable as follows:

i <<- 0:n

6 Comments

Assigning to a global variable is a very dangerous way to go about this.
Thanks for the warning, @Gregor--I will read up on global variables. Is there another way you can think to do this? If you'd like I can make it a separate question.
I can't think of a really easy way. The robust solution would be to add new data columns for each value of i, melt, and use geom_segment with a grouping variable, aes(group = i). It's quite a bit more work, but that's the price we pay to have stable and reliable functions.
Also, fortunes::fortune(236)
And Circle 6 of The R Inferno is about global assignment (and why you should never do it).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.