2017-05-20 16:30:51
https://axismaps.github.io/thematic-cartography/images/cartogram_US_pop.jpg
Wikipedia: 地理信息系统(GIS)……是用于输入、存储、查询、分析和显示地理数据的计算机系统,可以分为以下五个部分…:人员,…数据,…硬件,…软件,…过程…
其中, GIS内部数据即空间数据(spatial data)
利用rgdal::readOGR
包读取 -> SpatialPolygonsDataFrame
df <- rgdal::readOGR("~/MAP_DTA/CHN_adm/CHN_adm0.shp") str(df)
..@ data : 'data.frame': 1 obs. of 70 variables: .. ..$ ID_0 : Factor w/ 1 level "49": 1 .. ..$ ISO : Factor w/ 1 level "CHN": 1 .. .. ... ..@ polygons :List of 1 .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots .. .. .. ..@ Polygons :List of 2013 .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots .. .. .. .. .. .. ..@ labpt : num [1:2] 109.7 18.2 .. .. .. .. .. .. ..@ area : num 1.75e-05 .. .. .. .. .. .. ..@ hole : logi FALSE .. .. .. .. .. .. ..@ ringDir: int 1 .. .. .. .. .. .. ..@ coords : num [1:61, 1:2] 110 110 110 110 110 ...
SpatialPolygonsDataFrame
类sp
包的标准地理数据类型,包含5个槽(slot,即属性)
CRS
类S4对象maps
、maptools
、sp
等包broom::tidy
转化为数据框broom::tidy
broom
包可以自动将统计分析对象转为数据框SpatialPolygonsDataFrame
转化后变成一个7列数据框,便于ggplot2
制图
head(broom::tidy(df))
long lat order hole piece group id 1 121.7179 39.44096 1 FALSE 1 0.1 0 2 121.7179 39.44181 2 FALSE 1 0.1 0 3 121.7182 39.44181 3 FALSE 1 0.1 0 4 121.7182 39.44236 4 FALSE 1 0.1 0 5 121.7185 39.44236 5 FALSE 1 0.1 0 6 121.7185 39.44320 6 FALSE 1 0.1 0
recharts::convCoord
进行偏置利用ggmap包,直接获取地图图块
library(ggmap) ggmap(get_map("shanghai", maptype="terrain"))
ggmap(get_map("shanghai", maptype="terrain-lines", source="stamen"))
maps
包library(maps) map("world")
sp
包支持的地图数据格式map(rgdal::readOGR( "CHN_adm/CHN_adm1.shp"))
ggplot2
包library(ggplot2) wmap <- map('world', plot=FALSE, fill=TRUE) wmap <- maptools::map2SpatialPolygons( wmap, IDs=wmap$names) wmap <- broom::tidy(wmap) ggplot()+geom_path( aes(long, lat, group=group), data=wmap)
sp
包支持的地图数据格式cmap <- rgdal::readOGR( "CHN_adm/CHN_adm1.shp") cmap <- broom::tidy(cmap) ggplot()+geom_path( aes(long, lat, group=group), data=cmap)
maps
map('state', region=c( 'new york', 'new jersey', 'penn')) txt <- data.frame( x=c(-76, -78, -74), y=c(42.5, 40.5, 40), txt=c("New York", "Pennsylvania", "New Jersey")) text(x=txt$x, y=txt$y, labels=txt$txt)
ggplot2
map <- map('state', plot=FALSE, fill=TRUE, region=c('new york', 'new jersey', 'penn')) map <- maptools::map2SpatialPolygons( map, IDs=map$names) ggplot() + coord_map() + geom_path( aes(long, lat, group=group), data=map) + geom_text(aes(x, y, label=txt), data=txt)
# 州级图层 map1 <- map('state', plot=FALSE, fill=TRUE) map1 <- maptools::map2SpatialPolygons( map1, IDs=map1$names) # 县级图层 map2 <- map('county', plot=FALSE, fill=TRUE) map2 <- maptools::map2SpatialPolygons( map2, IDs=map2$names) # 先画县级图层 p <- ggplot() + coord_map("cylindrical") + geom_polygon( aes(long, lat, group=group), data=map2, fill="gray", color="gray95", size=0.01) # 添加州级图层 p <- p + geom_path( aes(long, lat, group=group), data=map1, color="white", size=0.75) p
ggplot2
包group
关联底图,映射视觉通道maps
包一般不做底图,直接将数据映射到视觉通道,并展示为地图元素
美国失业数据集unemp和county.fips,在maps包中
data(unemp) data(county.fips)
分别看看各自的结构,以fips
关联
str(unemp)
## 'data.frame': 3218 obs. of 3 variables: ## $ fips : int 1001 1003 1005 1007 1009 ... ## $ pop : int 23288 81706 9703 8475 25306 ... ## $ unemp: num 9.7 9.1 13.4 12.1 9.9 16.4 ...
str(county.fips)
## 'data.frame': 3085 obs. of 2 variables: ## $ fips : int 1001 1003 1005 1007 1009 ... ## $ polyname: Factor w/ 3085 levels "alabama,autauga",..:
unemp.map <- merge(broom::tidy(map2), merge(unemp, county.fips, by="fips"), by.x="id", by.y="polyname", all.x=TRUE) str(unemp.map)
## 'data.frame': 87949 obs. of 10 variables: ## $ id : chr "alabama,autauga" "alabama,autauga" ... ## $ long : num -86.5 -86.5 -86.5 -86.6 -86.6 ... ## $ lat : num 32.3 32.4 32.4 32.4 32.4 ... ## $ order: int 1 2 3 4 5 6 7 8 9 10 ... ## $ hole : logi FALSE FALSE FALSE FALSE ... ## $ piece: Factor w/ 1 level "1": 1 1 1 1 1 1 ... ## $ group: Factor w/ 3085 levels "alabama,autauga.1",..: ## $ fips : int 1001 1001 1001 1001 1001 1001 ... ## $ pop : int 23288 23288 23288 23288 23288 ... ## $ unemp: Factor w/ 6 levels "<2%","2-4%","4-6%",..:
# 失业率分段 unemp.map$unemp <- cut(unemp.map$unemp, c( seq(0, 10, 2), 100), labels=c( "<2%", "2-4%", "4-6%", "6-8%", "8-10%", "10%+")) # 自定义颜色 colors <- c("#F1EEF6", "#D4B9DA", "#C994C7", "#DF65B0", "#DD1C77", "#980043") names(colors) <- c( "<2%", "2-4%", "4-6%", "6-8%", "8-10%", "10%+") # 作图,将底图叠在上方 ggplot() + coord_map("cylindrical") + geom_polygon(aes( long, lat, group=group, fill=unemp), data=unemp.map) + scale_fill_manual(values=colors) + geom_path( aes(long, lat, group=group), data=map2, color="gray95", size=0.01) + geom_path( aes(long, lat, group=group), data=map1, color="white", size=0.75) + labs(title="Unemployment by county, 2009")
fill=unemp
)用maps
实现上例
mar=c(0, 0, 1.1, 0) par(mar=mar) data(unemp) data(county.fips) # 定义色谱 colors = c("#F1EEF6", "#D4B9DA", "#C994C7", "#DF65B0", "#DD1C77", "#980043") unemp$colorBuckets <- as.numeric(cut(unemp$unemp, c(seq(0, 10, 2), 100))) leg.txt <- c("<2%", "2-4%", "4-6%", "6-8%", "8-10%", ">10%") # 州县名与地图定义匹配 cnty.fips <- county.fips$fips[match(map("county", plot=FALSE)$names, county.fips$polyname)] colorsmatched <- unemp$colorBuckets [match(cnty.fips, unemp$fips)] map("county", col = colors[colorsmatched], fill = TRUE, resolution = 0, lty = 0, projection = "polyconic", mar=mar) map("state", col = "white", fill = FALSE, add = TRUE, lty = 1, lwd = 0.2, projection="polyconic", mar=mar) title("Unemployment by county, 2009") legend("bottomright", leg.txt, horiz = TRUE, fill = colors, cex=0.8)
maps
实现人口气泡图
mar=c(0, 0, 1.1, 0) par(mar=mar) map("world", lty=0, fill=TRUE, col="gray", bg='lightblue1', mar=mar) map("world", lwd=0.01, col="white", add=TRUE, mar=mar) map("world", lwd=0.02, col="lightblue1", interior=FALSE, add=TRUE, mar=mar) map.cities(label=FALSE, minpop=100000, maxpop=199999, cex=0.1, pch=16, col='blue') map.cities(label=FALSE, minpop=200000, maxpop=499999, cex=0.2, pch=16, col='cyan') map.cities(label=FALSE, minpop=500000, maxpop=999999, cex=0.5, pch=16, col='green') map.cities(label=FALSE, minpop=1000000, maxpop=4999999, cex=1, pch=19, col='yellow') map.cities(label=FALSE, minpop=5000000, maxpop=9999999, cex=2, pch=19, col='orange') map.cities(label=FALSE, minpop=10000000, cex=5, pch=19, col='red') title("Big cities in the world, as of Jan 2016")
ggplot2
实现上例
# 底图和边界 wmap <- map("world", fill=TRUE, plot=FALSE) wmap <- maptools::map2SpatialPolygons(wmap, IDs=wmap$names) wmap.bou <- map("world", plot=FALSE, interior=FALSE) wmap.bou <- maptools::map2SpatialLines(wmap.bou) wmap.bou <- SpatialLinesDataFrame(wmap.bou, data=data.frame(ID=1:length(wmap.bou))) # 人口分段,映射颜色和尺寸 data(world.cities) world.cities <- subset(world.cities, pop>100000) world.cities$popl <- cut(world.cities$pop, 100000 * c(1000, 100, 50, 10, 5, 2, 1)) world.cities$popl <- factor(world.cities$popl, levels=rev(levels(world.cities$popl))) cols <- c('red', 'orange', 'yellow', 'green', 'cyan', 'blue') sizes <- c(5, 2, 1, 0.5, 0.2, 0.1) names(cols) <- names(sizes) <- levels(world.cities$popl) # 国界、海岸线底图,上覆数据层 ggplot() + geom_polygon(aes(long, lat, group=id), data=wmap, fill='gray', color="gray95", size=0.01) + geom_path(aes(long, lat, group=id), dat=wmap.bou, color="gray") + theme(panel.background=element_rect(fill="lightblue1"), legend.position="bottom") + geom_point(aes(long, lat, color=popl, size=popl), alpha=0.5,data=world.cities) + scale_color_manual(values=cols) + scale_size_manual(values=sizes, guide='none') + labs(title="Big cities in the world, as of Jan 2016")
ggplot2
实现地理柱形图
# 底图和边界 wmap <- map("world", fill=TRUE, plot=FALSE) wmap <- maptools::map2SpatialPolygons(wmap, IDs=wmap$names) wmap.bou <- map("world", plot=FALSE, interior=FALSE) wmap.bou <- maptools::map2SpatialLines(wmap.bou) wmap.bou <- SpatialLinesDataFrame(wmap.bou, data=data.frame(ID=1:length(wmap.bou))) # 人口分段,映射颜色和尺寸 data(world.cities) world.cities <- subset(world.cities, pop>100000) world.cities$popl <- cut(world.cities$pop, 100000 * c(1000, 100, 50, 10, 5, 2, 1)) world.cities$popl <- factor(world.cities$popl, levels=rev(levels(world.cities$popl))) cols <- c('red', 'orange', 'yellow', 'green', 'cyan', 'blue') sizes <- c(5, 2, 1, 0.5, 0.2, 0.1) names(cols) <- names(sizes) <- levels(world.cities$popl) # 国界、海岸线底图,上覆数据层 ggplot() + geom_polygon(aes(long, lat, group=id), data=wmap, fill='gray', color="gray95", size=0.01) + geom_path(aes(long, lat, group=id), dat=wmap.bou, color="gray") + theme(panel.background=element_rect(fill="lightblue1"), legend.position="bottom") + geom_linerange(aes(x=long, ymin=lat, ymax=lat+pop/500000, color=popl), stat='identity', alpha=0.5, size=1, data=world.cities) + scale_color_manual(values=cols, guide='none') + scale_size_manual(values=sizes, guide='none') + labs(title="Big cities in the world, as of Jan 2016")
Thank you!