如何调试无法渲染的闪亮应用程序图

问题描述 投票:0回答:1

我正在尝试为一个类构建一个闪亮的应用程序,允许您自定义简单的热图。我能够在 Shiny 之外的 R 中获得我想要的绘图输出,但遇到了应用程序实现的问题。我使用的数据是

结构(列表(距离= c(100L,100L,100L,100L,100L,100L,100L, 100L, 100L, 150L, 150L, 150L, 150L, 150L, 150L, 150L, 150L, 150L, 200L, 200L, 200L, 200L, 200L, 200L, 200L, 200L, 200L, 250L, 250L, 250L, 250L, 250L, 250L, 250L, 250L, 250L, 300L, 300L, 300L, 300L, 300L, 300L, 300L, 300L, 300L, 350L, 350L, 350L, 350L, 350L, 350L, 350L、350L、350L、400L、400L、400L、400L、400L、400L、400L、400L、 400L, 450L, 450L, 450L, 450L, 450L, 450L, 450L, 450L, 450L), 方向 = c("中心", "中心", "中心", "左", "左", "左", “右”、“右”、“右”、“中”、“中”、“中”、“左”、 “左”、“左”、“右”、“右”、“右”、“中”、“中”、 “中”、“左”、“左”、“左”、“右”、“右”、“右”、 “中心”、“中心”、“中心”、“左”、“左”、“左”、“右”、 “右”、“右”、“中”、“中”、“中”、“左”、“左”、 “左”、“右”、“右”、“右”、“中”、“中”、“中”、 “左”,“左”,“左”,“右”,“右”,“右”,“中”, “中心”、“中心”、“左”、“左”、“左”、“右”、“右”、 “右”、“中”、“中”、“中”、“左”、“左”、“左”、 "右", "右", "右"), 偏移量 = c(0, 0, 0, 20, 20, 20, 20, 20, 20, 0, 0, 0, 20, 20, 20, 20, 20, 20, 0, 0, 0, 20, 20, 20, 20, 20, 20, 0, 0, 0, 20, 20, 20, 20, 20, 20, 0, 0, 0, 20, 20, 20, 20, 20, 20, 0, 0, 0, 20, 20, 20, 20, 20, 20, 0, 0, 0, 20, 20, 20, 20, 20, 20, 0, 0, 0、7.5、7.5、7.5、7.5、7.5、 7.5), 高度 = c(12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L , 24L, 36L, 12L、24L、36L、12L、24L、36L、12L、24L、36L、12L、24L、36L、12L、24L、 36L、12L、24L、36L、12L、24L、36L、12L、24L、36L、12L、24L、36L、12L、 24L、36L、12L、24L、36L、12L、24L、36L、12L、24L、36L、12L、24L、36L、 12L、24L、36L、12L、24L、36L),水平 = c(0.1, 0.15、0.1、0.04、0.03、0.02、0.13、0.11、0.06、0.05、0.06、0.02、 0.02、0.02、0.02、0.04、0.06、0.04、0.02、0.02、0.02、0.01、0.01、 0.02、0.03、0.02、0.02、0.04、0.02、0.02、0.01、0.01、0.01、0.05、 0.04、0.02、0.02、0.02、0.02、0.01、0.01、0.01、0.03、0.02、0.02、 0.02, 0.02, 0.01, 0.01, 0.01, 0.01, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.01, 0.01, 0.01, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.01, 0.02, 0.02, 0.02, 0.02), 垂直 = c(2.3, 1.43, 0.7, 0.49, 0.12、0.07、0.88、0.74、0.6、0.47、0.34、0.23、0.04、0.04、0.03、 0.5、0.43、0.32、0.3、0.23、0.17、0.03、0.02、0.02、0.3、0.25、 0.19、0.3、0.23、0.17、0.03、0.03、0.03、0.3、0.25、0.2、0.17、 0.13、0.1、0.02、0.02、0.02、0.2、0.18、0.15、0.14、0.12、0.09、 0.02、0.02、0.02、0.2、0.15、0.15、0.1、0.08、0.07、0.02、0.02、 0.01、0.11、0.09、0.09、0.09、0.08、0.06、0.05、0.05、0.04、0.12、 0.1, 0.07)), 类 = "data.frame", row.names = c(NA, -72L))

我的应用程序的完整代码是

library(shiny)
library(shinyjs)
library(ggplot2)
library(dplyr)
library(DT)
jsCode <- "
shinyjs.colorInputBinding = function() {
  $('#colorLowInput').on('change', function() {
    Shiny.setInputValue('colorLow', $('#colorLowInput').val());
  });
  $('#colorHighInput').on('change', function() {
    Shiny.setInputValue('colorHigh', $('#colorHighInput').val());
  });
}"

#read in the data
light_data <- read.csv("lightData.csv",
                       header = TRUE, stringsAsFactors = FALSE)


