2

I defined a very simple for loop in which I plot a normal distribution with a vertical red line and a smaller vertical black segment. The normal distribution doesn't change, but the position of the vertical line and the vertical segment are supposed to change at each iteration.
If a plot the ggplot() objects on the fly after every iteration, the lines are correctly displayed, but if I store each plot in a list and then I plot the list, the vertical black segment has always the value defined in the last loop. Please check the reprex below:

set.seed(seed = 314159)

library(ggplot2)

plots_list <- list()

for (number in c(1:10)) {

  line <- number
  segment <- number + 1

  p <- ggplot(data = data.frame(x = c(-3, 3)),
              aes(x)) +
    stat_function(fun = dnorm,
                  n = 101,
                  args = list(mean = 0,
                              sd = 1)) +
    geom_vline(xintercept = line,
               colour = "red",
               size = 0.5,
               linetype = "dashed") +
    geom_segment(aes(x = segment,
                     xend = segment,
                     y = 0,
                     yend = 0.5),
                 linetype = "dashed")

  plot(p)

  plots_list[[number]] <- p

}

plots_list

If you check the plots after launching the plot_list object, you'll see the the red line changes position for each plot, while the black segment doesn't. Any suggestion about how to solve that? Thanks!

1 Answer 1

1

You have to take out aes().

The original geom_segment() call is in blue. The commented out code for annotate() works the same as geom_segment() without aes().

set.seed(seed = 314159)

library(ggplot2)

plots_list <- list()

for (number in c(1:10)) {
  line <- number
  segment <- number + 1
  
  p <- ggplot(data = data.frame(x = c(-3, 3)),
              aes(x)) +
    stat_function(fun = dnorm,
                  n = 101,
                  args = list(mean = 0,
                              sd = 1)) +
    geom_vline(xintercept = line,
               colour = "red",
               size = 0.5,
               linetype = "dashed") +
    geom_segment(x = segment,           # the new segment is black
                 xend = segment,
                 y = 0,
                 yend = 0.5,
                 linetype = "dashed") +
    geom_segment(aes(x = segment,       # your original segment is blue
                     xend = segment,
                     y = 0,
                     yend = 0.5),
                 linetype = "dashed",
                 col = "blue")
    # annotate("segment",        # this works, too
    #          x = segment,
    #          xend = segment,
    #          y = 0,
    #          yend = 0.5,
    #          linetype = "dashed",
    #          col = "orange")
  
  plot(p)
  
  plots_list[[number]] <- p
}

plots_list

enter image description here

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

2 Comments

Thanks a lot! Didn't know I could treat the segment as a vertical line.
I have the same problem as the OP but taking out aes() didn't solve it (it actually removes the segment from the plot). Where does this behaviour come from? Why is it incompatible with loops?

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.