Shiny click/brush 不能使用非笛卡尔坐标?

Shiny click/brush not working with non-cartesian coordinates?

我正在开发一个闪亮的应用程序,它应该让用户在 ggplot2 生成的世界地图上 select 地理数据点(如 this example)。

如果我使用常规 coord_cartesian 坐标系(这会扭曲地图),这会起作用,但如果我使用更合适的 coord_map 坐标系,则会失败. click/brush 事件似乎在投影后没有收到正确的坐标。有什么办法可以解决或解决这个问题而不用回到笛卡尔坐标系吗?

您可以在下面找到一个工作示例:

library(shiny)
library(ggplot2)
library(dplyr)

map_world <- function(world, mapPoints, xlim, ylim){
  # function to generate ggplot world map
  ggplot() + 
    geom_polygon(data=world, aes(x=long, y=lat, group=group)) +
    geom_point(data=mapPoints, aes(x=Longitude, y=Latitude), color="red") +
    # coord_map messes up the brush select
     coord_map(xlim=xlim, ylim=ylim)
    # coord_cartesian would work but distort the map
    # coord_cartesian(xlim=xlim, ylim=ylim)
}

mapPoints <- data.frame(Longitude=c(-103, -108, -130, -120),
                      Latitude=c(52, 40, 45, 54))
world <- map_data("world")

ui <- fluidPage(
  fluidRow(
    column(width = 6, 
           plotOutput("plot1", height = 300, 
                      click = "plot1_click", brush = "plot1_brush") )
  ),
  fluidRow(
    column(width = 6, 
           h4("Near points"), verbatimTextOutput("click_info") ),
    column(width = 6, 
           h4("Brushed points"), verbatimTextOutput("brush_info") )
  )
)

server <- function(input, output) {
  # output world map
  output$plot1 <- renderPlot({
    map_world(world = world, mapPoints = mapPoints, 
              xlim=c(-180,180), ylim=c(-90,90))
  })
  # output clicked points 
  output$click_info <- renderPrint({
    nearPoints(mapPoints, xvar="Longitude", 
                  yvar="Latitude", input$plot1_click)
  })
  # output brushed points 
  output$brush_info <- renderPrint({
    brushedPoints(mapPoints, xvar="Longitude", 
                  yvar="Latitude", input$plot1_brush)
  })
}

shinyApp(ui, server)

谢谢!

我尝试了一些使用 ggplot 的解决方案,但是 plotOutput 函数没有解决缩放问题。在帮助页面 (http://shiny.rstudio.com/reference/shiny/latest/plotOutput.html) 中,请注意以下内容:

For plotOutput, the coordinates will be sent scaled to the data space, if possible. (At the moment, plots generated by base graphics and ggplot2 support this scaling, although plots generated by lattice and others do not.) If scaling is not possible, the raw pixel coordinates will be sent. For imageOutput, the coordinates will be sent in raw pixel coordinates.

另外,

With ggplot2 graphics, the code in renderPlot should return a ggplot object; if instead the code prints the ggplot2 object with something like print(p), then the coordinates for interactive graphics will not be properly scaled to the data space.

我尝试将 ggplot 移动到脚本的服务器部分,但没有成功。

我建议的解决方案,使用基础图形:

library(shiny)
library(dplyr)
library(maps)
library(mapdata)


mapPoints <- data.frame(Longitude=c(-103, -108, -130, -120),
                        Latitude=c(52, 40, 45, 54))

ui <- fluidPage(
  fluidRow(
    column(width = 6, 
           plotOutput("plot1", height = 300, 
                      click = "plot1_click", brush = "plot1_brush") )
  ),
  fluidRow(
    column(width = 6, 
           h4("Near points"), verbatimTextOutput("click_info") ),
    column(width = 6, 
           h4("Brushed points"), verbatimTextOutput("brush_info") )
  )
)

server <- function(input, output) {
  # output world map
  output$plot1 <- renderPlot({
    map('worldHires')
    points(mapPoints$Longitude, mapPoints$Latitude, 
           col = "red", pch = 16)
  })
  # output clicked points 
  output$click_info <- renderPrint({
    nearPoints(mapPoints, xvar="Longitude", 
               yvar="Latitude", input$plot1_click)
  })
  # output brushed points 
  output$brush_info <- renderPrint({
    brushedPoints(mapPoints, xvar="Longitude", 
                  yvar="Latitude", input$plot1_brush)
  })
}

shinyApp(ui, server)