将重置按钮放入R Shiny交互式绘图中

时间:2013-10-26 14:53:31

标签: r plot shiny

我想在交互式绘图闪亮应用中添加重置按钮。该应用程序执行以下操作:鼠标单击时捕获鼠标的位置,在该位置绘制一个红点,并用蓝线连接所有以前的位置。如果按下重置按钮,则应删除所有红点和蓝线,并开始新的绘图过程。但是,实际上当我单击重置按钮时,最后一个红点仍然在绘图区域上。我不确定出了什么问题。谢谢你的帮助。

PS:感谢jcheng5提供的情节鼠标事件!

server.R如下:

library(shiny)
N = 30 # sample size
x = sort(runif(N, 0, 10)); y = x + rnorm(N)
xval=NULL
yval=NULL

shinyServer(function(input, output) {
get.coords <- reactive({
    data.frame(x=input$coords$x, y=input$coords$y)
})

actiontype <- reactiveValues()
actiontype$lastAction <- 'draw'

observe({
    if (input$reset != 0) 
        actiontype$lastAction <- 'reset'
})
observe({
    if (input$closepolygon != 0) 
        actiontype$lastAction <- 'closepolygon'
})

output$diagPlot = renderPlot({
    plot(x, y, xlim = range(x), ylim = range(y))
    grid()

    if (identical(actiontype$lastAction, 'reset')) {
        xval <<- NULL
        yval <<- NULL
        actiontype$lastAction <- 'draw'

    } else if (identical(actiontype$lastAction, 'draw')){
        temp <- get.coords()
        xval <<- c(xval,temp$x)
        yval <<- c(yval,temp$y)

        points(xval, yval, pch = 19, col = 'red', cex = 1.5)
        for (i in 1:(length(xval)-1))
             lines(c(xval[i],xval[i+1]),c(yval[i],yval[i+1]),type="l",col="blue")
        if(identical(actiontype$lastAction, 'closepolygon'))
             lines(c(xval[1],xval[length(xval)]),c(yval[1],yval[length(yval)]),type="l",col="blue")         
    }
}, width = 700, height = 600)
})

和ui.R

library(shiny)

shinyUI(pageWithSidebar(

headerPanel('iPED: The interactive ChIP-PED analysis platform'),

sidebarPanel(
    helpText("graph"),
    actionButton('closepolygon', 'Close the Polygon'),
    actionButton('reset', 'Reset')
),

mainPanel(
    plotOutput('diagPlot', clickId="coords", height="auto", width="100%")
)
))

2 个答案:

答案 0 :(得分:1)

问题在于,当您测试actiontype$lastAction'reset'时,您会立即将actiontype$lastAction设置为'draw',因此,您输入else部分创建temp的位置,最后绘制。即使您将xvalyval设置为NULL,前一次点击仍然存在input$coords。因此,解决方案应该在于“重置”input$coords

经过多次尝试(例如将input$coords设置为NULL等)后,我想出了以下内容(无论我在哪里更改,都会在评论中注明):

#server.R
library(shiny)
N = 30
x = sort(runif(N, 0, 10)); y = x + rnorm(N)
xval=NULL
yval=NULL
checker <- 1 #### CHANGE

shinyServer(function(input, output) {
get.coords <- reactive({
    data.frame(x=input$coords$x, y=input$coords$y)
})

actiontype <- reactiveValues()
actiontype$lastAction <- 'draw'

observe({
    if (input$reset != 0)
        actiontype$lastAction <- 'reset'
})
observe({
    if (input$closepolygon != 0)
        actiontype$lastAction <- 'closepolygon'
})

output$diagPlot = renderPlot({
    plot(x, y, xlim = range(x), ylim = range(y))
    grid()

    if (identical(actiontype$lastAction, 'reset')) {
        xval <<- NULL
        yval <<- NULL
        checker <<- 0 ####CHANGE
        actiontype$lastAction <- 'draw'

    } else if (identical(actiontype$lastAction, 'draw')){
        temp <- get.coords()
        xval <<- c(xval,temp$x)
        yval <<- c(yval,temp$y)

        ########### CHANGE...
        if(identical(checker, 0))
         {
           points(xval, yval, pch = 19, col = rgb(1,0,0,0), cex = 1.5)
           xval <<- NULL
           yval <<- NULL
           checker <<- 1
         }else
         {
          points(xval, yval, pch = 19, col = 'red', cex = 1.5)
         }
        ############# ...CHANGE

        for (i in 1:(length(xval)-1))
             lines(c(xval[i],xval[i+1]),c(yval[i],yval[i+1]),type="l",col="blue")
        if(identical(actiontype$lastAction, 'closepolygon'))
       lines(c(xval[1],xval[length(xval)]),c(yval[1],yval[length(yval)]),
              type="l",col="blue")
    }
}, width = 700, height = 600)
})

我想到的是实际绘制最后存储的input$coords但是100%透明度,并删除之前点击的input$coordschecker的作用是在10之间波动并完全相同。

这可能更容易实现,但我现在想不出更明确的方法。

答案 1 :(得分:0)

你的最后一点没有消失的原因是因为一旦点击完成,它就会持续存在,直到它被更新的点击数据替换。据我所知,此功能无法修改。但是处理这些数据的方式可以。

事实证明,clickID实际上将3个数值(而不仅仅是2)发送回Shiny会话:x,y和唯一标识符double。我发现解决方案实际上在于充分利用第三个标识符。我存储在reactiveValue对象中,让我们称之为“reactive $ uniqueIdentifier”,该标识符只更新了第二个reactiveValue对象,让我们称之为“reactive $ clickedCoordinates”,当新的clickID标识符与上一个不同时,使用clickID坐标。然后我使用反应性$ clickedCoordinates作为我想要绘制的点的坐标。然后,当我想重置点击的坐标并取消一切时,我只需将reactive $ clickedCoordinates的值设置为NULL。这使得所有绘图点都消失了! : - )