简体   繁体   English

ggplot 在 shiny 的 eventReactive() 内无法正常工作

[英]ggplot not working properly inside eventReactive() in shiny

I wasted hours to find out why my plot is automatically updating itself when I change inputs while it was supposed to wait for the Run button but it simply ignored that step and I ended up finally finding ggplot as the trouble maker:!!我浪费了几个小时来找出为什么我的 plot 在我更改输入时会自动更新自己,而它应该等待“运行”按钮,但它只是忽略了该步骤,我最终发现ggplot是麻烦制造者:!! This is my minimal code:这是我的最小代码:

library(ggplot2)
library(tidyverse)

varnames <- names(cars)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      fluidRow(
        column(
          width = 12,

          # Variables Inputs:
          varSelectInput("variables", "Select Input Variables", cars, multiple = TRUE),
          selectizeInput("outvar", "Select Output Variable", choices = varnames, "speed", multiple = F),

          # Run Button
          actionButton(inputId = "run", label = "Run")
        )
      )
    ),

    # Main panel for displaying outputs ----
    mainPanel(
      plotOutput("plot")
    )
  )
)

server <- function(input, output, session) {
  
  df <- reactive({
    cars %>% dplyr::select(!!!input$variables, input$outvar)
  })


  plt <- eventReactive(input$run, {
    
    #Just creating lm formula
    current_formula <- paste0(input$outvar, " ~ ", paste0(input$variables, collapse = " + "))
    current_formula <- as.formula(current_formula)
    #Fitting lm
    fit <- lm(current_formula, data = df())
    pred <- predict(fit, newdata = df())

    #Plotting
    ggplot(df(), aes(df()[, input$outvar], pred)) +
      labs(x = "Observed", y = "Predicted") +
      geom_point() +
      theme_bw()

     #plot(df()[, input$outvar], pred)       #This one works fine!!!!
  })


  output$plot <- renderPlot({
     plt()
  })
}

# Run the application
shinyApp(ui = ui, server = server)

If you run this, you'll notice that ggplot doesn't care anymore about the Run button after the 1st run and it keeps updating as you change the inputs,!如果你运行它,你会注意到 ggplot 在第一次运行后不再关心Run按钮,它会随着你改变输入而不断更新,! However, if you use the simple base plot function (which I put in a comment in the code) there wouldn't be any problems and that works just fine.但是,如果您使用简单的基础plot function(我在代码中添加了注释),就不会有任何问题,而且效果很好。 Sadly I need ggplot in my app because base plot is ugly.可悲的是,我的应用程序中需要 ggplot,因为基础 plot 很难看。 I am seeing suggestion for using isolate() to solve this issue but I have no clue where isolate() should be put to fix my problem also it doesn't make sense to use isolate() when base plot function works fine without it and it's the ggplot that makes the problem.我看到了使用isolate() 解决此问题的建议,但我不知道应该将isolate() 放在哪里来解决我的问题,而且当base plot function 没有它时使用isolate() 也没有意义,并且这是造成问题的 ggplot 。 Any explanation would be appreciated.任何解释将不胜感激。

The issue is that ggplot aesthetics are lazy evaluated.问题是 ggplot 美学是懒惰的评估。 You really want to put symbols into the aes() rather that reactive data values.您真的想将符号放入aes()而不是反应数据值。 Change your plotting code to将您的绘图代码更改为

ggplot(df(), aes(.data[[input$outvar]], pred)) +
  labs(x = "Observed", y = "Predicted") +
  geom_point() +
  theme_bw()

With ggplot you use the .data pronoun to access the current data source rather than trigger the reactive df() object again.使用 ggplot 您可以使用.data代词来访问当前数据源,而不是再次触发反应式df() object。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM