点击Leaflet地图上的点生成Shiny中的ggplot。

6
使用R中的Shiny,我正在尝试创建一个Leaflet地图,允许用户单击任何标记以生成表示该特定站点信息(温度)的相应图表。
我结合了这个问题的代码(Click on points in a leaflet map as input for a plot in shiny)和这个博客上的第二个技巧(https://www.r-bloggers.com/4-tricks-for-working-with-r-leaflet-and-shiny/),但仍然无法成功在Shiny中注册点击的标记点。
即,当我单击任何站点时,没有任何绘图。
根据进一步的研究,我找不到任何解决方案,欢迎任何帮助。
library(leaflet)
library(shiny)
library(ggplot2)

# example data frame 
wxstn_df <- data.frame(Site = c("a", "a", "b"), Latitude = c(44.1, 44.1, 37), Longitude = c(-110.2, -110.2, -112.7), Month = c(1,2,1), Temp_avg = c(10, 18, 12))

ui <- fluidPage(column(7, leafletOutput("wsmap", height = "600px")),
  column(5, plotOutput("plot", height = "600px"))
)

server <- function(input, output) {

  # create a reactive value to store the clicked site
  stn <- reactiveValues(clickedMarker = NULL)

  ## leaflet map
  output$wsmap <- renderLeaflet({
    leaflet() %>% 
      addTiles() %>% 
      addCircleMarkers(data = wxstn_df, ~unique(Longitude), ~unique(Latitude), layerId = ~unique(Site), popup = ~unique(Site)) 
  })

 # store the click
  observeEvent(input$map_marker_click, {
    stn$clickedMarker <- input$map_marker_click
  })

output$plot <- renderPlot({
      ggplot(wxstn_df[wxstn_df$Site %in% stn$clickedmarker$Site,], aes(Month, Temp_avg)) +
        geom_line()
  }) 
}

shinyApp(ui, server)
1个回答

7
这里有一个解决方案:
library(leaflet)
library(shiny)
library(ggplot2)

# example data frame 
wxstn_df <- data.frame(Site = c("a", "a", "b"), Latitude = c(44.1, 44.1, 37), Longitude = c(-110.2, -110.2, -112.7), Month = c(1,2,1), Temp_avg = c(10, 18, 12))

ui <- fluidPage(column(7, leafletOutput("wsmap", height = "600px")),
                column(5, plotOutput("plot", height = "600px"))
)

server <- function(input, output) {

  ## leaflet map
  output$wsmap <- renderLeaflet({
    leaflet() %>% 
      addTiles() %>% 
      addCircleMarkers(data = wxstn_df, ~unique(Longitude), ~unique(Latitude), layerId = ~unique(Site), popup = ~unique(Site)) 
  })

  # generate data in reactive
  ggplot_data <- reactive({
    site <- input$wsmap_marker_click$id
    wxstn_df[wxstn_df$Site %in% site,]
  })

  output$plot <- renderPlot({
    ggplot(data = ggplot_data(), aes(Month, Temp_avg)) +
      geom_line()
  }) 
}

shinyApp(ui, server)

主要问题是您没有更改示例中的对象名称,例如input$wsmap_marker_click,因为wsmap是您的leaflet ID的名称。同样,要访问站点信息,请使用input$wsmap_marker_click$id而不是input$wsmap_marker_click$Site。在响应式函数中打印对象通常很有用,以探索输入对象的外观及如何访问其部分。
例如:
   # generate data in reactive
  ggplot_data <- reactive({
    print(input$wsmap_marker_click)
    site <- input$wsmap_marker_click$id
    print(site)

    data <- wxstn_df[wxstn_df$Site %in% site,]
    print(data)
    data})

在这种情况下,我个人更喜欢使用响应式表达式从标记单击生成ggplot数据(ggplot_data()),而不是创建一个reactiveValues对象。每次单击标记时,绘图都会使用新的ggplot_data()更新。

并且证明它有效:

enter image description here


非常感谢您的解释和提示!现在它运行得非常好。 - Jane

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接