数模技巧不用for循环且使用ggplot2实现地图上连线

目录

  • 1. 前文回顾
    • 背景图像
  • 2. 利用ggplot2连接多个点
    • 1) 现有数据
    • 2) 数据预处理
    • 3) 绘图
    • 4) 结果展示
最近由于自己的时间关系,很久没有发一些干货了。这次想谈谈之前我们在进行数学建模时,如何将设计好的最优路径,利用ggplot2在地图上进行绘制与展示。
最简单的方法是使用plot绘图,然后再使用lines函数一条一条地将线加上去,但是一条一条加上去的过程中,需要使用for循环不说,而且绘制出来的图相对也没那么美腻。
下面我们讲一讲使用ggplot2且不使用for循环,如何快速便捷地完成这样的操作。

1. 前文回顾 首先可以回顾一下,在没有梯子的前提下,我们是如何利用ggplot2绘制一个较为好看的中国地图:利用R绘制漂亮的中国地图(无需通过google获取)。
下面我们基于前面绘制的中国地图,根据计算(最小生成树算法,之后有时间在说说这个,不过目前网上说的很详细了,而且也有很多代码)得到的相应连线贴到我们的图上。

背景图像
数模技巧不用for循环且使用ggplot2实现地图上连线
文章图片


2. 利用ggplot2连接多个点 我们需要选定其中几个点,并将其进行连线。下面是我们最终想要达到的效果(之前的图使用Mac画的,下面这个是Windows,可能质感有些不一样,望大家理解):
数模技巧不用for循环且使用ggplot2实现地图上连线
文章图片

为了达到这样的效果,我们主要是需要将数据集整理成可以能够舒适绘制的方式。利用ggplot2绘图,整理数据集要占80%以上的工作。

1) 现有数据
我们的最终目的是连33条线,所以先将需要连的线均一组一组地罗列而出(每个city都对应着一组经纬度,相应地是地图上的一个点)。
(前面的最终效果图是前11组城市连线)
下面的数据我们命名为:city_pair
city1city21北京&天津上海2上海 广州&深圳3广州&深圳重庆4重庆成都5重庆西安6北京&天津哈尔滨7北京&天津武汉8武汉郑州9重庆昆明10 北京&天津乌鲁木齐11 北京&天津拉萨12郑州西安13武汉重庆14 北京&天津郑州15 北京&天津西安16郑州重庆17 北京&天津重庆18武汉 广州&深圳19上海武汉20上海郑州21 北京&天津 广州&深圳22上海重庆23昆明 广州&深圳24武汉成都25郑州成都26西安成都27 北京&天津成都28成都昆明29西安武汉30成都 广州&深圳31上海成都32哈尔滨重庆33哈尔滨 广州&深圳

所以我们还需要对应城市经纬度及人口信息,这里的对象为mat.cities,它长这样:(这部分的数据生成也在我们前面的博客中有提及)
nameslatlong population1北京&天津 39.90420 116.4074032.55062上海 31.23039 121.4737023.01913郑州 34.74725 113.624938.62654乌鲁木齐 43.8266087.616843.11035哈尔滨 45.80218 126.5358210.63606西安 34.34126 108.939828.46787武汉 30.59276 114.305249.78548成都 30.57022 104.0647714.04769拉萨 29.6441191.114450.559410重庆 29.56470 106.5507128.846211昆明 24.87966 102.833216.432012 广州&深圳 23.02067 113.7517823.0587

有了这样两份原始数据,我们就可以开始进行绘图了。
首先是需要将数据整理成能够进行绘图的,为了方便操作,我们直接对原本的33组城市对进行操作。下面是数据预处理的过程。(由于当时数模时间有限,而数据量也不是很大,所以下面采用了大量的for循环,希望大家在用R时还是尽可能多用向量化操作,少用for循环)

2) 数据预处理
预处理代码如下:
dat_plot = matrix(nrow = 66, ncol = 4)k = 0for (i in 1:33) {for (j in 1:2) {k = k + 1my.row = mat.cities[city_pair[i, j] == mat.cities$names, ]dat_plot[k, 1] = unlist(my.row[1])dat_plot[k, 2] = unlist(my.row[2])dat_plot[k, 3] = unlist(my.row[3])dat_plot[k, 4] = i}}colnames(dat_plot) = c('地区', 'lat', 'long', 'group')dat_plot = as.data.frame(dat_plot)dat_plot$lat = as.numeric(as.character(dat_plot$lat))dat_plot$long = as.numeric(as.character(dat_plot$long))

