Zac Warham
Zac Warham

Reputation: 157

Storing ggplots in loop makes all plots the last one

I have been banging my head against the wall for hours trying to fix this. I am facing a similar issue to here but I am unable to work out my problem through the provided solution. Every time I run it, I can print() plot as I loop and see the correct ones but every loop, all plots in the list are replaced with the current one, until finally the list is just full of the last iteration. Can someone please help me work out why it is not working?

My reduced example (not working)

plotCount <- 5
multiplePlots <<- tibble(clockPlots = list(), index = double())
loopCount = 1
while(plotCount > 0) {
  
  plot <- ggplot()
  
  short <- tibble(val = c(1:12), x = 3 * sin(val * pi / 6), y = 3 * cos(val * pi / 6))
  long <- tibble(val = c(1:60), x = 4.5 * sin(val * pi / 30), y = 4.5 * cos(val * pi / 30))
  shorter <- short[loopCount,]
  longer <- long[loopCount,]
  plot <- plot + geom_segment(aes(x = 0, y = 0, xend = shorter[[2]], yend = shorter[[3]]), colour = "black", size = 3)
  plot <- plot + geom_segment(aes(x = 0, y = 0, xend = longer[[2]], yend = longer[[3]]), colour = "black", size = 2)
  
  print(plot)
  plotCount <- plotCount - 1
  loopCount <- loopCount + 1
  
  multiplePlots <<- multiplePlots %>%
    add_row(clockPlots = list(plot), index = loopCount)
}

multiplePlots[[1]][[1]]
multiplePlots[[1]][[2]]
multiplePlots[[1]][[3]]

After viewing solution in other document (not working either)

plotCount <- 5 
multiplePlots <<- tibble(plots = double(), index = double()) 
plot_list = list() 
loopCount = 1

short <- tibble(val = c(1:12), x = 3 * sin(val * pi / 6), y = 3 * cos(val * pi / 6)) 
long <- tibble(val = c(1:60), x = 4.5 * sin(val * pi / 30), y = 4.5 * cos(val * pi / 30))

while(plotCount > 0) {   
    shorter <- short[loopCount*2,]   
    longer <- long[loopCount*2,]   plot_list[[loopCount]] <- local({
        loopCount <- loopCount
        plot <- ggplot() + 
            geom_segment(aes(x = 0, y = 0, xend = shorter[[2]], yend = shorter[[3]]), colour = "black", size = 3) + 
            geom_segment(aes(x = 0, y = 0, xend = longer[[2]], yend = longer[[3]]), colour = "black", size = 2)   
    })
    plotCount <- plotCount - 1   
    loopCount <- loopCount + 1 
}

plot_list[[1]] 
plot_list[[2]] 
plot_list[[3]] 
plot_list[[4]] 
plot_list[[5]]

I have tried breaking it down so many times it barely even represents my original code but I can't work out what the issue is.

Upvotes: 0

Views: 168

Answers (1)

Marek Fiołka
Marek Fiołka

Reputation: 4949

Here is the solution you are looking for

createPlot = function(i){
  dfs = tibble(x = 0, xend = 3*sin((1:12)[i]*pi/6), y=0, yend = 3*cos((1:12)[i]*pi/6))
  dfl = tibble(x = 0, xend = 4.5*sin((1:60)[i]*pi/30), y=0, yend =4.5*cos((1:60)[i]*pi/30))
  p1 = ggplot()+
    geom_segment(aes(x, y, xend = xend, yend = yend), data=dfs, colour = "black", size = 3)+
    geom_segment(aes(x, y, xend = xend, yend = yend), data=dfl, colour = "black", size = 3)
}

multiplePlots = tibble(index = 1:5) %>% 
  rowwise() %>% 
  mutate(clockPlots = list(createPlot(index)))

lapply(multiplePlots$clockPlots, plot)

Here are a few selected charts enter image description here

enter image description here

enter image description here

Upvotes: 2

Related Questions