You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在R语言Plotly平行坐标图中获取选中数据以更新表格

解决R中Plotly平行坐标图交互更新数据表格的问题

以下是针对你遇到的三个问题的完整解决方案,直接替换原代码即可运行:

library("shiny")
library("plotly")
library("DT")

ui <- fluidPage(
  headerPanel("Example"),
  mainPanel(
    plotlyOutput("plot"),
    verbatimTextOutput("text"),
    DTOutput("table")
  )
)

server <- function(input, output, session) {
  
  df <- reactive({read.csv("https://raw.githubusercontent.com/bcdunbar/datasets/master/iris.csv")})
  
  # 初始化反应式状态,保存所有维度的约束范围,对应初始图表设置
  current_constraints <- reactiveVal(list(
    "Sepal Width" = NULL,
    "Sepal Length" = c(5,6),
    "Petal Width" = NULL,
    "Petal Length" = NULL
  ))
  
  output$plot <- renderPlotly({
    fig <- plot_ly(
      data = df(),
      source = "myplot",
      type = "parcoords",
      line = list(color = ~species_id,
                  colorscale = list(c(0, "red"), c(0.5, "green"), c(1, "blue"))),
      dimensions = list(
        list(
          range = c(2,4.5),
          label = "Sepal Width", 
          values = ~sepal_width,
          constraintrange = current_constraints()[["Sepal Width"]]
        ),
        list(
          range = c(4,8),
          constraintrange = current_constraints()[["Sepal Length"]],
          label = "Sepal Length", 
          values = ~sepal_length
        ),
        list(
          range = c(0,2.5),
          label = "Petal Width", 
          values = ~petal_width,
          constraintrange = current_constraints()[["Petal Width"]]
        ),
        list(range = c(1,7),
             label = "Petal Length", 
             values = ~petal_length,
             constraintrange = current_constraints()[["Petal Length"]]
        )
      )
    )
    
    fig <- event_register(fig, "plotly_restyle")
  })
  
  # 处理交互事件,更新约束状态
  observeEvent(event_data("plotly_restyle", source = "myplot", session = session), {
    new_data <- event_data("plotly_restyle", source = "myplot", session = session)
    
    if (is.null(new_data)) {
      # 双击重置所有约束为初始状态
      current_constraints(list(
        "Sepal Width" = NULL,
        "Sepal Length" = c(5,6),
        "Petal Width" = NULL,
        "Petal Length" = NULL
      ))
    } else {
      # 从现有状态复制,只更新修改过的维度
      updated_constraints <- current_constraints()
      
      # 遍历返回的维度修改信息,更新对应约束
      for (i in seq_along(new_data$dimensions)) {
        dim_info <- new_data$dimensions[[i]]
        if (!is.null(dim_info$label) && !is.null(dim_info$constraintrange)) {
          updated_constraints[[dim_info$label]] <- dim_info$constraintrange
        }
      }
      
      # 如果是调整轴顺序,同步更新约束的顺序(保证和图表轴顺序一致)
      if (!is.null(new_data$dimensions) && all(sapply(new_data$dimensions, function(x) !is.null(x$label)))) {
        new_order <- sapply(new_data$dimensions, function(x) x$label)
        updated_constraints <- updated_constraints[new_order]
      }
      
      current_constraints(updated_constraints)
    }
  })
  
  output$text <- renderPrint({
    current_constraints()
  })
  
  # 根据约束过滤数据
  filtered_df <- reactive({
    constraints <- current_constraints()
    data <- df()
    
    # 逐个维度应用约束过滤
    for (dim_name in names(constraints)) {
      range_val <- constraints[[dim_name]]
      if (!is.null(range_val)) {
        # 把维度标签转为数据框列名格式
        col_name <- tolower(gsub(" ", "_", dim_name))
        data <- data[data[[col_name]] >= range_val[1] & data[[col_name]] <= range_val[2], ]
      }
    }
    
    data
  })
  
  output$table <- renderDT({
    datatable(filtered_df())
  })
  
}

shinyApp(ui,server)

关键解决思路

  • 维护完整约束状态:用reactiveVal存储所有维度的约束范围,每次交互只更新修改过的维度,避免其他维度被NULL覆盖。
  • 双击重置处理:判断event_data返回NULL时,直接将约束状态重置为初始值,实现图表和表格的同步重置。
  • 全操作覆盖完整信息:不管是拖动约束还是调整轴顺序,都基于current_constraints维护完整的约束集合,确保任何操作后都能拿到所有维度的当前状态。
  • 动态过滤数据:基于约束状态实时过滤原始数据,自动更新DT表格内容。

内容的提问来源于stack exchange,提问作者moremo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 17:57:14