數(shù)模技巧不用for循環(huán)且使用ggplot2實(shí)現(xiàn)地圖上連線(xiàn)
最近由于自己的時(shí)間關(guān)系,很久沒(méi)有發(fā)一些干貨了。這次想談?wù)勚拔覀冊(cè)谶M(jìn)行數(shù)學(xué)建模時(shí),如何將設(shè)計(jì)好的最優(yōu)路徑,利用ggplot2在地圖上進(jìn)行繪制與展示。
最簡(jiǎn)單的方法是使用plot繪圖,然后再使用lines函數(shù)一條一條地將線(xiàn)加上去,但是一條一條加上去的過(guò)程中,需要使用for循環(huán)不說(shuō),而且繪制出來(lái)的圖相對(duì)也沒(méi)那么美膩。
下面我們講一講使用ggplot2且不使用for循環(huán),如何快速便捷地完成這樣的操作。
1. 前文回顧
首先可以回顧一下,在沒(méi)有梯子的前提下,我們是如何利用ggplot2繪制一個(gè)較為好看的中國(guó)地圖:利用R繪制漂亮的中國(guó)地圖(無(wú)需通過(guò)google獲取)。
下面我們基于前面繪制的中國(guó)地圖,根據(jù)計(jì)算(最小生成樹(shù)算法,之后有時(shí)間在說(shuō)說(shuō)這個(gè),不過(guò)目前網(wǎng)上說(shuō)的很詳細(xì)了,而且也有很多代碼)得到的相應(yīng)連線(xiàn)貼到我們的圖上。
背景圖像

2. 利用ggplot2連接多個(gè)點(diǎn)
我們需要選定其中幾個(gè)點(diǎn),并將其進(jìn)行連線(xiàn)。下面是我們最終想要達(dá)到的效果(之前的圖使用Mac畫(huà)的,下面這個(gè)是Windows,可能質(zhì)感有些不一樣,望大家理解):

