多層次互動地圖

一講到地圖,大家腦海中出現的應該都是谷哥地圖(google map),但想要在網頁上呈現地圖,其實不是只有google map這個工具而已。

今天要為大家介紹一款套叫作 Leaflet 的套件,Leaflet 是一套適用於各種平台的JavaScript地圖繪製工具,它是一套開放原始碼的輕量級 JaveScript 網頁地圖函式庫,其呈現的效果與 google map 非常相似,主要特色是簡單、速度快,且可以跨平台使用,許多知名網站例如 GitHub 和 Flickr 都是使用 Leaflet 來呈現地圖。

底下的介紹會先簡單地示範些Leaflet的功能,然後再介紹比較完整的範例。

Leaflet 套件介紹

教學影片

  1. 首先我們先載入 leaflet 套件,如果沒有安裝該套件的話,請先將它安裝好再載入。

    install.packages("leaflet")
    library(leaflet)
    
  2. 建立 leaflet 物件,並逐一加入與地圖相關的屬性。底下的程式碼執行完成後會得到一張地圖,地圖上有個標籤標注在經度 120.239 緯度 22.992 這個位置。

    map <- leaflet()
    map <- addTiles(map)
    map <- addMarkers(map, lng = 120.239, lat = 22.992)
    map
    

    也可以透過 pipeline 來改寫上面的code。

    map <- leaflet() %>%
        addTiles() %>%
        addMarkers(lng = 120.239, lat = 22.992) 
    map
    
  3. leaflet 物件也可以直接讀取 data frame 裡面的欄位。如果沒有特別指定要讀取哪個欄位的資料,leaflet物件會自動去抓 data frame 中欄位名稱類似lat、long、latitude、longtitude的作為經緯度資料。

    point.df <- data.frame(
      Lat = 22.992 + rnorm(10)/800,
      Long = 120.239 + rnorm(10)/800)
      
    m <- leaflet(point.df) %>%
        addTiles() %>%
        setView(lng = 120.239, lat = 22.992, zoom = 17)
    m %>% addCircles()
    

    也可以透過公式的方式給 leaflet 物件明確的變數名稱。

    m <- leaflet() %>%
        addTiles() %>%
        setView(lng = 120.239, lat = 22.992, zoom = 17)
    m %>% addCircles( data = point.df, lng = ~Long, lat = ~Lat )
    

以上是對 leaflet 這個套件最基本的介紹,想要更深入了解的同學,請上 leaflet 的官網自行研習。

Yelp 評價資料實作

教學影片


該資料為Yelp上的店家評價資料,本範例的目標為建立一個多圖層的地圖,標示出資料中的所有店家,並依店家位置以叢集方式顯示。

  1. 載入套件及資料

    library(dplyr)
    library(leaflet)
    library(purrr)
    
    load("biz.rdata")
    
  2. 新增 group 欄位,該欄位用來儲存店家的資訊,該資訊用在點擊店家時的pop-up訊息,包括店家的網站、評價星星數、被評價次數、店家地址。
    在這邊我們沒有搜集所有店家的網站,所以網址暫時先用中山大學管理學院的網址代替。

    url = "'http://www.cm.nsysu.edu.tw'"
    biz$group <- paste(
        sprintf("<b><a href = %s>%s</a></b>", urlbiz$name),
        sprintf("Stars:%.1f, Reviews:$d", biz$star, biz$review),
        biz$address,
        sep = "<br/>"
    )
    
  3. 將店家被評價的次數分成7個區間,並新增 no.review 欄位儲存每個店家被評價的次數落在哪個區間。

    biz$no.review <- cut(biz$review ,c(0,5,10,50,100,200,400,900))
    
  4. 將原始資料依先前分的7個區間切成7組並存成 list,叫作 bx。

    bx <- split(biz ,biz$no.review)
    
  5. 接下來就可以建立地圖物件了,建立好地圖物件後,將每個區間的資料一組一組疊上去地圖上。
    將7組資料分次疊上去地圖物件的方式是透過 purrr 套件的 walk() 來執行,而walk()的原理是對輸入的vector內的每個值執行參數內的function。

    ## create map object
    l <- leaflet() %>% addTiles()
    
    names(bx) %>% 
        walk(function(df){
            l <<- l %>% 
                addMarkers(data=bx[[df]], 
                    lng=~longitude, 
                    lat=~latitude,
                    label=~name,
                    popup=~group,
                    group = df,
                    clusterOptions=markerClusterOptions(removeOutsideVisibleBounds=F),
                    labelOptions = labelOptions(noHide=F, direction='auto'))
            })
    
  6. 最後,將圖層的篩選加到地圖上。

    l %>% addLayersControl(
      overlayGroups = names(bx),
      options = layersControlOptions(collapsed = FALSE) )
    

以上就是將Yelp評價資料標注在地圖上的實作範例,可以發現 leaflet 這個套件相當方便,幾行程式碼就能做到很直覺的資料視覺化,希望各位同學喜歡這次的範例,下次見囉!