1. 程式人生 > 其它 >R語言,你要怎樣畫地圖?

R語言,你要怎樣畫地圖?

不知道各位平常有沒有過需要畫地圖的需求,有的時候需要在地圖上標出特定位置的資料表現或者一些數值,然而怎麼實現?

這裡主要介紹下在R語言中繪製地圖的個人琢磨的思路。繪製地圖步驟有三:

  1. 你得需要繪製地圖;(約等於廢話)
  2. 你得有要繪製地圖的地理資訊,經緯度啊,邊界啊等等;
  3. 你得利用2的資料在R中畫出來。

以上步驟中,目前最關鍵的是2,一旦2的資料有了,在R中不就是把它們連起來嘛,這個對於R來說就是調戲它,就跟全民調戲小黃雞一樣。

R語言中繪製地圖的思路也是由於2的獲取方式不一樣而分開的。

第一種思路:有一些R包中儲存著常見地圖的資料,比如maps包中存有世界地圖、美國地圖、美國各州郡地圖、法國地圖以及加拿大城市地圖等,載入了這個包,就可以輕鬆愉快地繪製上述地圖。mapdata包中存有中國地圖的資料,但是比較舊了,這個資料,重慶還沒有從四川分出來呢。

總體來講,第一種思路受包中已有的資料數量限制(但我R包多!),如果各個包中都沒有梵蒂岡的資訊,那咋辦啊(其實可以通過繪製世界地圖,然後限制區域把梵蒂岡畫出來)。而且,如果我想畫中國人民大學的地圖怎麼辦???哭……

第二種思路:我先去一個地方下載所畫圖的地理資料,然後讀入R進行繪製。比如由於mapdata中的中國地圖比較久遠了,謝老大的《終於搞定中國分省市地圖》一文中就介紹了,先從國家基礎地理資訊中心下載中國各省市的地理資料,之後再繪製。後來肖凱老師又介紹googleVis包也可以按照這個思路來繪製地圖,具體可參考《利用googleVis包實現環境資料視覺化》(友情提示,需訪問外國網站)。之後的OpenStreetMap包也是提供了方便下載地理資料的途徑。

如您所看到的,第二種途徑的步驟稍多,不利於大家上手。我知道,如果過程越長,越艱辛,最終繪製出地圖的那一刻的快感就越強烈,但是“少折騰”的指示,還是提醒我們,儘量化繁為簡。於是第三種的思路,就是既繼承了第一種思路簡潔的操作方式,又吸取了第二種思路的資料來源廣泛的優勢。

第三種思路:既然R是自由的,那我能不能直接去調取專業的地圖企業或者網站的資料呢,這樣就不會受包中資料集所限,我只需要有一個途徑去專業的地圖供應商那取資料就可以了,比如Google Map,Baidu Map等,這可都是專業的地圖網站,裡面的地理資料應有盡有,想取啥取啥。自由的R只需要連線Google Map的API,一切就都有了,當然Google大爺不會讓你無限制的取資料,目前的限制是2000次(應該是單天的限制),於是ggmap包誕生了,兩位作者David Kahle和 Hadley Wickham真是太會解放全球人民了,並且該包中有幾個讓我無比激動的命令,下文見!!!

好,我們先來按照第一種思路來畫幾個圖:

1、 畫世界地圖

如果是首次使用,需要在R中裝載maps包(install.packages('maps')),這個包中存有世界地圖和美國地圖的地圖資料,所以,幾行程式碼便可以畫出世界地圖。

程式碼如下:

library(maps)
map("world", fill = TRUE, col = rainbow(200),
    ylim = c(-60, 90), mar = c(0, 0, 0, 0))
title("世界地圖")

輸出為:

無比絢麗的世界,引無數騷客競折腰啊……

2、 畫美國地圖

同樣在maps包中包含了美國地圖和美國各州郡的詳細地圖資料,同樣的,也可以用簡單的程式碼畫出美國地圖,便於我們使用。

程式碼如下:

library(maps)
map("state", fill = TRUE, col = rainbow(209),
    mar = c(0, 0, 2, 0))
title("美國地圖")

輸出為:

整體形狀這是像啥啊,山姆大叔……

對於美國地圖,該包提供畫出指定幾個州的圖,比如這裡只畫出New York, New Jersey, Penn三州的地圖:

