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

在Shiny中点击Leaflet地图点位生成ggplot图表的问题

嘿,我帮你搞定这个问题!其实核心就是把Leaflet标记点的点击事件正确传递给Shiny的反应式系统,再用点击到的站点数据生成ggplot。我给你写个完整的可运行示例,拆解关键步骤:

完整可运行示例代码
library(shiny)
library(leaflet)
library(ggplot2)
library(dplyr)
library(lubridate)

# 模拟站点温度数据
set.seed(123)
site_data <- tibble(
  site_id = c("site_1", "site_2", "site_3"),
  lat = c(39.9, 31.2, 23.1),
  lon = c(116.4, 121.5, 113.3),
  site_name = c("北京站点", "上海站点", "广州站点")
)

# 生成每个站点的时间序列温度数据
temp_data <- expand_grid(
  site_id = site_data$site_id,
  date = seq.Date(as.Date("2024-01-01"), as.Date("2024-01-31"), by = "day")
) %>%
  mutate(temperature = rnorm(n(), mean = 15 + as.integer(factor(site_id))*3, sd = 2))

ui <- fluidPage(
  titlePanel("站点温度查询"),
  fluidRow(
    column(6, leafletOutput("map")),
    column(6, plotOutput("temp_plot"))
  )
)

server <- function(input, output) {
  
  # 渲染Leaflet地图
  output$map <- renderLeaflet({
    leaflet(site_data) %>%
      addTiles() %>%
      addMarkers(
        lat = ~lat,
        lng = ~lon,
        popup = ~site_name,
        # 关键!设置layerId绑定站点ID,这样点击时能拿到对应站点标识
        layerId = ~site_id
      )
  })
  
  # 响应点击事件,获取选中站点的温度数据
  selected_temp_data <- reactive({
    # 等待用户点击标记点,避免初始状态报错
    req(input$map_marker_click)
    # 根据点击的layerId筛选对应站点的温度数据
    filter(temp_data, site_id == input$map_marker_click$id)
  })
  
  # 渲染温度趋势图
  output$temp_plot <- renderPlot({
    # 如果没有选中站点,显示提示图
    if (is.null(selected_temp_data())) {
      ggplot() +
        annotate("text", x = 1, y = 1, label = "点击地图上的站点查看温度", size = 5) +
        theme_void()
    } else {
      selected_data <- selected_temp_data()
      site_name <- filter(site_data, site_id == selected_data$site_id[1])$site_name
      
      ggplot(selected_data, aes(x = date, y = temperature)) +
        geom_line(color = "#2c3e50", linewidth = 1) +
        geom_point(color = "#e74c3c", size = 2) +
        labs(title = paste(site_name, "1月温度趋势"),
             x = "日期", y = "温度(℃)") +
        theme_minimal() +
        theme(plot.title = element_text(hjust = 0.5, size = 16, face = "bold"))
    }
  })
}

shinyApp(ui, server)
关键步骤拆解
  • 绑定标记点唯一标识:在addMarkers里必须设置layerId = ~site_id,这是让Shiny能识别你点击了哪个站点的核心。没有这个参数的话,input$map_marker_click只会返回坐标,拿不到具体站点信息。
  • 捕获点击事件:用input$map_marker_click$id获取点击到的站点ID,再通过reactive()函数把筛选后的温度数据变成反应式对象,这样数据变化时ggplot会自动更新。
  • 处理初始状态:用req(input$map_marker_click)确保只有用户点击后才执行数据筛选,避免启动时因为input$map_marker_click为NULL而报错;同时在ggplot渲染时判断是否有选中数据,显示友好提示。

你可以直接运行这段代码,点击地图上的三个站点,就能看到对应站点的温度趋势图啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:13:29