基于SelectInput选轴的DT数据Plotly绘图异常:多行无图形
问题诊断与修复
你的代码存在几个关键问题,导致多行数据时绘图失败:
核心问题分析
- 全局赋值滥用:用
<<-给XAxis、YAxis等反应式对象赋值,破坏了Shiny的反应式上下文,导致数据更新异常。 - 数据格式错误:从data.frame提取坐标轴数据时,用
final_df[xaxis]得到的是子data.frame而非向量,后续转成list的操作完全错误,plotly无法识别这种格式。 - 无效依赖与冗余代码:
summarised_frame的逻辑混乱(分组列和汇总列重名),且绘图时根本没用到这个数据,却用req()强制依赖,干扰了反应式流程。 - 筛选逻辑偏差:
input$table_rows_all会返回DT的所有行索引(包括未筛选的),如果要获取筛选后的行,应该用input$table_rows_current。
修正后的完整代码
library(ggpubr) library(ggplot2) library(plotly) library(shiny) library(dplyr) library(DT) library(readr) library(shinythemes) # 补充原代码缺失的主题包 initial_df <- data.frame('Scratch' = c(1, 1, 3, 4, 6), 'Particle' = c(3, 4, 5, 6, 6)) initial_df$count <- sapply(strsplit(rownames(initial_df), ","), "[[", 1) column_names <- colnames(initial_df) ui <- fluidPage( theme = shinytheme('spacelab'), navbarPage( 'Test 1', tags$style(HTML(".content {padding-top: 65px;}")), position = c('static-top'), fluid = TRUE, tabPanel('Test 2', fluidRow( column(12, fluidRow( column(3, selectInput('xAxis', 'X-Axis', choices = c('Scratch')), selectInput('yAxis', 'Y-Axis', choices = c('Scratch', 'Particle'))), column(9, h4('Plot'), plotlyOutput('fig') ) ), h4('Waferdata'), DT::dataTableOutput('table') ) ) ) ) ) server <- function(input, output, session) { # 移除全局赋值,定义正常反应式对象 XAxis <- reactive({ input$xAxis }) YAxis <- reactive({ input$yAxis }) in_react_frame <- reactiveVal(initial_df) filtered_frame <- reactive({ frame <- req(in_react_frame()) # 改用table_rows_current获取筛选后的行索引 indexes <- req(input$table_rows_current) frame[indexes, , drop = FALSE] }) output$table <- renderDT({ in_react_frame() }, filter = "top", options = list( pageLength = 25 ) ) output$fig <- renderPlotly({ xaxis <- XAxis() yaxis <- YAxis() final_df <- req(filtered_frame()) # 直接提取向量,无需多余转list操作 x_vals <- final_df[[xaxis]] y_vals <- final_df[[yaxis]] fig <- plot_ly(x = ~x_vals, y = ~y_vals, type = 'scatter', mode = 'markers') fig <- fig %>% layout(title = "Graph", showlegend = F, xaxis = list(showgrid = TRUE, zeroline = TRUE, showticklabels = TRUE, title = xaxis, tickangle=45), yaxis = list(showgrid = TRUE, zeroline = TRUE, showticklabels = TRUE, title = yaxis, tickangle=45)) }) } shinyApp(ui, server)
关键修改点说明
- 移除全局赋值:所有反应式对象和变量都在server函数内部定义,避免污染全局环境,保证反应式上下文正常工作。
- 修正数据提取方式:用
[[代替[提取坐标轴数据,直接得到向量,符合plotly的输入要求。 - 删除冗余代码:移除了无用的
summarised_frame及其依赖,简化反应式流程。 - 修复筛选逻辑:用
input$table_rows_current获取DT筛选后的行索引,确保绘图数据是用户筛选后的结果。 - 补充缺失包:添加
shinythemes包的加载,避免原代码中shinytheme()函数报错。
内容的提问来源于stack exchange,提问作者Ji Th
相关产品推荐
相关产品推荐

