2016-08-06 9 views
2

私はユーザーがggplot2によって生成された世界地図上の地理的データ点を(this exampleのように)選択できるようにする、Shinyアプリケーションに取り組んでいます。光沢のあるクリック/ブラシは非デカルト座標では動作しませんか?

これは通常のcoord_cartesian座標系(マップを歪ませる)を使用すると機能しますが、より適切なcoord_map座標系を使用すると失敗します。クリック/ブラシイベントが投影後に正しい座標を受け取らないようです。私が回避したり、デカルト座標に戻すことなくこれを修正する方法はありますか?

あなたは、以下の実施例を見つけることができます。

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) 

感謝を!

答えて

1

ggplotを使用していくつかの解決策を試しましたが、plotOutput機能では取り上げられていないスケーリングに問題があります。ヘルプページ(http://shiny.rstudio.com/reference/shiny/latest/plotOutput.html)では、以下の点に注意してください。可能な場合は

plotOutputについて、座標は、データ空間にスケーリング送信されます。 (現時点では、ベースグラフィックスとggplot2によって生成されたプロットは、このスケーリングをサポートしますが、格子などで生成されたプロットはそうしません)。スケーリングが不可能な場合、生のピクセル座標が送信されます。 imageOutputの場合、座標は生のピクセル座標で送信されます。また

、ggplot2グラフィックス

、ggplotオブジェクトを返す必要がrenderPlotのコード。その代わりにコードがprint(p)のようなggplot2オブジェクトを印刷する場合、インタラクティブグラフィックスの座標はデータ空間に正しくスケーリングされません。

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) 
+0

おかげで、これは動作します!しかし、ggplot2を使用すると、世界のデータを1回だけ取得することができ、レンダリングが高速になりました(この例は、大きなアプリで複数回含まれています)。後で。あなたはマップを生成するのにかかる時間を改善できる方法を考えてもいいですか?再度、感謝します。 –

+0

これは、本来の 'ggplot'バージョンを' coord_map'なしで行うのと本質的に同じです。元のコードを使うこともできます。 – wch

+0

実際は違うようです。これは[base](https://cloud.githubusercontent.com/assets/14842133/17569676/3b4500d8-5f41-11e6-9358-20d888f6b99c.png)と[ggplot2](https:// cloud。 githubusercontent.com/assets/14842133/17569677/3b690bfe-5f41-11e6-900b-f63c6addb410.png)(ポイントは、マップ上のブラシ付き領域から右に選択されています)。ベースはggplot2が軸を再スケーリングしないので、歪みが増します(私はgithubの光沢のあるチームに問題を提出しました)。 –

関連する問題