您好,登錄后才能下訂單哦!
小編給大家分享一下數模技巧不用for循環且使用ggplot2如何實現地圖上連線,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
首先可以回顧一下,在沒有梯子的前提下,我們是如何利用ggplot2
繪制一個較為好看的中國地圖:利用R繪制漂亮的中國地圖(無需通過google獲取)。
下面我們基于前面繪制的中國地圖,根據計算(最小生成樹算法,之后有時間在說說這個,不過目前網上說的很詳細了,而且也有很多代碼)得到的相應連線貼到我們的圖上。
我們需要選定其中幾個點,并將其進行連線。下面是我們最終想要達到的效果(之前的圖使用Mac畫的,下面這個是Windows,可能質感有些不一樣,望大家理解):
為了達到這樣的效果,我們主要是需要將數據集整理成可以能夠舒適繪制的方式。利用ggplot2
繪圖,整理數據集要占80%以上的工作。
我們的最終目的是連33條線,所以先將需要連的線均一組一組地羅列而出(每個city都對應著一組經緯度,相應地是地圖上的一個點)。
(前面的最終效果圖是前11組城市連線)
下面的數據我們命名為: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 哈爾濱 廣州&深圳
所以我們還需要對應城市經緯度及人口信息,這里的對象為mat.cities
,它長這樣:(這部分的數據生成也在我們前面的博客中有提及)
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
有了這樣兩份原始數據,我們就可以開始進行繪圖了。
首先是需要將數據整理成能夠進行繪圖的,為了方便操作,我們直接對原本的33組城市對進行操作。下面是數據預處理的過程。(由于當時數模時間有限,而數據量也不是很大,所以下面采用了大量的for循環,希望大家在用R時還是盡可能多用向量化操作,少用for循環)
預處理代碼如下:
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('地區', '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
長下面這樣:
地區 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
下面我們的核心繪圖代碼如下,想要連接不同的線,我們只是變了數據中選取的行,如:dat_plot[1:22, ]
。
## 11線 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 = '經度', 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 = 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 = '經度', 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 = 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 = '經度', y = '緯度', title = '三十三條連線', size = '人口(百萬)') + theme_bw() + theme(panel.border = element_blank(), text = element_text(family = "STHeiti"), plot.title = element_text(hjust = 0.5))
繪圖過程沒有什么好說的了,里面使用的函數與方法都在前面的博客中提及過:
R語言學習ggplot2繪制統計圖形包全面詳解
唯一添加的連線所使用的函數:geom_line
,里面只需注意多了一個參數group
,記得添加即可。
最后的16條連線與33條連線的效果圖分別如下所示:
16條連線:
33條連線:
看完了這篇文章,相信你對“數模技巧不用for循環且使用ggplot2如何實現地圖上連線”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。