ui <- fluidPage(
  useShinyjs(),
  titlePanel("Dynamic Heatmap and Data Display"),
  extendShinyjs(text = jsCode, functions = c("colorInputBinding")),
  
  
  sidebarLayout(
    sidebarPanel(
      tags$label("Lower Color"),
      tags$input(type = "color", id = "colorLowInput", value = "#0000FF"),
      tags$br(),
      tags$label("Higher Color"),
      tags$input(type = "color", id = "colorHighInput", value = "#FF0000"),
      sliderInput("heightFilter", "Select Height", min = 12, max = 36, value = c(12, 36)),
      radioButtons("dataView", "Select Data View", choices = list("All Data" = "all", "Filtered Data" = "filtered"))
    ),
      mainPanel(
        tabsetPanel(id = "MainPanel", selected = "Plot Output",
                    tabPanel(Title = "Plot Output", value="Plot",  plotOutput(outputId = "heatmap")),
                    tabPanel(Title = "Data Table", value="Table", DTOutput(outputId = "dataTable"))
        )
      )
  ),
)

server <- function(input, output, session) {
  
  filtered_data <- reactive({
    data <- light_data %>%
      filter(Height >= input$heightFilter[1] & Height <= input$heightFilter[2])
    if (input$dataView == "filtered") {
      return(data)
    } else {
      return(light_data)
    }
  })
  
  output$heatmap <- renderPlot({
    req(input$colorLow, input$colorHigh)
    data <- filtered_data()
    #print(head(data))
    #if (nrow(data) == 0) {
    #  return()
    #}
    
    ggplot(data, aes(x = Distance, y = factor(Height), fill = Horizontal)) +
      geom_tile() +
      scale_fill_gradient(low = input$colorLow, high = input$colorHigh) +
      labs(title = "Heatmap of Horizontal Light Intensity",
           x = "Distance from Truck (ft)",
           y = "Height (in)",
           fill = "Intensity (Fc)") +
      theme_minimal()
  }, height = "auto",
  width = "auto")
  
  output$dataTable <- renderDT({
    datatable(filtered_data(), options = list(pageLength = 5))
  })
}

shinyApp(ui, server)

当我运行应用程序时,我并没有真正看到我期望的选项卡,并且有一条错误消息显示

error: figure margins too large
。我以为在
height = "auto", width = "auto"
中有
renderPlot()
就可以解决这个问题吗?

我完全有可能用反应式数据过滤搞砸了一些东西,但我不知道如何从这一点开始调试它。

r shiny
1个回答
0
投票

最好的调试方法之一是从头开始,并在将它们添加回来时进行测试。

例如,我从您的

filtered_data
反应开始,并确保它根据需要输出数据。我做的一件事是
cat(length(filtered_data()[[1]]))
作为
renderPlot()
中的第一行,以观察过滤是否正在删除行。然后我将注意力转向你的情节,我注释掉了所有行并将它们一一添加回来,直到我发现
scale_fill_gradient()
行存在问题。这让我意识到您的颜色选择器实现存在问题。我建议使用
{colourpicker}
包中的预滚动颜色选择器,而不是进行调试。

这是经过这些更改的代码:

  1. 改用
    colourpicker::colourInput()
    以避免滚动您自己的颜色输入的复杂性。
  2. 将两个
    Title
    s
     中的 
    title
     编辑为 
    tabPanel()
  3. 对于
    selected
    tabsetPanel()
    参数,请使用
    tabPanel()
    value
    参数,而不是
    title
    参数
library(shiny)
library(ggplot2)
library(dplyr)
library(DT)
library(colourpicker)

