2012-01-07 245 views
14

我正在实施R(模拟退火)中的旅行推销员问题(TSP)的解决方案,我想定期输出当前最佳路径。我已经搜索了很多关于如何在for循环中输出图的方法,并且迄今为止失败了。在RStudio循环中绘图

我使用RStudio,并希望看到他们生成的图形。如果你曾经看过TSP求解器做他们的事情,你会明白它有多酷。这里是我想看到的图形输出示例http://www.staff.science.uu.nl/~beuke106/anneal/anneal.html

我不认为内存使用情况会是一个问题(在大约500,000次迭代期间,我只希望得到50-100个图)。这里有一个简单的功能,在这里我们希望在函数运行的时候,看到10个不同的情节:

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

当我运行它,我看到的是(在RStudio)生产的最终情节。我怎样才能看到他们生成的情节?

另外:我在Ubuntu上(无论最新的稳定版本是什么)。不知道这是否相关。

谢谢大家提前。

编辑:每墨菲队长墨菲的建议,我试图在Linux终端运行这个,并出现图形。我仍然认为“如何在RStudio中执行此操作?”的问题?但是,仍然有关。这是一个很好的计划,所以也许有人有一个想法,可以做些什么来实现这个目标?

EDIT2:正如Thilo所说,这是Rstudio中的一个已知错误。如果任何人有任何其他想法来解决这个问题,而软件本身没有被修复,那么还有什么可以讨论的。否则,请考虑解决这个问题。

+1

在标准R控制台(而不是R工作室)试试你的代码。迭代情节似乎出现在我身上,而不仅仅是结尾。 – 2012-01-07 20:08:00

+1

我不知道你是否看到过,但是在RStudio的绘图面板中有来回箭头,这实际上是一种很好的方式让你循环生成的绘图(我没有注意到它们一段时间) 。当然,你并没有看到它们产生的情节,但是在那之后,你可以随意循环这些情节。 – 2012-01-07 20:20:46

+4

我没有给你一个完整的答案,但也许有一些信息:看起来这是(是?)2011年RStudio中的一个错误。请参阅http://support.rstudio.org/help/discussions/suggestions/214-地块 - 应该更新在实时-OSX – Thilo 2012-01-07 20:36:03

回答

8

一两件事你可以做的是在那里打开一个窗口,X11和情节:

x11() 
Plotz() 

这应该工作一样端子运行它。

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() 
1

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

16

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

(我感到惊讶的是dev.flush()不给你所希望看到的结果,这可能是一个错误。)

+1

这也是一个很好的解决方案。这个和@Sacha的区别在于,如果我们在短时间内生成很多地块,那么这个(至少在我的系统上)并不总是显示所有的地块,如果它们生成得太快。这不一定是坏事,这取决于你是否想要看到所有的情节,或者你的目标只是对TSP系统的当前状态有一个总体的了解。就我的目的而言,x11()解决方案效果更好,但这也是一个很好的解决方案。 – Rguy 2012-01-11 20:56:40

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

上@ JoeCheng的答案,@上回答RGuy的评论跟进:我worked out with the RStudio folks,这个问题似乎时有太多的绘图在太短的时间跨度去上主要出现。解决方案有两个:

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

举例来说,在我的电脑(I7,RStudio服务器)上,下面的代码不会更新,直到循环完成:实时

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的数量,而不是要绘制的数据量。

+1

当我想在TCL TK窗口中绘图时,我的问题是什么?我无法找到更新窗口的方法。 当我做'Sys.sleep(0)',它正在更新,但我看不到变化,直到我通过按住并移动标题栏来移动(字面上)该窗口。 – David 2013-08-20 10:05:25

0

您可以使用animate包将您的图形叠加到GIF中。