前几天帮人用R语言画个一个河北省的地图,河北省各个市被填充上颜色,颜色的深浅和这个市的GDP有关系,效果如下:
然后加上各个城市的名字并加上指北针、再把背景的网格去掉,效果如下:
library(rgdal)
library(ggplot2)
library(maptools)
library(mapproj)
library(ggsn)
当然你还要安装sf
包,这个包非常重要,用ggplot2画地图必不可少。还要安装readxl
包,这个包是用来读取excel表格的(可以读取xlsx,或者xls表格)。
show_data <- readxl::read_xlsx("河北省各市GDP增长率.xlsx")
show_data数据框包含河北省各个地方的GDP,这个数据长得是这样的:
shp_data <- sf::st_read("./CHN_adm/CHN_adm2.shp")
这个数据是地理信息数据,从CHN_adm文件夹里面读取的,长成这样的:
仔细看一下shp_data
里面有两个变量要注意,geometry
是包含各个市的地理信息位置,没有这一列,ggplot2
就不会画地图,NL_NAME_2
是各个市的中文名字。
show_data
和shp_data
进行关联。也很简单,再仔细看一下,show_data
就这几个城市,我们将这几个城市和shp_data
关联就可以;具体如下:(下面的代码是不完全正确)
my_data <- dplyr::left_join(show_data, shp_data,by = c("城市" = "NL_NAME_2"))
在你进行上面的代码运行的时候,你会发现一个问题,就是show_data
的城市
变量是字符串型,而shp_data
的NL_NAME_2
是因子型,你要将shp_data
的NL_NAME_2
转换成字符串型。然后再合并,不然就会有下面的错误:
所以正确的转换如下:(其实转换不转换也都一样,效果上是一样的,但是没有了警告。这样不是很完美么。
shp_data$NL_NAME_2 <- as.character(shp_data$NL_NAME_2)
my_data <- dplyr::left_join(show_data, shp_data,by = c("城市" = "NL_NAME_2"))
dplyr::left_join
的意思是使用dplyr
包的left_join
函数。这样就不用加载完全加载这个包了。left_join
意思是做连接,按照左边的表进行关联,这样不管你右边的表有多少行,最后只是根据你左边的数据框,也就是show_data
,合并规则就是by = c("城市" = "NL_NAME_2")
按照,左边的数据框的城市
和右边数据框的NL_NAME_2
,这两列进行比较。(这个我写的比较浅,可以看一下别人写的介绍,多用一用就熟悉了。
my_data
长得就是下面的样子:
ggplot(data = my_data) geom_sf(aes(fill = `GDP生产总值`))
很多人直接使用这样的代码,其实我刚开始也是,但是效果不理想(出现错误,其实大部分都是可以的,我也不知道怎么回事,错误如下:
> ggplot(data = my_data) geom_sf(aes(fill = `GDP生产总值`))
错误: stat_sf requires the following missing aesthetics: geometry
这个意思就是说你要指定my_data
数据里面的那一列是地理信息数据,很明显,就是geometry
这一列:
把代码改成如下就可以了:
ggplot(data = my_data) geom_sf(aes(fill = `GDP生产总值`, geometry = `geometry`))
但是很多人不认识哪一个区域叫什么市,所以要给区域加标签,因为刚开始做的比较着急,没想到使用sf
的一些神奇的函数,我就自己观察上面的图,然后自己找坐标,通过geom_text
来加标签,现在回头看,好傻!!!
先把我当时写的代码放出来:
label_city <- data.frame(x = c(114.5,118,115,119.2,118.3,116.5,115,
116.8,115.8, 114.9, 114.5),
y = c(38,41,41,40,40,39.3,39,
38, 37.9, 37.2, 36.5))
label_city['city'] <- my_data$城市
#
# [1] "石家庄市" "承德市" "张家口市" "秦皇岛市" "唐山市" "廊坊市" "保定市"
# [8] "沧州市" "衡水市" "邢台市" "邯郸市"
ggplot(data = my_data) geom_sf(aes(fill = `GDP生产总值`, geometry = `geometry`))
geom_text(data = label_city, aes(x = x, y = y, label = city), color = 'red')
画出来的图如下:
其实也可以,但是当城市比较多的时候,就不行了,因为我不可能一个一个去查城市的坐标是多少。
改进后的代码如下:
library(sf)
ggplot(data = my_data) geom_sf(aes(fill = `GDP生产总值`, geometry = `geometry`))
geom_sf_text(aes(label = `城市`,geometry = `geometry`), color = 'red')
上面的那个地理信息文件夹内容如下:
其实都在gadm2这个网站上,网站如下:https://gadm.org/
可以免费下载:
github: **https://github.com/yuanzhoulvpi2017/plot_data/tree/master/hebei_province_gdp