原文地址:点击打开链接
R语言有着令人称赞的可视化能力,在这篇文章中,我们试着用R语言来展示地图数据,也就是绘制地图,并在地图上展示数据的分布。
由于R语言所带的中国地图过于老旧,因此我们通过寻找外部地图数据文件,并在R中载入并展示地图。
我们所用的地图数据文件是Shapefile格式的文件,它可以存储地理要素的几何位置和属性信息,Shapefile中的地理要素可通过点、线、面来表示。一个完整的shape文件由一组文件组成,其中必要的基本文件包括坐标文件(.shp),索引文件(.shx),属性文件(.dbf)三个文件,有时候还会出现特征空间索引文件(.sbn和.sbx)。地图数据文件下载地址)(http://cos.name/wpcontent/uploads/2009/07/chinaprovinceborderdata_tar_gz.zip),下载解压缩后,可以看到有三个文件,分别是bou2_4p.dbf,dou2_4p.shp,bou2_4p.shx,数字1~4分别代表国家、省、市、县的4级行政划分,字母p结尾的表示多边形数据,用来绘制区域,bou2表示是省级行政划分的边界。这份数据并不是最新的数据,最新的数据在国家基础地理信息中心找不到,大概要购买才能得到,不过对于一般的绘图而言,这份数据已经可以满足要求。
这篇文章绘制地图用到了3个包:sp,maptools,ggplot2。Sp包主要提供了操作地理信息数据的一些方。Maptools包提供了读入和操作地理信息数据的一些工具。ggplot2提供了数据可视化的功能。具体功能请查看各包附带文档。
> library(sp)
>library(maptools)#windows系统加载时都会提示以下信息,对绘制影响不大。
Checking rgeos availability:FALSE
Note: when rgeos is not available,polygon geometry computationsin maptools depend on gpclib,
which has a restricted licence. It isdisabled by default;
to enable gpclib, typegpclibPermit()
> library(ggplot2)
地图数据基本可以分为点、线、面三种数据,在maptools包内分别有对应的函数来读取(readShapePoints、readShapeLines和readShapePoly),这里我们采用readShapePoly函数。
> x <-readShapePoly(file.choose()) #读入bou2_4p.shp文件
> class(x) #x是sp包的数据框
[1] "SpatialPolygonsDataFrame"
attr(,"package")
[1] "sp"
> names(x)
[1] "AREA" "PERIMETER" "BOU2_4M_" "BOU2_4M_ID""ADCODE93"
[6] "ADCODE99" "NAME"
我们发现x包含了7类信息,其中AREA是地区,PERIMEIER是周长,NAME是中文名称。其他的是一些编码。我们采用ggplot2进行地图绘制,ggplot2绘制的对象格式为数据框,而x的格式为地理信息类数据框(class(x)),我们对其格式进行转换以满足ggplot2的绘制要求。
> china <-fortify(x)#将地理信息文件转换为data.frame格式数据
Regions defined for each Polygons
> head(china)
long lat order hole piece group id
1 121.4884 53.33265 1 FALSE 1 0.1 0
2 121.4995 53.33601 2 FALSE 1 0.1 0
3 121.5184 53.33919 3 FALSE 1 0.1 0
4 121.5391 53.34172 4 FALSE 1 0.1 0
5 121.5738 53.34818 5 FALSE 1 0.1 0
6 121.5840 53.34964 6 FALSE 1 0.1 0
转换后china数据包含7列数据,long表示精度,lat表示纬度。
现在我们就可以绘制原始的地图了。
> p <-ggplot(china,aes(x=long,y=lat))+geom_polygon(aes(group=id),fill=I("red"))
这样绘制的地图形状有些扁平,这是因为在绘制过程中,默认把经度和纬度作为普通的坐标,均匀平等对待,绘制在笛卡尔坐标系中。而地图应该绘制在专业的地理坐标图中,这一点在ggplot2中的coord_map()函数中体现出来,详情请?coor_map(),它有不同的投影方式。同时,图中的刻度线和坐标线也可以去掉,只显示地图。
> p1 <-p+theme(panel.background=element_rect(fill="lightblue"))+coord_map()
> p2 <-p1+theme(panel.grid=element_blank())
> p3 <-p2+theme(axis.title=element_blank())
> p4 <-p3+theme(axis.ticks=element_blank())
> p5 <-p4+theme(axis.text=element_blank())
> p6 <- p5 +theme(plot.background=element_rect(fill="lightblue"))+theme(legend.background=element_rect(fill="lightblue"))
> p6
最后,加个标题吧!
>p6+ggtitle(" 中国地图 ")
参考资料
1.Shapefile格式说明