17

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.

4

7 回答 7

17

调用Sys.sleep(0)应该会导致绘图。与X11解决方案不同,这也适用于 RStudio 的服务器版本。

(我很惊讶dev.flush()没有给出你希望的结果,这可能是一个错误。)

于 2012-01-11T02:14:46.953 回答
8

跟进@JoeCheng 的回答和@RGuy 对该回答的评论:当我与 RStudio 的人一起解决问题时,问题似乎主要出现在在太短的时间内进行过多的绘图时。解决方案是双重的:

  • Sys.sleep(0)有助于强制更新绘图窗口。
  • 绘制每个W循环而不是每个循环的更新。

例如,在我的计算机(i7,RStudio Server)上,以下代码在循环完成之前不会更新:

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)
}

尽管要绘制的点数相同,但以下代码会实时更新:

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)
  }
}

换句话说,调用次数plot似乎很重要,而不是要绘制的数据量。

于 2012-10-31T13:58:34.457 回答
8

您可以做的一件事是打开一个 x11 窗口并在其中绘图:

x11()
Plotz()

这应该与在终端中运行它相同。

于 2012-01-08T11:58:23.120 回答
2

如果您也想保存绘图,您可以在循环中打开一个新设备,然后再关闭它。

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))
}
于 2012-04-24T09:38:17.547 回答
1

您还可以使用 RStudio 界面左下窗格的绘图选项卡上的后退箭头来查看绘图。

于 2012-01-09T15:49:41.163 回答
1
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()
于 2012-01-09T15:29:27.460 回答
0

您可以使用 animate 包将您的绘图分层到 GIF 中。

于 2017-04-11T10:42:50.923 回答