我正在try 制作一个交互式绘图,它突出显示点击shiny中的plotly绘图,并允许用户使用sliderInput更改绘图上显示的数据范围.如果在用户添加点击后更改了范围,我会try 保留已添加的痕迹.目前,它删除了所有现有的痕迹,因为它每次都会完全呈现新的情节.

我使用addTraces而不是restyle来点击标记,因为我还希望能够删除跟踪,这比重新设置单个标记的样式更容易.我正在对用于渲染绘图的数据进行子集设置,而不仅仅是更改x轴限制,因为我使用的是具有数万个数据点的非常长的时间序列,而子集设置似乎可以极大地提高性能,否则会非常慢.

我试着将公认的答案修改为this question,但因为用例略有不同,数据 struct 更复杂,所以不能真正做到.我还是个新手,这可能是问题的一部分.

我try 将每个添加的轨迹的相应值保存到react 式数据帧中,并将轨迹添加到observeEvent,但似乎也不起作用.

#Sample Data
df<-data.frame(t=seq(as.POSIXct("2024-01-01 00:00:00", tz='UTC'),
                     as.POSIXct("2024-01-02 00:00:00", tz='UTC'), by="1 hour"),
               V1=sample(1:20,25, replace=T))
library(shiny)
library(plotly)

# UI

ui <-fluidPage(
  fluidRow(style = "padding: 15px;",
             actionButton("remove", "Delete last click", width='150px') 
  ),
  fluidRow(style = "padding: 0px;",
           plotlyOutput("plot"),
           div(style = "margin: auto; width: 90%",
               sliderInput("range", label = NULL, width="100%",
                           min = as.POSIXct(min(df$t), tz='UTC'), 
                           max = as.POSIXct(max(df$t), tz='UTC'), 
                           value = c(as.POSIXct(min(df$t), tz='UTC'), 
                                     as.POSIXct(max(df$t), tz='UTC')),
                           timeFormat="%F %T", timezone="+0000")
           ))
)
# SERVER

server <- function(input, output, session) {
  
  output$plot <- renderPlotly({
    df[df$t>=input$range[1] & df$t <=input$range[2],] %>%
      plot_ly(x= ~t, y = ~V1, type='scatter', mode='line')%>%
      layout(showlegend=F) 
  })
  
  # highlight clicked point
  observeEvent(event_data("plotly_click"),{
    d <- req(event_data("plotly_click"))
    
    plotlyProxy("plot", session) %>%
      plotlyProxyInvoke("addTraces",list(x =c(d$x,d$x), y=c(d$y,d$y), type = 'scatter',
                                         marker=list(symbol='x', size=10, color='red')))
    })
  
  # remove last click
  observeEvent(input$remove, {
    plotlyProxy("plot", session) %>%
      plotlyProxyInvoke("deleteTraces", list(-1))
  })
}
shinyApp(ui,server)

Interactive Plotly

Attempt with 100:(不起作用,即不添加痕迹)

server <- function(input, output, session) {
  
  vals<-reactiveValues(
    d_click = data.frame()
  )
  
  output$plot <- renderPlotly({
    df[df$t>=input$range[1] & df$t <=input$range[2],] %>%
      plot_ly(x= ~t, y = ~V1, type='scatter', mode='line')%>%
      layout(showlegend=F)
  })
  
  #did my slider range change and I already have highlighted points?
  observeEvent(input$range,{
    if(dim(vals$d_click)[1]>0){
      plotlyProxy("plot", session) %>%
        plotlyProxyInvoke("addTraces",list(list(x=c(vals$d_click$x,vals$d_click$x), 
                                                y=c(vals$d_click$y,vals$d_click$y), 
                                                type = 'scatter',
                                                marker=list(symbol='x', size=10, color='red'))))
    }
  })
  
  # highlight clicked point
  observeEvent(event_data("plotly_click"),{
    d <- req(event_data("plotly_click"))
    
    plotlyProxy("plot", session) %>%
      plotlyProxyInvoke("addTraces",list(x =c(d$x,d$x), y=c(d$y,d$y), type = 'scatter',
                                         marker=list(symbol='x', size=10, color='red')))
    
      vals$d_click<-rbind(vals$d_click,d)
  })
  
  # remove last click
  observeEvent(input$remove, {
    plotlyProxy("plot", session) %>%
      plotlyProxyInvoke("deleteTraces", list(-1))
    
    vals$d_click <- vals$d_click[-nrow(vals$d_click),]
  })
}

推荐答案

您可以按如下方式更新数据:

  output$plot <- renderPlotly({
    df %>%
      plot_ly(x= ~t, y = ~V1, type='scatter', mode='line')%>%
      layout(showlegend=F) 
  })

  Dat <- eventReactive(input$range, {
    df[df$t >= input$range[1] & df$t <= input$range[2], ]
  })
  
  observeEvent(Dat(), {
    plotlyProxy("plot", session) %>%
      plotlyProxyInvoke("restyle", list(x = list(Dat()$t), y = list(Dat()$V1)), 0)
  })

plotlyProxyInvoke中的0意味着必须仅对跟踪0应用重新样式化.

但是,如果通过单击添加了一些点,并且这些点在选定的时间范围之外,则绘图的时间范围将包括这些点.因此,您还必须更新X轴范围:

  observeEvent(Dat(), {
    plotlyProxy("plot", session) %>%
      plotlyProxyInvoke("restyle", list(x = list(Dat()$t), y = list(Dat()$V1)), 0)
    plotlyProxy("plot", session) %>%
      plotlyProxyInvoke("relayout", list(xaxis = list(range = input$range)))
  })

R相关问答推荐

有没有方法将琴弦完全捕捉到R中的多边形?

通过绘图 Select 线串几何体并为其着色

通过使用str_detect对具有相似字符串的组进行分组

derrr summarise每个组返回多行?

在"gt"表中添加第二个"groupname_col",而不连接列值

当两个图层映射到相同的美学时,隐藏一个图层的图例值

将文件保存到新文件夹时,切换r设置以不必创建目录

在不丢失空值的情况下取消列出嵌套列表

将二进制数据库转换为频率表

如何基于两个条件从一列中提取行

有没有办法使用ggText,<;Sub>;&;<;sup>;将上标和下标添加到同一元素?

使用R中的dist()迭代ID匹配的欧几里德距离

跨列查找多个时间报告

仅当后续值与特定值匹配时,才在列中回填Nas

SHILINY中DT列的条件着色

按组和连续id计算日期差

如何使用包metaviz更改标签的小数位数?

通过比较来自多个数据框的值和R中的条件来添加新列

Ggplot2水平线和垂直线的图例图标不匹配

Gggvenn为Venn增加了不存在的价值