单击ShinyApp中的ggmap不会返回正确的坐标

时间:2015-09-26 18:42:53

标签: r ggplot2 shiny ggmap

如果我将点击事件附加到ShinyApp中的ggmap,然后点击地图,我就不会找回正确的坐标点。

以下应用程序绘制了一个包含某些点的地图,并将点击事件附加到地图上。我的目标是,当我点击这些点时,他们的数据(在这种情况下为lon / lat)应出现在outputId =“coords”verbatimTextOutput中。

app.R:

library(shiny);
library(ggmap);

# load data
points <- data.frame(lon=c(-122,-121.9,-121.8,-121.7),lat=c(37.2,37.2,37.2,37.2));
map <- get_map(location = c(lon = mean(points$lon),lat = mean(points$lat)),maptype="roadmap",scale=2, zoom =11)


ui <- fluidPage (
  plotOutput(outputId="mapOut",
             width="100%", height="500px",
             click = "plot_click"
  ),
  verbatimTextOutput(outputId="info"),
  verbatimTextOutput(outputId="coords")

)


server <- function(input,output) {

  output$mapOut <- renderPlot({
     mapPoints <-  ggmap(map) + geom_point(aes(x = lon, y = lat),size=8,colour="black", data=points);;
     mapPoints
  })

  output$info <- renderPrint({
    ptClicked <- nearPoints(points, coordinfo = input$plot_click, threshold = 10, maxpoints = 1, xvar="lon", yvar="lat");
    data.frame(lon=ptClicked$lon,lat=ptClicked$lat);

  })

  output$coords <- renderText({
    paste0("x=", input$plot_click$x, "\ny=", input$plot_click$y)
  })
}

shinyApp(server = server, ui = ui)

当我运行此应用程序时,点将显示在正确的位置。如果我直接点击一个点,输出$ info&lt; - ...中的nearPoints()不能正确识别该点。这是因为单击的返回坐标是错误的。 (正如您可以从“coords”逐字文本输出中看到的那样。)

如果我点击该点的右侧,从而在数据意义上使返回的点击坐标“在点上”,则返回该点。

问题类似于getting correct click coords with ggplot map in shiny,除非在这种情况下坐标以[0,1]中的数字返回;在我的情况下,坐标看起来像真正的坐标,但有点错误....从这个问题我也注意到,即使在使用lon&lt; - 400 * x - 200和lat&lt; - 200 * y - 100重新缩放之后坐标仍然偏离(例如(lon,lat)=(0,0)似乎映射到(8.9,5.4))。因此ggplot在用于映射时似乎面临同样的问题。

有没有办法点击ggmap / ggplot产生正确的坐标?这可能与预测有关。

如果没有,是否有不同的方法可以解决问题,以便正确点击这些点? (例如,一种解决方法可能是以某种方式捕获“就点击而言”(x,y)绘制点的位置,存储它们,并使用它们代替lon / lat用于nearPoints()目的...)

1 个答案:

答案 0 :(得分:2)

默认情况下,

ggmap()使用coord_map()中的ggplot2投影,这会扭曲坐标。要在Shiny中获得正确的单击坐标,您需要将其转回笛卡尔坐标。只需添加coord_cartesian()即可完成此操作。当coord_map()被剥离时,输出映射的宽高比可以是任意的。因此,您需要更改plotOutput()中的宽度和高度,以使地图仍然是一个不错的地图。

以下是上述小修改的代码。它产生正确的点击和漂亮的地图。

library(shiny);
library(ggmap);

# load data
points <- data.frame(lon=c(-122,-121.9,-121.8,-121.7),lat=c(37.2,37.2,37.2,37.2))
map <- get_map(location = c(lon = mean(points$lon),lat = mean(points$lat)),
               maptype="roadmap",scale=2, zoom =11)


ui <- fluidPage (
    plotOutput(outputId="mapOut",
               ##########################################################
               # force the ratio of the width and height so that the map
               # appears as square
               width=530, height=500,  
               click = "plot_click"
    ),
    verbatimTextOutput(outputId="info"),
    verbatimTextOutput(outputId="coords")

)


server <- function(input,output) {

    output$mapOut <- renderPlot({
        mapPoints <-  ggmap(map, extent = "normal") + 
            geom_point(aes(x = lon, y = lat),size=8,colour="black", data=points)
        #########################################################
        # add coord_cartesian() to strip coord_map() from ggmap()
        mapPoints + coord_cartesian()
    })

    output$info <- renderPrint({
        ptClicked <- nearPoints(points, coordinfo = input$plot_click, 
                                threshold = 10, maxpoints = 1, 
                                xvar="lon", yvar="lat");
        data.frame(lon=ptClicked$lon,lat=ptClicked$lat);

    })

    output$coords <- renderText({
        paste0("x=", input$plot_click$x, "\ny=", input$plot_click$y)
    })
}

shinyApp(server = server, ui = ui)