程式碼如下:

library(maps)
map('state', region = c('new york', 'new jersey', 'penn'),
    fill = TRUE, col = rainbow(3), mar = c(2, 3, 4, 3))
title("美國三州地圖")

輸出結果為:

三州鼎力!!

3、 畫中國地圖

上述的maps包中並沒有中國地圖的資料 ,在另外一個包mapdata中有中國地圖的資料(比較舊的資料)。

程式碼如下:

library(maps)
library(mapdata)
map("china", col = "red4", ylim = c(18, 54), panel.first = grid())
title(" 中國地圖")

輸出為:

哭,重慶在哪裡,重慶在哪裡??

好,我們來強力介紹ggmap包,先來說下該包讓我驚訝的幾個命令:

1、geocode()

比如:

> geocode("Beijing")
       lon      lat
1 116.4075 39.90403

這大哥可以返回一個地方的經緯度,那我再調戲之:

> #這意思就是大哥你多給點!!
> geocode("Renmin University of China", output = "more")
       lon      lat              type     loctype
1 116.3184 39.96998 point_of_interest approximate
                                                                                address
1 renmin university of china, 59號 zhongguancun street, haidian, beijing, china, 100086
     north    south     east     west postal_code country
1 39.97853 39.96142 116.3345 116.3024      100086   china
  administrative_area_level_2 administrative_area_level_1 locality
1                        <NA>                     beijing  beijing
               street streetNo          point_of_interest
1 zhongguancun street       NA renmin university of china
                       query
1 Renmin University of China

資訊給多了,我說幾個點,不但有人民大學的經緯度,還有該大學的詳細地址(中國人民大學,中關村大街59號,海淀,北京,中國),還有郵編好吧100086!!!!但是好像跟我們實際的100872有差距(倒是跟10086很接近啊),但是它確實是返回了郵政編碼,還有zhongguancun street就不說了……這完全就是返回的Google地圖儲存的人民大學的資訊啊……

2、mapdist()

第二個顛顫顫的命令式mapdist()。比如:

> mapdist('China Agricultural University',
+     'Renmin University of China', 'walking')
                           from                         to    m    km
1 China Agricultural University Renmin University of China 6022 6.022
     miles seconds  minutes    hours
1 3.742071    4523 75.38333 1.256389

1 mile = 1609米。

這意思就是說從農大到人大距離6022米,如果您步行,需要4523秒……汗,我下次考慮下步行試試。不過,您說的是農大東校區還是農大西校區啊……

另,ggmap包中不僅僅可以調取Google Map的資料,還可以調取OpenStreetMap (‘osm’)、Stamen Maps (‘stamen’)和CloudMade maps (‘cloudmade’)。親,這夠用了吧。那地圖的表現形式也是個性化的,有’terrain’(地勢圖)、’satellite’(衛星圖)、’roadmap’(道路圖)和 ‘hybrid’(混合)等。您自個兒選。

其他的不談了,直接畫地圖:

1、中國地圖

library(ggmap)
library(mapproj)
## Google啊Google給我China的地圖資料吧
map <- get_map(location = 'China', zoom = 4)
ggmap(map)

於是:

我天朝雄赳赳,氣昂昂啊!!請注意左下角的Google logo!!

再來北京道路地圖:

#Google啊Google給我Beijing的公路地圖資料吧
map <- get_map(location = 'Beijing', zoom = 10, maptype = 'roadmap')
ggmap(map)

於是:

最後,我想看下大冬天的有沒有人在人民大學的各個樓頂上晒太陽浴:

## Google啊Google給我RUC的衛星地圖資料吧
map <- get_map(location = 'Renmin University of China', zoom = 14,
    maptype = 'satellite')
ggmap(map)

太不清楚了,根本看不清楚哪跟哪啊。就這麼著吧,我估計快夠當天限制數了。

最後來個正經的,借用肖凱老師編好的程式碼(肖老師的原文後面還有用謝老大animation包做的動態圖呢),從中國地震資料中心下載 2013.1.5-2013.1.11 這一週發生在中國的小地震,呃,應該都是小地震,因為沒有聽到相關的大地震的新聞報道。

從這圖上看,每週發生在我親愛的祖國上的地震真心不少啊,我大中國臺灣也飽受其苦啊。向天祈禱,讓地震少震我中國吧……

參考文獻: