
如何用R繪制地圖
本文主要包含三種繪制地圖的方法:繪制基礎(chǔ)地圖、基于空間數(shù)據(jù)格式(shapefile)繪制地圖以及如何調(diào)用百度地圖和谷歌地圖的數(shù)據(jù)來繪制地圖。
基礎(chǔ)地圖
方法
從map()包里獲取地圖數(shù)據(jù),用geom_polygon()(可以用顏色填充)或者geom_path()(不能填充)繪制。
#install.packages(“ggplot2″)
#install.packages(“maps”)
library(ggplot2)
library(maps) # 為了獲取數(shù)據(jù)
##
## # ATTENTION: maps v3.0 has an updated ‘world’ map. #
## # Many country borders and names have changed since 1990. #
## # Type ‘?world’ or ‘news(package=”maps”)’. See README_v3. #
# 美國地圖數(shù)據(jù)
states_map <- map_data(“state”)
head(states_map)
## long lat group order region subregion
## 1 -87.46201 30.38968 1 1 alabama
## 2 -87.48493 30.37249 1 2 alabama
## 3 -87.52503 30.37249 1 3 alabama
## 4 -87.53076 30.33239 1 4 alabama
## 5 -87.57087 30.32665 1 5 alabama
## 6 -87.58806 30.32665 1 6 alabama
# geom_polygon()
ggplot(states_map, aes(x=long,y=lat,group=group)) +
geom_polygon(fill=”white”,colour=”black”) +
labs(title = “USA Map”)
# 中國地圖
library(mapdata)
map(“china”, col = “red4″, ylim = c(18,54), panel.first = grid())
title(“China Map”)
# 世界地圖數(shù)據(jù)
world_map <- map_data(“world”)
head(world_map)
## long lat group order region subregion
## 1 -69.89912 12.45200 1 1 Aruba
## 2 -69.89571 12.42300 1 2 Aruba
## 3 -69.94219 12.43853 1 3 Aruba
## 4 -70.00415 12.50049 1 4 Aruba
## 5 -70.06612 12.54697 1 5 Aruba
## 6 -70.05088 12.59707 1 6 Aruba
#sort(unique(world_map$region))
# 繪制指定區(qū)域的地圖數(shù)據(jù)
# 繪制歐洲足球五大聯(lián)賽所在地
euro <- map_data(“world”, region = c(“UK”,”France”, “Spain”,”Germany”, “Italy”))
ggplot(euro, aes(x=long, y = lat, group=group,fill=region)) +
geom_polygon(colour=”black”) +
scale_fill_brewer(palette = “Set2″) +
scale_y_continuous(limits=c(40,60)) +
scale_x_continuous(limits=c(-25,25)) +
labs(title = ” Euorpe’s Big Five Football Leagues”)
繪制等值區(qū)域圖
當(dāng)我們創(chuàng)建一個地圖后,如果根據(jù)變量值對不同區(qū)域填充不同的顏色呢?
方法
很簡單,只要把變量值和地圖數(shù)據(jù)合并在一起,然后把一個變量映射到fill上就可以了。
head(USArrests) # 1973年的數(shù)據(jù)
## Murder Assault UrbanPop Rape
## Alabama 13.2 236 58 21.2
## Alaska 10.0 263 48 44.5
## Arizona 8.1 294 80 31.0
## Arkansas 8.8 190 50 19.5
## California 9.0 276 91 40.6
## Colorado 7.9 204 78 38.7
crimes <- data.frame(state= tolower(rownames(USArrests)), USArrests)
# 合并數(shù)據(jù)集
crime_map <- merge(states_map,crimes,by.x=”region”,by.y = “state”)
# head(crime_map)
library(plyr) # 加載數(shù)據(jù)清洗軟件包
##
## Attaching package: ‘plyr’
##
## The following object is masked from ‘package:maps':
##
## ozone
# 按照 group, order排序
crime_map <- arrange(crime_map,group,order)
# head(crime_map)
ggplot(crime_map, aes(x=long,y=lat, group = group, fill = Assault)) +
geom_polygon(colour = “black”) +
coord_map(“polyconic”) +
labs(title = “USA Map”)
# 更改配色
ggplot(crimes, aes(map_id = state, fill = Assault)) +
geom_map(map = states_map, colour = “black”) +
scale_fill_gradient(low=”#FFFFFF”, high = “#BB4444″) +
expand_limits(x = states_map$long, y = states_map$lat)
對于犯罪率這個指標(biāo),從上圖可以看出采用連續(xù)取值的方法無法很好地反映出信息,這時采用離散取值反而更容易解釋。
# 離散顏色標(biāo)度
qa <- quantile(crimes$Assault, c(0,0.2,0.4,0.6,0.8,1.0))
qa
## 0% 20% 40% 60% 80% 100%
## 45.0 98.8 135.0 188.8 254.2 337.0
# 新增一個分位數(shù)類別變量
crimes$Assault_q <- cut(crimes$Assault, qa, labels = c(“0-20%”, “20-40%”,”40-60%”,
“60-80%”, “80-100%”),
include.lowest = TRUE)
states <- ddply(states_map, .(region),summarise, lat = mean(lat,na.rm = TRUE),
long = mean(long,na.rm = TRUE))
crimes <- merge(crimes, states, by.x = “state”, by.y = “region”)
# 繪制離散分類地圖
p <- ggplot(crimes, aes(map_id = state, fill = Assault_q)) +
geom_map(map = states_map, colour = “black”) +
scale_fill_brewer(palette = “Set2″) +
expand_limits(x = states_map$long, y =states_map$lat) +
coord_map(“polyconic”) +
labs(fill=”Assault Rate\nPercentile”, title = “USA Map”)
p
# 加入州名對應(yīng)的標(biāo)簽
p + geom_text(aes(x=long,y=lat,label=state),size=3,colour=”black”) +
theme_bw() +
xlab(“l(fā)ong”) + ylab(“l(fā)at”)
# 如果你想去掉網(wǎng)格線和坐標(biāo)框,那么接著往下翻!
# 創(chuàng)建空白背景地圖
theme_clean <- function(base_size=12){
require(grid)
theme_grey(base_size)
theme(
axis.title = element_blank(),
axis.text = element_blank(),
panel.background = element_blank(),
panel.grid = element_blank(),
axis.ticks.length = unit(0, “cm”),
axis.ticks.margin = unit(0, “cm”),
panel.margin = unit(0, “l(fā)ines”),
plot.margin = unit(c(0,0,0,0), “l(fā)ines”),
complete = TRUE
)
}
p + theme_clean()
## Loading required package: grid
ESRI公司的Shapefile文件是描述空間數(shù)據(jù)的幾何和屬性特征的矢量數(shù)據(jù)結(jié)構(gòu)的一種格式。 一個Shapefile文件最少包括三個文件:主文件(.shp):存儲地理要素的幾何圖形的文件; 索引文件(.shx):存儲圖形要素與屬性信息索引的文件; dBASE表文件(*.dbf):存儲要素信息屬性的dBase表文件。
除此之外還有可選的文件包括:空間參考文件(.prj), 幾何體的空間索引文件(.sbn 和 .sbx), 只讀的Shapefiles的幾何體的空間索引文件(.fbn 和 .fbx), 列表中活動字段的屬性索引(.ain 和 .aih), 可讀寫Shapefile文件的地理編碼索引(.ixs), 可讀寫Shapefile文件的地理編碼索引(.mxs), dbf文件的屬性索引(.atx), 以XML格式保存元數(shù)據(jù)(.shp.xml), 用于描述.dbf文件的代碼頁,指明其使用的字符編碼的描述文件(*.cpg)。
需要注意的是,主文件是一個直接存取,變長記錄的文件,其中每個記錄描述一個實體的數(shù)據(jù),我們稱之為稱為shape。
下面這個網(wǎng)站中可以下載全球各個國家完整的shapefile格式數(shù)據(jù): shapefile數(shù)據(jù)下載網(wǎng)站
備注:慎用中國地圖數(shù)據(jù)!
方法
利用maptools()包中的readShapePoly()載入空間數(shù)據(jù)文件,用fortify()把數(shù)據(jù)轉(zhuǎn)化成數(shù)據(jù)框的格式,然后畫圖。
library(maptools)
## Loading required package: sp
## Checking rgeos availability: TRUE
setwd(“~/Desktop/dataset/map”)
# 載入空間數(shù)據(jù)并轉(zhuǎn)化成數(shù)據(jù)框
china_shp <- readShapePoly(“china/bou2_4p.shp”)
# 返回一個 SpatialPolygonsDataFrame 對象
# str(china_shp)
china_map <- fortify(china_shp)
## Regions defined for each Polygons
# 繪制中國地圖
p <- ggplot(china_map, aes(x = long, y = lat, group = group)) +
geom_path() +
labs(title = “China Map”)
# 繪制空白背景的地圖
p + theme_clean()
這里我們只利用了shapefile中最基本的邊界信息,還沒有對地理信息數(shù)據(jù)進(jìn)行更進(jìn)一步的分析。我們還可以將不同格式的地理數(shù)據(jù)整合起來,例如如何在上面的地圖上繪制出我國的鐵路、水系分布等內(nèi)容。
調(diào)用百度地圖和谷歌地圖的數(shù)據(jù)
接下來,我將介紹如何從百度地圖和谷歌地圖中獲取心儀的地圖數(shù)據(jù)信息。
百度地圖
library(devtools)
#install_github(“badbye/baidumap”)
library(baidumap)
# 隨便輸入幾個經(jīng)緯度坐標(biāo)
lon = matrix(c(117.93780, 24.55730, 117.93291, 24.57745, 117.23530, 24.64210,
117.05890, 24.74860), byrow=T, ncol=2)
# 將經(jīng)緯度坐標(biāo)轉(zhuǎn)換成真實地理信息
location = getLocation(lon, formatted = T)
location
## lon=117.9378;lat=24.5573 lon=117.93291;lat=24.57745
## “福建省廈門市海滄區(qū)坂南路” “福建省廈門市海滄區(qū)大溪路”
## lon=117.2353;lat=24.6421 lon=117.0589;lat=24.7486
## “福建省漳州市南靖縣” “福建省漳州市南靖縣X607″
# 獲取廈門大學(xué)經(jīng)緯度坐標(biāo),返回json格式文件
getCoordinate(‘廈門大學(xué)’) # json
## 廈門大學(xué)
## “{\”status\”:0,\”result\”:{\”location\”:{\”lng\”:118.10229694322,\”lat\”:24.442898974406},\”precise\”:0,\”confidence\”:30,\”level\”:\”商圈\”}}”
ad <- getCoordinate(‘廈門大學(xué)’, formatted = TRUE)
names(ad) <- NULL
# 繪制地圖
# 自己修改了一些參數(shù),并將修改后的package掛在github上,所以我選擇從github上安裝ggmap包。
# install_github(“fibears/ggmap”)
library(ggmap)
p <- getBaiduMap(“廈門市思明區(qū)”,zoom = 12)
## Map from URL : http://api.map.baidu.com/staticimage?width=400&height=400¢er=118.13453488213,24.468728076403&zoom=12&scale=2
ggmap(p) +
geom_point(aes(x=ad[1], y =ad[2]))
當(dāng)當(dāng)當(dāng),奇跡發(fā)生了——廈門大學(xué)位于海中央!這是因為谷歌地圖和百度地圖經(jīng)緯度坐標(biāo)存在一定的偏差, 而getBaiduMap()軟件包的作者利用了ggmap()包中坐標(biāo)轉(zhuǎn)換的思想,這導(dǎo)致最終繪制出來 的圖形不準(zhǔn)確。因此,我們還是考慮轉(zhuǎn)入谷歌陣營。
谷歌地圖
首先介紹一個概念:火星坐標(biāo)系統(tǒng)
火星坐標(biāo)系統(tǒng)是一種國家保密插件,也叫做加密插件或者加偏或者SM模組,其實就是對真實坐標(biāo)系統(tǒng)進(jìn)行人為的加偏處理,按照特殊的算法,將真實的坐標(biāo)加密成虛假的坐標(biāo),而這個加偏并不是線性的加偏,所以各地的偏移情況都會有所不同。而加密后的坐標(biāo)也常被人稱為火星坐標(biāo)系統(tǒng)。
所有的電子地圖、導(dǎo)航設(shè)備,都需要加入國家保密插件。第一步,地圖公司測繪地圖,測繪完成后,送到國家測繪局,將真實坐標(biāo)的電子地圖,加密成“火星坐標(biāo)”,這樣的地圖才是可以出版和發(fā)布的,然后才可以讓GPS公司處理。第二步,所有的GPS公司,只要需要汽車導(dǎo)航的,需要用到導(dǎo)航電子地圖的,都需要在軟件中加入國家保密算法,將COM口讀出來的真實的坐標(biāo)信號,加密轉(zhuǎn)換成國家要求的保密的坐標(biāo)。這樣,GPS導(dǎo)航儀和導(dǎo)航電子地圖就可以完全匹配,GPS也就可以正常工作了。
由于谷歌地圖被GFW屏蔽了,所以想調(diào)用其API需要翻墻。
主要有以下幾個步驟:
安裝SSLedge
在RStudio中更改proxy
首先,我們先簡單認(rèn)識下http和https:
http是普通超文本協(xié)議,其信息室明文傳送,而https就是安全超文本傳輸協(xié)議,需要證書和提供安全連接,https是嵌套了SSL加密的http連接,其內(nèi)容會由SSL先加密,然后再傳送。
為了更方便地使用網(wǎng)絡(luò),我將只使用https代理,對于Http類型的網(wǎng)站使用直接連接的方式。
# 查看信息
Sys.getenv()
# 兩種方式設(shè)置proxy
# 利用Sys.setenv()
Sys.setenv(https_proxy=”https://user:password@ip:port”)
# 修改.Renviron 文檔
接下來我們來看看如何調(diào)用谷歌地圖的API來繪圖。
# 可以直接在cran中下載package
# install_github(“fibears/ggmap”) # 自己修改了部分鏈接代碼,所以我選擇從github下載
# library(ggmap)
setwd(“~/Desktop/dataset/others”)
# 獲取坐標(biāo)及地圖數(shù)據(jù)
ad1 <- as.numeric(geocode(“福建省廈門市思明南路422″,source = “google”))
## Information from URL : https://maps.googleapis.com/maps/api/geocode/json?address=%E7%A6%8F%E5%BB%BA%E7%9C%81%E5%8E%A6%E9%97%A8%E5%B8%82%E6%80%9D%E6%98%8E%E5%8D%97%E8%B7%AF422&sensor=false
xmu <- get_map(“廈門市思明區(qū)”,zoom = 13, maptype = “roadmap”)
## Map from URL : https://maps.googleapis.com/maps/api/staticmap?center=%E5%8E%A6%E9%97%A8%E5%B8%82%E6%80%9D%E6%98%8E%E5%8C%BA&zoom=13&size=640×640&scale=2&maptype=roadmap&language=en-EN&sensor=false
## Information from URL : https://maps.googleapis.com/maps/api/geocode/json?address=%E5%8E%A6%E9%97%A8%E5%B8%82%E6%80%9D%E6%98%8E%E5%8C%BA&sensor=false
ggmap(xmu, extent = “normal”) +
geom_point(aes(x=ad1[1], y =ad1[2]))
需要注意的是,利用geocode函數(shù)檢索經(jīng)緯度數(shù)據(jù)時,最好選擇使用道路數(shù)據(jù),這樣可以提高檢索的準(zhǔn)確率。
最后引用肖凱大神博客中的一個案例:本例是從地震信息網(wǎng)獲取最近一周的地震數(shù)據(jù),得到其經(jīng)緯度,然后以散點形式繪制在google地圖上,同時也顯示地震發(fā)生的密度估計。
# 加載擴展包
# install.packages(“animation”)
# install.packages(“XML”)
library(ggmap)
library(animation)
library(XML)
# 從網(wǎng)頁上抓取數(shù)據(jù),并進(jìn)行清理
webpage <-‘http://data.earthquake.cn/datashare/globeEarthquake_csn.html’
tables <- readHTMLTable(webpage,stringsAsFactors = FALSE)
raw <- tables[[6]]
data <- raw[-1,c(‘V1′,’V3′,’V4′)]
names(data) <- c(‘date’,’lan’,’lon’)
data$lan <- as.numeric(data$lan)
data$lon <- as.numeric(data$lon)
data$date <- as.Date(data$date, “%Y-%m-%d”)
# 用ggmap包從google讀取地圖數(shù)據(jù),并將之前的數(shù)據(jù)標(biāo)注在地圖上。
ggmap(get_googlemap(center = ‘china’, zoom=4,maptype=’terrain’),extent=’device’) +
geom_point(data=data,aes(x=lon,y=lan),colour = ‘red’,alpha=0.7) +
stat_density2d(aes(x=lon,y=lan,fill=..level..,alpha=..level..),
size=2,bins=4,data=data,geom=’polygon’)+
theme(legend.position = “none”)
## Map from URL : https://maps.googleapis.com/maps/api/staticmap?center=china&zoom=4&size=640×640&scale=2&maptype=terrain&sensor=false
## Information from URL : https://maps.googleapis.com/maps/api/geocode/json?address=china&sensor=false
## Warning: Removed 47 rows containing non-finite values (stat_density2d).
## Warning: Removed 47 rows containing missing values (geom_point).
數(shù)據(jù)分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
SQL Server 中 CONVERT 函數(shù)的日期轉(zhuǎn)換:從基礎(chǔ)用法到實戰(zhàn)優(yōu)化 在 SQL Server 的數(shù)據(jù)處理中,日期格式轉(zhuǎn)換是高頻需求 —— 無論 ...
2025-09-18MySQL 大表拆分與關(guān)聯(lián)查詢效率:打破 “拆分必慢” 的認(rèn)知誤區(qū) 在 MySQL 數(shù)據(jù)庫管理中,“大表” 始終是性能優(yōu)化繞不開的話題。 ...
2025-09-18CDA 數(shù)據(jù)分析師:表結(jié)構(gòu)數(shù)據(jù) “獲取 - 加工 - 使用” 全流程的賦能者 表結(jié)構(gòu)數(shù)據(jù)(如數(shù)據(jù)庫表、Excel 表、CSV 文件)是企業(yè)數(shù)字 ...
2025-09-18DSGE 模型中的 Et:理性預(yù)期算子的內(nèi)涵、作用與應(yīng)用解析 動態(tài)隨機一般均衡(Dynamic Stochastic General Equilibrium, DSGE)模 ...
2025-09-17Python 提取 TIF 中地名的完整指南 一、先明確:TIF 中的地名有哪兩種存在形式? 在開始提取前,需先判斷 TIF 文件的類型 —— ...
2025-09-17CDA 數(shù)據(jù)分析師:解鎖表結(jié)構(gòu)數(shù)據(jù)特征價值的專業(yè)核心 表結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 規(guī)范存儲的結(jié)構(gòu)化數(shù)據(jù),如數(shù)據(jù)庫表、Excel 表、 ...
2025-09-17Excel 導(dǎo)入數(shù)據(jù)含缺失值?詳解 dropna 函數(shù)的功能與實戰(zhàn)應(yīng)用 在用 Python(如 pandas 庫)處理 Excel 數(shù)據(jù)時,“缺失值” 是高頻 ...
2025-09-16深入解析卡方檢驗與 t 檢驗:差異、適用場景與實踐應(yīng)用 在數(shù)據(jù)分析與統(tǒng)計學(xué)領(lǐng)域,假設(shè)檢驗是驗證研究假設(shè)、判斷數(shù)據(jù)差異是否 “ ...
2025-09-16CDA 數(shù)據(jù)分析師:掌控表格結(jié)構(gòu)數(shù)據(jù)全功能周期的專業(yè)操盤手 表格結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 存儲的結(jié)構(gòu)化數(shù)據(jù),如 Excel 表、數(shù)據(jù) ...
2025-09-16MySQL 執(zhí)行計劃中 rows 數(shù)量的準(zhǔn)確性解析:原理、影響因素與優(yōu)化 在 MySQL SQL 調(diào)優(yōu)中,EXPLAIN執(zhí)行計劃是核心工具,而其中的row ...
2025-09-15解析 Python 中 Response 對象的 text 與 content:區(qū)別、場景與實踐指南 在 Python 進(jìn)行 HTTP 網(wǎng)絡(luò)請求開發(fā)時(如使用requests ...
2025-09-15CDA 數(shù)據(jù)分析師:激活表格結(jié)構(gòu)數(shù)據(jù)價值的核心操盤手 表格結(jié)構(gòu)數(shù)據(jù)(如 Excel 表格、數(shù)據(jù)庫表)是企業(yè)最基礎(chǔ)、最核心的數(shù)據(jù)形態(tài) ...
2025-09-15Python HTTP 請求工具對比:urllib.request 與 requests 的核心差異與選擇指南 在 Python 處理 HTTP 請求(如接口調(diào)用、數(shù)據(jù)爬取 ...
2025-09-12解決 pd.read_csv 讀取長浮點數(shù)據(jù)的科學(xué)計數(shù)法問題 為幫助 Python 數(shù)據(jù)從業(yè)者解決pd.read_csv讀取長浮點數(shù)據(jù)時的科學(xué)計數(shù)法問題 ...
2025-09-12CDA 數(shù)據(jù)分析師:業(yè)務(wù)數(shù)據(jù)分析步驟的落地者與價值優(yōu)化者 業(yè)務(wù)數(shù)據(jù)分析是企業(yè)解決日常運營問題、提升執(zhí)行效率的核心手段,其價值 ...
2025-09-12用 SQL 驗證業(yè)務(wù)邏輯:從規(guī)則拆解到數(shù)據(jù)把關(guān)的實戰(zhàn)指南 在業(yè)務(wù)系統(tǒng)落地過程中,“業(yè)務(wù)邏輯” 是連接 “需求設(shè)計” 與 “用戶體驗 ...
2025-09-11塔吉特百貨孕婦營銷案例:數(shù)據(jù)驅(qū)動下的精準(zhǔn)零售革命與啟示 在零售行業(yè) “流量紅利見頂” 的當(dāng)下,精準(zhǔn)營銷成為企業(yè)突圍的核心方 ...
2025-09-11CDA 數(shù)據(jù)分析師與戰(zhàn)略 / 業(yè)務(wù)數(shù)據(jù)分析:概念辨析與協(xié)同價值 在數(shù)據(jù)驅(qū)動決策的體系中,“戰(zhàn)略數(shù)據(jù)分析”“業(yè)務(wù)數(shù)據(jù)分析” 是企業(yè) ...
2025-09-11Excel 數(shù)據(jù)聚類分析:從操作實踐到業(yè)務(wù)價值挖掘 在數(shù)據(jù)分析場景中,聚類分析作為 “無監(jiān)督分組” 的核心工具,能從雜亂數(shù)據(jù)中挖 ...
2025-09-10統(tǒng)計模型的核心目的:從數(shù)據(jù)解讀到?jīng)Q策支撐的價值導(dǎo)向 統(tǒng)計模型作為數(shù)據(jù)分析的核心工具,并非簡單的 “公式堆砌”,而是圍繞特定 ...
2025-09-10