Home > Software engineering >  geom_segment() doesn't store object value defined inside a for loop
geom_segment() doesn't store object value defined inside a for loop

Time:10-06

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!

CodePudding user response:

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

  • Related