為了達(dá)到這樣的效果,我們主要是需要將數(shù)據(jù)集整理成可以能夠舒適繪制的方式。利用ggplot2繪圖,整理數(shù)據(jù)集要占80%以上的工作。
1) 現(xiàn)有數(shù)據(jù)
我們的最終目的是連33條線(xiàn),所以先將需要連的線(xiàn)均一組一組地羅列而出(每個(gè)city都對(duì)應(yīng)著一組經(jīng)緯度,相應(yīng)地是地圖上的一個(gè)點(diǎn))。
(前面的最終效果圖是前11組城市連線(xiàn))
下面的數(shù)據(jù)我們命名為:city_pair
city1 city2
1 北京&天津 上海
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 哈爾濱 廣州&深圳
所以我們還需要對(duì)應(yīng)城市經(jīng)緯度及人口信息,這里的對(duì)象為mat.cities,它長(zhǎng)這樣:(這部分的數(shù)據(jù)生成也在我們前面的博客中有提及)
names lat long population
1 北京&天津 39.90420 116.40740 32.5506
2 上海 31.23039 121.47370 23.0191
3 鄭州 34.74725 113.62493 8.6265
4 烏魯木齊 43.82660 87.61684 3.1103
5 哈爾濱 45.80218 126.53582 10.6360
6 西安 34.34126 108.93982 8.4678
7 武漢 30.59276 114.30524 9.7854
8 成都 30.57022 104.06477 14.0476
9 拉薩 29.64411 91.11445 0.5594
10 重慶 29.56470 106.55071 28.8462
11 昆明 24.87966 102.83321 6.4320
12 廣州&深圳 23.02067 113.75178 23.0587
有了這樣兩份原始數(shù)據(jù),我們就可以開(kāi)始進(jìn)行繪圖了。
首先是需要將數(shù)據(jù)整理成能夠進(jìn)行繪圖的,為了方便操作,我們直接對(duì)原本的33組城市對(duì)進(jìn)行操作。下面是數(shù)據(jù)預(yù)處理的過(guò)程。(由于當(dāng)時(shí)數(shù)模時(shí)間有限,而數(shù)據(jù)量也不是很大,所以下面采用了大量的for循環(huán),希望大家在用R時(shí)還是盡可能多用向量化操作,少用for循環(huán))
2) 數(shù)據(jù)預(yù)處理
預(yù)處理代碼如下:
dat_plot = matrix(nrow = 66, ncol = 4)
k = 0
for (i in 1:33) {
for (j in 1:2) {
k = k + 1
my.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('地區(qū)', '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))
這里我們的主要思路是:將配對(duì)的一組城市變?yōu)椴鸱殖蓛山M,然后再在最后添加一個(gè)group變量,主要是用于連線(xiàn)(兩個(gè)城市如果在一個(gè)相同的group中,使用ggplot繪圖中的參數(shù)group即可將兩個(gè)點(diǎn)連接起來(lái))。
在生成完想要的數(shù)據(jù)集后,記得將經(jīng)緯度調(diào)整為數(shù)值型,group直接為factor即可。
最后我們得到的數(shù)據(jù)dat_plot長(zhǎng)下面這樣:
地區(qū) lat long group
1 北京&天津 39.90420 116.40740 1
2 上海 31.23039 121.47370 1
3 上海 31.23039 121.47370 2
4 廣州&深圳 23.02067 113.75178 2
5 廣州&深圳 23.02067 113.75178 3
6 重慶 29.56470 106.55071 3
7 重慶 29.56470 106.55071 4
8 成都 30.57022 104.06477 4
9 重慶 29.56470 106.55071 5
10 西安 34.34126 108.93982 5
11 北京&天津 39.90420 116.40740 6
12 哈爾濱 45.80218 126.53582 6
13 北京&天津 39.90420 116.40740 7
14 武漢 30.59276 114.30524 7
15 武漢 30.59276 114.30524 8
16 鄭州 34.74725 113.62493 8
17 重慶 29.56470 106.55071 9
18 昆明 24.87966 102.83321 9
19 北京&天津 39.90420 116.40740 10
20 烏魯木齊 43.82660 87.61684 10
21 北京&天津 39.90420 116.40740 11
22 拉薩 29.64411 91.11445 11
23 鄭州 34.74725 113.62493 12
24 西安 34.34126 108.93982 12
25 武漢 30.59276 114.30524 13
26 重慶 29.56470 106.55071 13
27 北京&天津 39.90420 116.40740 14
28 鄭州 34.74725 113.62493 14
29 北京&天津 39.90420 116.40740 15
30 西安 34.34126 108.93982 15
31 鄭州 34.74725 113.62493 16
32 重慶 29.56470 106.55071 16
33 北京&天津 39.90420 116.40740 17
34 重慶 29.56470 106.55071 17
35 武漢 30.59276 114.30524 18
36 廣州&深圳 23.02067 113.75178 18
37 上海 31.23039 121.47370 19
38 武漢 30.59276 114.30524 19
39 上海 31.23039 121.47370 20
40 鄭州 34.74725 113.62493 20
41 北京&天津 39.90420 116.40740 21
42 廣州&深圳 23.02067 113.75178 21
43 上海 31.23039 121.47370 22
44 重慶 29.56470 106.55071 22
45 昆明 24.87966 102.83321 23
46 廣州&深圳 23.02067 113.75178 23
47 武漢 30.59276 114.30524 24
48 成都 30.57022 104.06477 24
49 鄭州 34.74725 113.62493 25
50 成都 30.57022 104.06477 25
51 西安 34.34126 108.93982 26
52 成都 30.57022 104.06477 26
53 北京&天津 39.90420 116.40740 27
54 成都 30.57022 104.06477 27
55 成都 30.57022 104.06477 28
56 昆明 24.87966 102.83321 28
57 西安 34.34126 108.93982 29
58 武漢 30.59276 114.30524 29
59 成都 30.57022 104.06477 30
60 廣州&深圳 23.02067 113.75178 30
61 上海 31.23039 121.47370 31
62 成都 30.57022 104.06477 31
63 哈爾濱 45.80218 126.53582 32
64 重慶 29.56470 106.55071 32
65 哈爾濱 45.80218 126.53582 33
66 廣州&深圳 23.02067 113.75178 33
3) 繪圖
下面我們的核心繪圖代碼如下,想要連接不同的線(xiàn),我們只是變了數(shù)據(jù)中選取的行,如:dat_plot[1:22, ]。
## 11線(xiàn)
ggplot() +
geom_path(data = china, aes(long, lat, group = group), color = '#FD9FA4', show.legend = F) +
geom_point(data = mat.cities, aes(x = long, y = lat, size = population), alpha = 0.8, color = '#8BB6D6') +
geom_line(data = dat_plot[1:22, ], aes(long, lat, group = group), size = 1, alpha = 0.8, color = '#8BB6D6') +
geom_text_repel(data = mat.cities, aes(x = long, y = lat, label = names), family = "STHeiti") +
labs(x = '經(jīng)度', y = '緯度', title = '十一條連線(xiàn)', size = '人口(百萬(wàn))') +
theme_bw() +
theme(panel.border = element_blank(),
text = element_text(family = "STHeiti"),
plot.title = element_text(hjust = 0.5))
## 16線(xiàn)
ggplot() +
geom_path(data = china, aes(long, lat, group = group), color = '#FD9FA4', show.legend = F) +
geom_point(data = mat.cities, aes(x = long, y = lat, size = population), alpha = 0.8, color = '#8BB6D6') +
geom_line(data = dat_plot[1:32, ], aes(long, lat, group = group), size = 1, alpha = 0.8, color = '#8BB6D6') +
geom_text_repel(data = mat.cities, aes(x = long, y = lat, label = names), family = "STHeiti") +
labs(x = '經(jīng)度', y = '緯度', title = '十六條連線(xiàn)', size = '人口(百萬(wàn))') +
theme_bw() +
theme(panel.border = element_blank(),
text = element_text(family = "STHeiti"),
plot.title = element_text(hjust = 0.5))
## 33線(xiàn)
ggplot() +
geom_path(data = china, aes(long, lat, group = group), color = '#FD9FA4', show.legend = F) +
geom_point(data = mat.cities, aes(x = long, y = lat, size = population), alpha = 0.8, color = '#8BB6D6') +
geom_line(data = dat_plot[1:66, ], aes(long, lat, group = group), size = 1, alpha = 0.8, color = '#8BB6D6') +
geom_text_repel(data = mat.cities, aes(x = long, y = lat, label = names), family = "STHeiti") +
labs(x = '經(jīng)度', y = '緯度', title = '三十三條連線(xiàn)', size = '人口(百萬(wàn))') +
theme_bw() +
theme(panel.border = element_blank(),
text = element_text(family = "STHeiti"),
plot.title = element_text(hjust = 0.5))
繪圖過(guò)程沒(méi)有什么好說(shuō)的了,里面使用的函數(shù)與方法都在前面的博客中提及過(guò):
R語(yǔ)言學(xué)習(xí)ggplot2繪制統(tǒng)計(jì)圖形包全面詳解
唯一添加的連線(xiàn)所使用的函數(shù):geom_line,里面只需注意多了一個(gè)參數(shù)group,記得添加即可。
4) 結(jié)果展示
最后的16條連線(xiàn)與33條連線(xiàn)的效果圖分別如下所示:
16條連線(xiàn):