light_data <- structure(list(Distance = c(100L, 100L, 100L, 100L, 100L, 100L, 100L, 100L, 100L, 150L, 150L, 150L, 150L, 150L, 150L, 150L, 150L, 150L, 200L, 200L, 200L, 200L, 200L, 200L, 200L, 200L, 200L, 250L, 250L, 250L, 250L, 250L, 250L, 250L, 250L, 250L, 300L, 300L, 300L, 300L, 300L, 300L, 300L, 300L, 300L, 350L, 350L, 350L, 350L, 350L, 350L, 350L, 350L, 350L, 400L, 400L, 400L, 400L, 400L, 400L, 400L, 400L, 400L, 450L, 450L, 450L, 450L, 450L, 450L, 450L, 450L, 450L ), Direction = c("Center", "Center", "Center", "Left", "Left", "Left", "Right", "Right", "Right", "Center", "Center", "Center", "Left", "Left", "Left", "Right", "Right", "Right", "Center", "Center", "Center", "Left", "Left", "Left", "Right", "Right", "Right", "Center", "Center", "Center", "Left", "Left", "Left", "Right", "Right", "Right", "Center", "Center", "Center", "Left", "Left", "Left", "Right", "Right", "Right", "Center", "Center", "Center", "Left", "Left", "Left", "Right", "Right", "Right", "Center", "Center", "Center", "Left", "Left", "Left", "Right", "Right", "Right", "Center", "Center", "Center", "Left", "Left", "Left", "Right", "Right", "Right"), Offset = c(0, 0, 0, 20, 20, 20, 20, 20, 20, 0, 0, 0, 20, 20, 20, 20, 20, 20, 0, 0, 0, 20, 20, 20, 20, 20, 20, 0, 0, 0, 20, 20, 20, 20, 20, 20, 0, 0, 0, 20, 20, 20, 20, 20, 20, 0, 0, 0, 20, 20, 20, 20, 20, 20, 0, 0, 0, 20, 20, 20, 20, 20, 20, 0, 0, 0, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5), Height = c(12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L, 12L, 24L, 36L), Horizontal = c(0.1, 0.15, 0.1, 0.04, 0.03, 0.02, 0.13, 0.11, 0.06, 0.05, 0.06, 0.02, 0.02, 0.02, 0.02, 0.04, 0.06, 0.04, 0.02, 0.02, 0.02, 0.01, 0.01, 0.02, 0.03, 0.02, 0.02, 0.04, 0.02, 0.02, 0.01, 0.01, 0.01, 0.05, 0.04, 0.02, 0.02, 0.02, 0.02, 0.01, 0.01, 0.01, 0.03, 0.02, 0.02, 0.02, 0.02, 0.01, 0.01, 0.01, 0.01, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.01, 0.01, 0.01, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.01, 0.02, 0.02, 0.02, 0.02), Vertical = c(2.3, 1.43, 0.7, 0.49, 0.12, 0.07, 0.88, 0.74, 0.6, 0.47, 0.34, 0.23, 0.04, 0.04, 0.03, 0.5, 0.43, 0.32, 0.3, 0.23, 0.17, 0.03, 0.02, 0.02, 0.3, 0.25, 0.19, 0.3, 0.23, 0.17, 0.03, 0.03, 0.03, 0.3, 0.25, 0.2, 0.17, 0.13, 0.1, 0.02, 0.02, 0.02, 0.2, 0.18, 0.15, 0.14, 0.12, 0.09, 0.02, 0.02, 0.02, 0.2, 0.15, 0.15, 0.1, 0.08, 0.07, 0.02, 0.02, 0.01, 0.11, 0.09, 0.09, 0.09, 0.08, 0.06, 0.05, 0.05, 0.04, 0.12, 0.1, 0.07)), class = "data.frame", row.names = c(NA, -72L))

ui <- fluidPage(
  titlePanel("Dynamic Heatmap and Data Display"),
  
  sidebarLayout(
    sidebarPanel(
      colourInput("colorLowInput", "Lower Color", value = "#0000FF"),
      tags$br(),
      colourInput("colorHighInput", "Higher Color", value = "#FF0000"),
      sliderInput(
        "heightFilter",
        "Select Height",
        min = 12,
        max = 36,
        value = c(12, 36)
      ),
      radioButtons(
        "dataView",
        "Select Data View",
        choices = list("All Data" = "all", "Filtered Data" = "filtered")
      )
    ),
    mainPanel(
      tabsetPanel(
        id = "MainPanel",
        selected = "Plot",
        tabPanel(
          title = "Plot Output",
          value = "Plot",
          plotOutput(outputId = "heatmap")
        ),
        tabPanel(
          title = "Data Table",
          value = "Table",
          DTOutput(outputId = "dataTable")
        )
      )
    )
  ),
)

server <- function(input, output, session) {
  filtered_data <- reactive({
    data <- light_data %>%
      filter(Height >= input$heightFilter[1] &
               Height <= input$heightFilter[2])
    if (input$dataView == "filtered") {
      return(data)
    } else {
      return(light_data)
    }
  })
  
  output$heatmap <- renderPlot({
    ggplot(filtered_data(), aes(
      x = Distance,
      y = factor(Height),
      fill = Horizontal
    )) +
      geom_tile() +
      scale_fill_gradient(low = input$colorLowInput,
                          high = input$colorHighInput) +
      labs(
        title = "Heatmap of Horizontal Light Intensity",
        x = "Distance from Truck (ft)",
        y = "Height (in)",
        fill = "Intensity (Fc)"
      ) +
      theme_minimal()
  }, height = "auto",
  width = "auto")
  
  output$dataTable <- renderDT({
    datatable(filtered_data(), options = list(pageLength = 5))
  })
}

shinyApp(ui, server)
#> 
#> Listening on http://127.0.0.1:7769

创建于 2024-04-22,使用 reprex v2.1.0

© www.soinside.com 2019 - 2024. All rights reserved.