Plotting during a loop in RStudio

2019-01-09 09:38发布

问题:

I am implementing a solution to the Traveling Salesman Problem (TSP) in R (simulated Annealing) and I want to output the current best path periodically. I have searched quite a bit for how to output plots during a for loop and have thus far failed.

I use RStudio, and want to see the graphs as they are generated. If you have ever watched TSP solvers do their thing, you will understand how cool it is to watch. Here is a sample of the graphics output I want to see http://www.staff.science.uu.nl/~beuke106/anneal/anneal.html

I don't think that the memory usage will be a problem (during about 500,000 iterations, I am only expecting 50-100 plots). Here is a sample function, where we would expect to see 10 different plots during the time the function runs:

Plotz <- function(iter = 1000000, interval = 100000) {
  x <- 1:10
  for(i in 1:iter){
    y <- runif(10)
    if(i %% interval == 0) {
      plot(x, y)
    }
  }
  return(c(x, y))
}
Plotz()

When I run this, all I see is the final plot produced (in RStudio). How can I see the plots as they're generated?

Also: I am on Ubuntu (whatever the newest stable release is). Don't know if that is relevant.

Thank you everyone in advance.

EDIT: Per Captain Murphy's suggestion, I tried running this in the Linux terminal, and the graphics appeared. I still think the question of "How to do this in RStudio?" Is still relevant, however. It's such a good program, so maybe someone has an idea of what could be done to get this to work?

EDIT2: As Thilo stated, this is a known bug in Rstudio. If anyone has any other ideas to solve this without the software itself being fixed, then there is still something to discuss. Otherwise, consider this question solved.

回答1:

One thing you can do is open a x11 window and plot in there:

x11()
Plotz()

That should work the same as running it in terminal.



回答2:

Calling Sys.sleep(0) should cause the plot to draw. Unlike the X11 solution, this will work on server versions of RStudio as well.

(I was surprised that dev.flush() did not give the result you were hoping for, that might be a bug.)



回答3:

Following up on @JoeCheng's answer and @RGuy's comment on that answer: as I worked out with the RStudio folks, the problem seems to primarily arise when there is too much plotting going on in too short a timespan. The solution is twofold:

  • Sys.sleep(0) helps force an update to the plotting window.
  • Plotting updates every Wth loop rather than every loop.

For instance, on my computer (i7, RStudio Server), the following code does not update until the loop completes:

N <- 1000
x <- rep(NA,N)
plot(c(0,1)~c(0,N), col=NA)
for(i in seq(N)) {
  Sys.sleep(.01)
  x[i] <- runif(1)
  iseq <- seq(i-99,i)
  points( x[i]~i )
  Sys.sleep(0)
}

The following code updates in real-time, despite having the same number of points to be plotted:

N <- 1000
x <- rep(NA,N)
plot(c(0,1)~c(0,N), col=NA)
for(i in seq(N)) {
  Sys.sleep(.01)
  x[i] <- runif(1)
  iseq <- seq(i-99,i)
  if(i%%100==0) {
    points( x[iseq]~iseq )
    Sys.sleep(0)
  }
}

In other words, it's the number of calls the plot that seems to matter, not the amount of data to be plotted.



回答4:

If you want to save the plots as well you could just open a new device in the loop and close it afterwards.

Plotz <- function(iter = 1000, interval = 100) {
  x <- 1:10

  p <- 0 #plot number

  for(i in 1:iter){

    y <- runif(10)
    if(i %% interval == 0) {
        png(file=paste(i,"png",sep="."))
        p <- p + 1; plot(x, y)
        dev.off()
    }
  }
return(c(x, y))
}


回答5:

Plotz <- function(iter = 1000, interval = 100) {
  x <- 1:10
  p <- 0 #plot number
  for(i in 1:iter){
    y <- runif(10)
    if(i %% interval == 0) {
        p <- p + 1; plot(x, y)
        readline("Please press the Enter key to see the next plot if there is one.")
    }
  }
  return(c(x, y))
}
Plotz()


回答6:

You can also use the back arrows on the plots tab of the lower left pane of the RStudio interface in order to view the plots.



回答7:

You can use the animate package to layer your plots into a GIF.



标签: r plot rstudio