33條連線(xiàn):

以上就是數(shù)模技巧ggplot2不用for循環(huán)實(shí)現(xiàn)地圖上連線(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于ggplot2在地圖上連線(xiàn)數(shù)模技巧的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于R/RStudio中安裝包“無(wú)法與服務(wù)器建立連接”的解決方案
這篇文章主要介紹了基于R/RStudio中安裝包“無(wú)法與服務(wù)器建立連接”的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04
R語(yǔ)言給圖形填充顏色的操作(polygon函數(shù))
這篇文章主要介紹了R語(yǔ)言給圖形填充顏色的操作(polygon函數(shù)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-03-03
R語(yǔ)言基于Keras的MLP神經(jīng)網(wǎng)絡(luò)及環(huán)境搭建
這篇文章主要介紹了R語(yǔ)言基于Keras的MLP神經(jīng)網(wǎng)絡(luò),我并沒(méi)有使用python去對(duì)比結(jié)果,但NSS的文章中有做對(duì)比,數(shù)據(jù)顯示R與Python相比在各方面的差別都不大,具體內(nèi)容介紹跟隨小編一起看看吧2022-01-01
R語(yǔ)言學(xué)習(xí)之線(xiàn)圖的繪制詳解
線(xiàn)圖是反映趨勢(shì)變化的一種方式,其輸入數(shù)據(jù)一般也是一個(gè)矩陣。本文將利用R語(yǔ)言繪制單線(xiàn)圖、多線(xiàn)圖以及橫軸文本線(xiàn)圖,感興趣的可以了解一下2022-03-03
R語(yǔ)言差異檢驗(yàn):非參數(shù)檢驗(yàn)操作
這篇文章主要介紹了R語(yǔ)言差異檢驗(yàn):非參數(shù)檢驗(yàn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04
R語(yǔ)言關(guān)于多重回歸知識(shí)點(diǎn)總結(jié)
在本篇內(nèi)容里小編給大家整理了一篇關(guān)于R語(yǔ)言關(guān)于多重回歸知識(shí)點(diǎn)總結(jié),有興趣的朋友們可以學(xué)習(xí)下。2021-05-05
R語(yǔ)言ggplot2拼圖包patchwork安裝使用
這篇文章主要介紹了R語(yǔ)言ggplot2拼圖包patchwork安裝使用的圖文示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06