这里我们的主要思路是:将配对的一组城市变为拆分成两组,然后再在最后添加一个group变量,主要是用于连线(两个城市如果在一个相同的group中,使用ggplot绘图中的参数group即可将两个点连接起来)。
在生成完想要的数据集后,记得将经纬度调整为数值型,group直接为factor即可。
最后我们得到的数据dat_plot长下面这样:
地区latlong group1北京&天津 39.90420 116.4074012上海 31.23039 121.4737013上海 31.23039 121.4737024广州&深圳 23.02067 113.7517825广州&深圳 23.02067 113.7517836重庆 29.56470 106.5507137重庆 29.56470 106.5507148成都 30.57022 104.0647749重庆 29.56470 106.55071510西安 34.34126 108.93982511 北京&天津 39.90420 116.40740612哈尔滨 45.80218 126.53582613 北京&天津 39.90420 116.40740714武汉 30.59276 114.30524715武汉 30.59276 114.30524816郑州 34.74725 113.62493817重庆 29.56470 106.55071918昆明 24.87966 102.83321919 北京&天津 39.90420 116.407401020乌鲁木齐 43.8266087.616841021 北京&天津 39.90420 116.407401122拉萨 29.6441191.114451123郑州 34.74725 113.624931224西安 34.34126 108.939821225武汉 30.59276 114.305241326重庆 29.56470 106.550711327 北京&天津 39.90420 116.407401428郑州 34.74725 113.624931429 北京&天津 39.90420 116.407401530西安 34.34126 108.939821531郑州 34.74725 113.624931632重庆 29.56470 106.550711633 北京&天津 39.90420 116.407401734重庆 29.56470 106.550711735武汉 30.59276 114.305241836 广州&深圳 23.02067 113.751781837上海 31.23039 121.473701938武汉 30.59276 114.305241939上海 31.23039 121.473702040郑州 34.74725 113.624932041 北京&天津 39.90420 116.407402142 广州&深圳 23.02067 113.751782143上海 31.23039 121.473702244重庆 29.56470 106.550712245昆明 24.87966 102.833212346 广州&深圳 23.02067 113.751782347武汉 30.59276 114.305242448成都 30.57022 104.064772449郑州 34.74725 113.624932550成都 30.57022 104.064772551西安 34.34126 108.939822652成都 30.57022 104.064772653 北京&天津 39.90420 116.407402754成都 30.57022 104.064772755成都 30.57022 104.064772856昆明 24.87966 102.833212857西安 34.34126 108.939822958武汉 30.59276 114.305242959成都 30.57022 104.064773060 广州&深圳 23.02067 113.751783061上海 31.23039 121.473703162成都 30.57022 104.064773163哈尔滨 45.80218 126.535823264重庆 29.56470 106.550713265哈尔滨 45.80218 126.535823366 广州&深圳 23.02067 113.7517833


3) 绘图
下面我们的核心绘图代码如下,想要连接不同的线,我们只是变了数据中选取的行,如:dat_plot[1:22, ]
## 11线ggplot() + geom_path(data = https://www.it610.com/article/china, aes(long, lat, group = group), color ='#FD9FA4', show.legend = F) +geom_point(data = https://www.it610.com/article/mat.cities, aes(x = long, y = lat, size = population), alpha = 0.8, color ='#8BB6D6') +geom_line(data = https://www.it610.com/article/dat_plot[1:22, ], aes(long, lat, group = group), size = 1, alpha = 0.8, color ='#8BB6D6') +geom_text_repel(data = https://www.it610.com/article/mat.cities, aes(x = long, y = lat, label = names), family ="STHeiti") +labs(x = '经度', y = '纬度', title = '十一条连线', size = '人口(百万)') + theme_bw() +theme(panel.border = element_blank(),text = element_text(family = "STHeiti"),plot.title = element_text(hjust = 0.5))## 16线ggplot() + geom_path(data = https://www.it610.com/article/china, aes(long, lat, group = group), color ='#FD9FA4', show.legend = F) +geom_point(data = https://www.it610.com/article/mat.cities, aes(x = long, y = lat, size = population), alpha = 0.8, color ='#8BB6D6') +geom_line(data = https://www.it610.com/article/dat_plot[1:32, ], aes(long, lat, group = group), size = 1, alpha = 0.8, color ='#8BB6D6') +geom_text_repel(data = https://www.it610.com/article/mat.cities, aes(x = long, y = lat, label = names), family ="STHeiti") +labs(x = '经度', y = '纬度', title = '十六条连线', size = '人口(百万)') + theme_bw() +theme(panel.border = element_blank(),text = element_text(family = "STHeiti"),plot.title = element_text(hjust = 0.5))## 33线ggplot() + geom_path(data = https://www.it610.com/article/china, aes(long, lat, group = group), color ='#FD9FA4', show.legend = F) +geom_point(data = https://www.it610.com/article/mat.cities, aes(x = long, y = lat, size = population), alpha = 0.8, color ='#8BB6D6') +geom_line(data = https://www.it610.com/article/dat_plot[1:66, ], aes(long, lat, group = group), size = 1, alpha = 0.8, color ='#8BB6D6') +geom_text_repel(data = https://www.it610.com/article/mat.cities, aes(x = long, y = lat, label = names), family ="STHeiti") +labs(x = '经度', y = '纬度', title = '三十三条连线', size = '人口(百万)') + theme_bw() +theme(panel.border = element_blank(),text = element_text(family = "STHeiti"),plot.title = element_text(hjust = 0.5))

绘图过程没有什么好说的了,里面使用的函数与方法都在前面的博客中提及过:
R语言学习ggplot2绘制统计图形包全面详解
【数模技巧不用for循环且使用ggplot2实现地图上连线】唯一添加的连线所使用的函数:geom_line,里面只需注意多了一个参数group,记得添加即可。

4) 结果展示
最后的16条连线与33条连线的效果图分别如下所示:
16条连线:
数模技巧不用for循环且使用ggplot2实现地图上连线
文章图片

33条连线:
数模技巧不用for循环且使用ggplot2实现地图上连线
文章图片

以上就是数模技巧ggplot2不用for循环实现地图上连线的详细内容,更多关于ggplot2在地图上连线数模技巧的资料请关注脚本之家其它相关文章!

    推荐阅读