我试图让我的RShiny应用程序显示一个实时的条形图。基本上逻辑是这样的:RShiny将建立与文件的连接并连续读取它直到它到达文件末尾。该文件也将更新。我的server.R代码如下:
library(stringr)
shinyServer
(
function(input, output, session)
{
output$plot1.3 = renderPlot({
con = file("C:/file.csv", open = "r")
a = c()
while (length((oneLine = readLines(con, n = 1, warn = F))) > 0)
{
#constructing vector
a = c(a, str_extract(oneLine, "\\[[A-Z]+\\]"))
#making vector into a table
b = table(a)
#plotting the table
barplot(b, xlim = c(0,10), ylim = c(0,1000), las = 2, col = rainbow(5))
#Sleeping for 1 second to achieve a "animation" feel
Sys.sleep(1)
}
close(con)
})
}
)
我知道我在这里要做的是低效的,因为我不断重建一个向量并从中创建一个表并重新绘制每次迭代,但这段代码在RStudio上完美运行,但该图只出现在我的RShiny上最后一次迭代完成时的应用程序(当达到EOF时)。发生了什么事?
答案 0 :(得分:3)
发生的事情是,在renderPlot()
的调用返回之前,浏览器没有任何显示内容,只有在所有while循环结束时才会显示。
@Shiva建议让您的数据被动(并提供整个代码)。我完全同意,但还有更多。
最好的办法是使用一对闪亮的reactiveTimer
和ggvis
渲染工具。
首先,您要将数据定义为:
# any reactive context that calls this function will refresh once a second
makeFrame <- reactiveTimer(1000, session)
# now define your data
b <- reactive({
# refresh once a second
makeFrame()
# here put whatever code is used to create current data
data.frame([you'll need to have your data in data.frame form rather than table form])
})
如果您使用ggvis
渲染图,ggvis
内部知道如何连接到shiny
反应式上下文,以便...哦,不要担心它,重点是,如果您将b
(函数b
,而不是b()
函数的返回值)提供给ggvis,它将平滑地为每个更新设置动画。
代码看起来像这样:
b %>% # passing the reactive function, not its output!
ggvis([a bunch of code to define your plot]) %>%
layer_bars([more code to define your plot]) %>%
bind_shiny("nameofplotmatchingsomethinginoutput.ui")
然后它看起来都很漂亮。如果需要,您还应该可以轻松找到示例代码,让用户启动和停止动画或设置帧速率。
如果您发布了一个可重复性最低的示例,我会尝试停止并编辑代码以便运行。