Project1: Geocoding and lightweight route planning based on Baidu Map API

1.Background

项目初始数据集为给定的客户住址与项目位置(文本),需求为利用百度地图开放平台API获取上述两类地址的地理编码,并给予地理编码进行轻量级路线规划(Route plan),获得公共交通、驾车两种交通方式下的出行时间信息,并基于此信息进行可视化展示与分析。

> library(readxl)
> base_path <- '/Users/hufeiran/Desktop/Data\ Analysis\ protfolio/基于百度地图API的地理编码和轻量级路线规划/百特员工住址及备选项目位置表.xlsx'
> Cus_address <- read_xlsx(base_path, sheet = '客户住址')
> Cus_address
# A tibble: 9 × 2
   序号 客户员工住址                                                            
  <dbl> <chr>                                                                   
1     1 江苏省苏州市姑苏区干将西路1313号 欣嘉园                                 
2     2 江苏省苏州市苏州工业园区普惠路699号 淞泽家园                            
3     3 江苏省苏州市工业园区亭盛街66号 中信森林湖                               
4     4 江苏省苏州市苏州工业园区成义路18号 阿卡迪亚一区                         
5     5 江苏省苏州市东沙湖路111号 时代上城繁华里                                
6     6 江苏省苏州市吴中区邓尉中路55号 滟河湾花园                               
7     7 江苏省苏州市苏州工业园区敦煌路 莲香社区(查询不到详细门牌号,在敦煌路28…
8     8 江苏省苏州市虎丘区锦峰路8号                                             
9     9 江苏省苏州市吴江区油车路682号 鲈乡三村                                  
> Proj_address <- read_xlsx(base_path, sheet = '项目地址')
> Proj_address
# A tibble: 5 × 2
   序号 备选项目位置及名称                             
  <dbl> <chr>                                          
1     1 苏州市苏州工业园星汉路5号 腾飞新苏工业坊       
2     2 苏州市工业园区苏桐路112号 环普苏桐112国际科创园
3     3 苏州市姑苏区渔郎桥滨路16号 德必姑苏WE          
4     4 苏州市姑苏区广济南路19号 西城永捷              
5     5 苏州市姑苏区人民南路56号 安和锦 美地Park       

2.Geocoding

> #载入需要的包
> library(rvest)
> library(XML)
> library(tidyverse)
> #百度地图API申请
> AK <- 'o6B33Ptg4r1fLgp86MCpFNd81NHOZ9ae'
> #设置存放结果的空列表
> origin_data<-list()
> destination_data <- list()

2.1获取客户地址经纬度

> # 客户住址
> origin <- Cus_address
> origin <- origin %>%
+   rowwise() %>%
+   mutate(客户住址 = strsplit(客户员工住址,' ')[[1]][1])
> # View(origin)
> origin <- origin$客户住址
> origin_jwd <- list()
> 
> for(i in 1:length(origin))
+ {
+   url<-paste("https://api.map.baidu.com/geocoding/v3/?address=",origin[i],"&output=json&ak=",AK,"&callback=showLocation",sep="")
+   web<-read_html(url)
+   xmldoc<-xmlRoot(xmlParse(web,encoding="UTF-8"))
+   rootnode<-xmlRoot(xmldoc)
+   res<-xmlValue(rootnode)
+   res2<-strsplit(res,"location")[[1]][2]
+   GIS<-strsplit(res2,'"')[[1]][c(4,6)]
+   lon<-sub(",","",sub(":","",strsplit(GIS," ")[1]))
+   lat<-sub(",","",sub(":","",sub("}","",strsplit(GIS," ")[2])))
+   data <- data.frame(name = origin[i], lon, lat)
+   origin_jwd[i] <- paste(round(as.double(lat),6),",",round(as.double(lon),6),sep = '')
+   origin_data[[i]] <- data
+   next
+ }
> 
> final_origin <- do.call(rbind,origin_data) %>%
+   mutate(origin_jwd = origin_jwd)
> final_origin
                                 name                lon                lat
1    江苏省苏州市姑苏区干将西路1313号 120.58625596227225 31.307770639194467
2 江苏省苏州市苏州工业园区普惠路699号 120.75039236878328  31.25362648986902
3      江苏省苏州市工业园区亭盛街66号 120.71991663571288  31.38298414996111
4  江苏省苏州市苏州工业园区成义路18号 120.74152205102502  31.37722902125238
5           江苏省苏州市东沙湖路111号 120.76094647038947 31.338376369519325
6      江苏省苏州市吴中区邓尉中路55号 120.40062409304348  31.29216159938657
7      江苏省苏州市苏州工业园区敦煌路 120.74665272294526 31.301987180853386
8         江苏省苏州市虎丘区锦峰路8号 120.44317700471224 31.316697853521189
9       江苏省苏州市吴江区油车路682号 120.64263038217863 31.172500907237646
            origin_jwd
1 31.307771,120.586256
2 31.253626,120.750392
3 31.382984,120.719917
4 31.377229,120.741522
5 31.338376,120.760946
6 31.292162,120.400624
7 31.301987,120.746653
8 31.316698,120.443177
9  31.172501,120.64263

2.2获取项目地址经纬度

> destination <- Proj_address
> destination <- destination %>%
+   rowwise() %>%
+   mutate(目标地址 = strsplit(备选项目位置及名称,' ')[[1]][1])
> destination <- destination$目标地址
> destination_jwd <- list()
> 
> for(i in 1:length(destination)){
+   url<-paste("https://api.map.baidu.com/geocoding/v3/?address=",destination[i],"&output=json&ak=",AK,"&callback=showLocation",sep="")
+   web<-read_html(url)
+   xmldoc<-xmlRoot(xmlParse(web,encoding="UTF-8"))
+   rootnode<-xmlRoot(xmldoc)
+   res<-xmlValue(rootnode)
+   res2<-strsplit(res,"location")[[1]][2]
+   GIS<-strsplit(res2,'"')[[1]][c(4,6)]
+   lon<-sub(",","",sub(":","",strsplit(GIS," ")[1]))
+   lat<-sub(",","",sub(":","",sub("}","",strsplit(GIS," ")[2])))
+   data <- data.frame(name = destination[i], lon, lat)
+   destination_jwd[i] <- paste(round(as.double(lat),6),",",round(as.double(lon),6),sep = '')
+   destination_data[[i]] <- data
+   next
+ }
> 
> final_destination <- do.call(rbind,destination_data) %>%
+   mutate(destination_jwd = destination_jwd)
> final_destination
                        name                lon                lat
1  苏州市苏州工业园星汉路5号  120.7298897133152   31.3304431437088
2  苏州市工业园区苏桐路112号 120.67201521303771 31.308718509337479
3 苏州市姑苏区渔郎桥滨路16号 120.84997600236402 31.388106140056519
4   苏州市姑苏区广济南路19号 120.60615001575731  31.31191284332292
5   苏州市姑苏区人民南路56号 120.96418099540846  31.37536187285818
       destination_jwd
1  31.330443,120.72989
2 31.308719,120.672015
3 31.388106,120.849976
4  31.311913,120.60615
5 31.375362,120.964181

2.3建立交叉表

> final_drive <- rbind.data.frame(final_origin,final_origin,final_origin,final_origin,final_origin) %>%
+   mutate(id = c(1:45)) %>%
+   mutate(des = case_when(
+     id <= 9 ~ final_destination$name[1],
+     id <= 18 ~ final_destination$name[2],
+     id <= 27 ~ final_destination$name[3],
+     id <= 36 ~ final_destination$name[4],
+     id <= 45 ~ final_destination$name[5]
+   )) %>%
+  mutate(des_jwd = case_when(
+   id <= 9 ~ final_destination$destination_jwd[1],
+   id <= 18 ~ final_destination$destination_jwd[2],
+   id <= 27 ~ final_destination$destination_jwd[3],
+   id <= 36 ~ final_destination$destination_jwd[4],
+   id <= 45 ~ final_destination$destination_jwd[5]
+ ))
> final_transit <- final_drive
> final_drive
                                  name                lon                lat
1     江苏省苏州市姑苏区干将西路1313号 120.58625596227225 31.307770639194467
2  江苏省苏州市苏州工业园区普惠路699号 120.75039236878328  31.25362648986902
3       江苏省苏州市工业园区亭盛街66号 120.71991663571288  31.38298414996111
4   江苏省苏州市苏州工业园区成义路18号 120.74152205102502  31.37722902125238
5            江苏省苏州市东沙湖路111号 120.76094647038947 31.338376369519325
6       江苏省苏州市吴中区邓尉中路55号 120.40062409304348  31.29216159938657
7       江苏省苏州市苏州工业园区敦煌路 120.74665272294526 31.301987180853386
8          江苏省苏州市虎丘区锦峰路8号 120.44317700471224 31.316697853521189
9        江苏省苏州市吴江区油车路682号 120.64263038217863 31.172500907237646
10    江苏省苏州市姑苏区干将西路1313号 120.58625596227225 31.307770639194467
11 江苏省苏州市苏州工业园区普惠路699号 120.75039236878328  31.25362648986902
12      江苏省苏州市工业园区亭盛街66号 120.71991663571288  31.38298414996111
13  江苏省苏州市苏州工业园区成义路18号 120.74152205102502  31.37722902125238
14           江苏省苏州市东沙湖路111号 120.76094647038947 31.338376369519325
15      江苏省苏州市吴中区邓尉中路55号 120.40062409304348  31.29216159938657
16      江苏省苏州市苏州工业园区敦煌路 120.74665272294526 31.301987180853386
17         江苏省苏州市虎丘区锦峰路8号 120.44317700471224 31.316697853521189
18       江苏省苏州市吴江区油车路682号 120.64263038217863 31.172500907237646
19    江苏省苏州市姑苏区干将西路1313号 120.58625596227225 31.307770639194467
20 江苏省苏州市苏州工业园区普惠路699号 120.75039236878328  31.25362648986902
21      江苏省苏州市工业园区亭盛街66号 120.71991663571288  31.38298414996111
22  江苏省苏州市苏州工业园区成义路18号 120.74152205102502  31.37722902125238
23           江苏省苏州市东沙湖路111号 120.76094647038947 31.338376369519325
24      江苏省苏州市吴中区邓尉中路55号 120.40062409304348  31.29216159938657
25      江苏省苏州市苏州工业园区敦煌路 120.74665272294526 31.301987180853386
26         江苏省苏州市虎丘区锦峰路8号 120.44317700471224 31.316697853521189
27       江苏省苏州市吴江区油车路682号 120.64263038217863 31.172500907237646
28    江苏省苏州市姑苏区干将西路1313号 120.58625596227225 31.307770639194467
29 江苏省苏州市苏州工业园区普惠路699号 120.75039236878328  31.25362648986902
30      江苏省苏州市工业园区亭盛街66号 120.71991663571288  31.38298414996111
31  江苏省苏州市苏州工业园区成义路18号 120.74152205102502  31.37722902125238
32           江苏省苏州市东沙湖路111号 120.76094647038947 31.338376369519325
33      江苏省苏州市吴中区邓尉中路55号 120.40062409304348  31.29216159938657
34      江苏省苏州市苏州工业园区敦煌路 120.74665272294526 31.301987180853386
35         江苏省苏州市虎丘区锦峰路8号 120.44317700471224 31.316697853521189
36       江苏省苏州市吴江区油车路682号 120.64263038217863 31.172500907237646
37    江苏省苏州市姑苏区干将西路1313号 120.58625596227225 31.307770639194467
38 江苏省苏州市苏州工业园区普惠路699号 120.75039236878328  31.25362648986902
39      江苏省苏州市工业园区亭盛街66号 120.71991663571288  31.38298414996111
40  江苏省苏州市苏州工业园区成义路18号 120.74152205102502  31.37722902125238
41           江苏省苏州市东沙湖路111号 120.76094647038947 31.338376369519325
42      江苏省苏州市吴中区邓尉中路55号 120.40062409304348  31.29216159938657
43      江苏省苏州市苏州工业园区敦煌路 120.74665272294526 31.301987180853386
44         江苏省苏州市虎丘区锦峰路8号 120.44317700471224 31.316697853521189
45       江苏省苏州市吴江区油车路682号 120.64263038217863 31.172500907237646
             origin_jwd id                        des              des_jwd
1  31.307771,120.586256  1  苏州市苏州工业园星汉路5号  31.330443,120.72989
2  31.253626,120.750392  2  苏州市苏州工业园星汉路5号  31.330443,120.72989
3  31.382984,120.719917  3  苏州市苏州工业园星汉路5号  31.330443,120.72989
4  31.377229,120.741522  4  苏州市苏州工业园星汉路5号  31.330443,120.72989
5  31.338376,120.760946  5  苏州市苏州工业园星汉路5号  31.330443,120.72989
6  31.292162,120.400624  6  苏州市苏州工业园星汉路5号  31.330443,120.72989
7  31.301987,120.746653  7  苏州市苏州工业园星汉路5号  31.330443,120.72989
8  31.316698,120.443177  8  苏州市苏州工业园星汉路5号  31.330443,120.72989
9   31.172501,120.64263  9  苏州市苏州工业园星汉路5号  31.330443,120.72989
10 31.307771,120.586256 10  苏州市工业园区苏桐路112号 31.308719,120.672015
11 31.253626,120.750392 11  苏州市工业园区苏桐路112号 31.308719,120.672015
12 31.382984,120.719917 12  苏州市工业园区苏桐路112号 31.308719,120.672015
13 31.377229,120.741522 13  苏州市工业园区苏桐路112号 31.308719,120.672015
14 31.338376,120.760946 14  苏州市工业园区苏桐路112号 31.308719,120.672015
15 31.292162,120.400624 15  苏州市工业园区苏桐路112号 31.308719,120.672015
16 31.301987,120.746653 16  苏州市工业园区苏桐路112号 31.308719,120.672015
17 31.316698,120.443177 17  苏州市工业园区苏桐路112号 31.308719,120.672015
18  31.172501,120.64263 18  苏州市工业园区苏桐路112号 31.308719,120.672015
19 31.307771,120.586256 19 苏州市姑苏区渔郎桥滨路16号 31.388106,120.849976
20 31.253626,120.750392 20 苏州市姑苏区渔郎桥滨路16号 31.388106,120.849976
21 31.382984,120.719917 21 苏州市姑苏区渔郎桥滨路16号 31.388106,120.849976
22 31.377229,120.741522 22 苏州市姑苏区渔郎桥滨路16号 31.388106,120.849976
23 31.338376,120.760946 23 苏州市姑苏区渔郎桥滨路16号 31.388106,120.849976
24 31.292162,120.400624 24 苏州市姑苏区渔郎桥滨路16号 31.388106,120.849976
25 31.301987,120.746653 25 苏州市姑苏区渔郎桥滨路16号 31.388106,120.849976
26 31.316698,120.443177 26 苏州市姑苏区渔郎桥滨路16号 31.388106,120.849976
27  31.172501,120.64263 27 苏州市姑苏区渔郎桥滨路16号 31.388106,120.849976
28 31.307771,120.586256 28   苏州市姑苏区广济南路19号  31.311913,120.60615
29 31.253626,120.750392 29   苏州市姑苏区广济南路19号  31.311913,120.60615
30 31.382984,120.719917 30   苏州市姑苏区广济南路19号  31.311913,120.60615
31 31.377229,120.741522 31   苏州市姑苏区广济南路19号  31.311913,120.60615
32 31.338376,120.760946 32   苏州市姑苏区广济南路19号  31.311913,120.60615
33 31.292162,120.400624 33   苏州市姑苏区广济南路19号  31.311913,120.60615
34 31.301987,120.746653 34   苏州市姑苏区广济南路19号  31.311913,120.60615
35 31.316698,120.443177 35   苏州市姑苏区广济南路19号  31.311913,120.60615
36  31.172501,120.64263 36   苏州市姑苏区广济南路19号  31.311913,120.60615
37 31.307771,120.586256 37   苏州市姑苏区人民南路56号 31.375362,120.964181
38 31.253626,120.750392 38   苏州市姑苏区人民南路56号 31.375362,120.964181
39 31.382984,120.719917 39   苏州市姑苏区人民南路56号 31.375362,120.964181
40 31.377229,120.741522 40   苏州市姑苏区人民南路56号 31.375362,120.964181
41 31.338376,120.760946 41   苏州市姑苏区人民南路56号 31.375362,120.964181
42 31.292162,120.400624 42   苏州市姑苏区人民南路56号 31.375362,120.964181
43 31.301987,120.746653 43   苏州市姑苏区人民南路56号 31.375362,120.964181
44 31.316698,120.443177 44   苏州市姑苏区人民南路56号 31.375362,120.964181
45  31.172501,120.64263 45   苏州市姑苏区人民南路56号 31.375362,120.964181

2.4驾车路线规划

> for (i in 1:nrow(final_drive)){
+     url_drive <- paste("https://api.map.baidu.com/directionlite/v1/driving?origin=",final_drive$origin_jwd[i],"&destination=",final_drive$des_jwd[i],"&ak=",AK,sep = '')
+     web_drive <- read_html(url_drive)
+     xmldoc_drive <- xmlRoot(xmlParse(web_drive,encoding="UTF-8"))
+     rootnode_drive <- xmlRoot(xmldoc_drive)
+     res_drive <- xmlValue(rootnode_drive) 
+     res_drive2 <- unlist(strsplit(res_drive,"route"))[3]
+     GIS_drive <- unlist(strsplit(res_drive2,'"'))
+     drive_dis <- sub(",","",sub(":","",GIS_drive[6]))
+     drive_time <- sub(",","",sub(":","",GIS_drive[8]))
+     final_drive$distance[i] <- drive_dis
+     final_drive$time[i] <- drive_time
+ }
> final_drive

2.5公共交通路线规划

> for (i in 1:nrow(final_transit)){
+     url_transit <- paste("https://api.map.baidu.com/directionlite/v1/transit?origin=",final_transit$origin_jwd[i],"&destination=",final_transit$des_jwd[i],"&ak=",AK,sep = '')
+     web_transit <- read_html(url_transit)
+     xmldoc_transit <- xmlRoot(xmlParse(web_transit, encoding="UTF-8"))
+     rootnode_transit <- xmlRoot(xmldoc_transit)
+     res_transit <- xmlValue(rootnode_transit) 
+     res_transit2 <- unlist(strsplit(res_transit,"route"))[3]
+     GIS_transit <- unlist(strsplit(res_transit2,'"'))
+     transit_dis <- sub(",","",sub(":","",GIS_transit[6]))
+     transit_time <- sub(",","",sub(":","",GIS_transit[8]))
+     final_transit$distance[i] <- transit_dis
+     final_transit$time[i] <- transit_time
+ }
> final_transit

3.写入结果

> writexl::write_xlsx(final_drive, path = 'drive.xlsx')
> writexl::write_xlsx(final_transit, path = 'transit.xlsx')

4.利用circlize、ggplot2等包可视化结果

4.1读入数据

> library(readxl)
> df <- read_xlsx('/Users/hufeiran/Desktop/2023_JLL/地址查找WGS1984/百特员工住址及备选项目位置表.xlsx',
+                 sheet = 'res')
> df
# A tibble: 49 × 5
   目的地                      客户住址 `经纬度/wgs84` `驾车时间/s` `公交时间/s`
   <chr>                       <chr>    <chr>                 <dbl>        <dbl>
 1 苏州市苏州工业园星汉路5号 … 江苏省…  31.303600,120…         1944         2737
 2 苏州市苏州工业园星汉路5号 … 江苏省…  31.248522,120…         1809         4067
 3 苏州市苏州工业园星汉路5号 … 江苏省…  31.378964,120…         1370         3738
 4 苏州市苏州工业园星汉路5号 … 江苏省…  31.372105,120…         1284         3196
 5 苏州市苏州工业园星汉路5号 … 江苏省…  31.335554,120…         1397         2928
 6 苏州市苏州工业园星汉路5号 … 江苏省…  31.288099,120…         2604         6161
 7 苏州市苏州工业园星汉路5号 … 江苏省…  31.299286,120…          864         2567
 8 苏州市苏州工业园星汉路5号 … 江苏省…  31.312775,120…         2067         6945
 9 苏州市苏州工业园星汉路5号 … 江苏省…  31.170377,120…         2348         3464
10 <NA>                        <NA>     <NA>                     NA           NA
# ℹ 39 more rows

4.2dplyr清洗

> library(tidyverse)
> df <- df %>%
+   filter(!is.na(目的地)) %>%
+   mutate(Proj_ori = sapply(strsplit(sapply(strsplit(客户住址,'市'), tail, 1),' '), head, 1)) %>%
+   mutate(Proj_des = sapply(strsplit(目的地,' '), tail, 1)) %>%
+   mutate(drive_time = round(`驾车时间/s`/60, 2)) %>%
+   mutate(bus_time = round(`公交时间/s`/60, 2)) %>%
+   mutate(gap_time = bus_time - drive_time) %>%
+   select(contains('_'))
> 
> df
# A tibble: 45 × 5
   Proj_ori                Proj_des              drive_time bus_time gap_time
   <chr>                   <chr>                      <dbl>    <dbl>    <dbl>
 1 姑苏区干将西路1313号    腾飞新苏工业坊              32.4     45.6     13.2
 2 苏州工业园区普惠路699号 腾飞新苏工业坊              30.2     67.8     37.6
 3 工业园区亭盛街66号      腾飞新苏工业坊              22.8     62.3     39.5
 4 苏州工业园区成义路18号  腾飞新苏工业坊              21.4     53.3     31.9
 5 东沙湖路111号           腾飞新苏工业坊              23.3     48.8     25.5
 6 吴中区邓尉中路55号      腾飞新苏工业坊              43.4    103.      59.3
 7 苏州工业园区敦煌路      腾飞新苏工业坊              14.4     42.8     28.4
 8 虎丘区锦峰路8号         腾飞新苏工业坊              34.4    116.      81.3
 9 吴江区油车路682号       腾飞新苏工业坊              39.1     57.7     18.6
10 姑苏区干将西路1313号    环普苏桐112国际科创园       29.0     49.4     20.4
# ℹ 35 more rows

4.3设置字体

> library(showtext)
> showtext_auto(enable = TRUE)
> getOption('encoding')
[1] "native.enc"
> options(encoding = 'UTF-8')
> font_families()
[1] "sans"         "serif"        "mono"         "wqy-microhei"
> font_add('Times','/System/Library/Fonts/Times.ttc')
> font_add('Arial','/System/Library/Fonts/ArialHB.ttc')
> font_add('Apple','/System/Library/Fonts/Apple Symbols.ttf')
> font_add('ST','/System/Library/Fonts/STHeiti Medium.ttc')

4.4 ggplot2绘制热图

drive_time

> df %>%
+   ggplot(aes(Proj_des, Proj_ori)) + 
+   theme_bw() + #设置系统自带主题
+   theme(text = element_text(family = 'ST')) + #设置字体
+   theme(panel.grid.major = element_blank()) +  #设置主项网格
+   theme(legend.key = element_blank()) + #去掉背景颜色
+   theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1)) + #坐标轴标签
+   theme(legend.position = 'top') + #图例位置
+   geom_tile(aes(fill = drive_time)) +
+   geom_text(aes(label = drive_time)) + 
+   scale_fill_gradient(low = 'white', high = '#D0355D')

bus_time

> df %>%
+   ggplot(aes(Proj_des, Proj_ori)) + 
+   theme_bw() + #设置系统自带主题
+   theme(text = element_text(family = 'ST')) + #设置字体
+   theme(panel.grid.major = element_blank()) +  #设置主项网格
+   theme(legend.key = element_blank()) + #去掉背景颜色
+   theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1)) + #坐标轴标签
+   theme(legend.position = 'top') + #图例位置
+   geom_tile(aes(fill = bus_time)) +
+   geom_text(aes(label = bus_time)) + 
+   scale_fill_gradient(low = 'white', high = '#D0355D')

gap_time(bus_time - drive_time)

> df %>%
+   ggplot(aes(Proj_des, Proj_ori)) + 
+   theme_bw() + #设置系统自带主题
+   theme(text = element_text(family = 'ST')) + #设置字体
+   theme(panel.grid.major = element_blank()) +  #设置主项网格
+   theme(legend.key = element_blank()) + #去掉背景颜色
+   theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1)) + #坐标轴标签
+   theme(legend.position = 'top') + #图例位置
+   geom_tile(aes(fill = drive_time)) +
+   geom_text(aes(label = drive_time)) + 
+   scale_fill_gradient(low = 'white', high = '#D0355D')

4.5 Complexheatmap绘制层次聚类热图

> #建构矩阵route_time
> route_time <- as.matrix(cbind(df$drive_time,df$bus_time,df$gap_time))
> rownames(route_time) <- df$Proj_ori
> colnames(route_time) <- colnames(df)[c(3,4,5)]
> route_time
                        drive_time bus_time gap_time
姑苏区干将西路1313号         32.40    45.62    13.22
苏州工业园区普惠路699号      30.15    67.78    37.63
工业园区亭盛街66号           22.83    62.30    39.47
苏州工业园区成义路18号       21.40    53.27    31.87
东沙湖路111号                23.28    48.80    25.52
吴中区邓尉中路55号           43.40   102.68    59.28
苏州工业园区敦煌路           14.40    42.78    28.38
虎丘区锦峰路8号              34.45   115.75    81.30
吴江区油车路682号            39.13    57.73    18.60
姑苏区干将西路1313号         29.03    49.45    20.42
苏州工业园区普惠路699号      25.50    69.32    43.82
工业园区亭盛街66号           23.52    76.10    52.58
苏州工业园区成义路18号       21.67    66.87    45.20
东沙湖路111号                24.22    52.23    28.01
吴中区邓尉中路55号           45.78    99.93    54.15
苏州工业园区敦煌路           15.75    60.83    45.08
虎丘区锦峰路8号              38.00   113.52    75.52
吴江区油车路682号            35.57    63.12    27.55
姑苏区干将西路1313号         18.50    40.37    21.87
苏州工业园区普惠路699号      33.97    88.55    54.58
工业园区亭盛街66号           20.02    85.35    65.33
苏州工业园区成义路18号       23.00    77.75    54.75
东沙湖路111号                22.55    75.58    53.03
吴中区邓尉中路55号           35.03   112.18    77.15
苏州工业园区敦煌路           30.92    59.02    28.10
虎丘区锦峰路8号              26.68   101.55    74.87
吴江区油车路682号            34.63    58.97    24.34
姑苏区干将西路1313号          6.05    16.28    10.23
苏州工业园区普惠路699号      33.00    57.52    24.52
工业园区亭盛街66号           32.50    74.72    42.22
苏州工业园区成义路18号       36.25    66.27    30.02
东沙湖路111号                40.77    52.47    11.70
吴中区邓尉中路55号           37.68    88.10    50.42
苏州工业园区敦煌路           39.55    46.33     6.78
虎丘区锦峰路8号              29.50    83.47    53.97
吴江区油车路682号            27.78    47.72    19.94
姑苏区干将西路1313号         18.23    29.27    11.04
苏州工业园区普惠路699号      24.33    55.80    31.47
工业园区亭盛街66号           25.23    79.72    54.49
苏州工业园区成义路18号       27.12    70.48    43.36
东沙湖路111号                35.13    56.45    21.32
吴中区邓尉中路55号           44.27    90.87    46.60
苏州工业园区敦煌路           19.10    41.92    22.82
虎丘区锦峰路8号              32.72   111.48    78.76
吴江区油车路682号            25.05    37.87    12.82
> ## 设置分割变量
> split1 <- factor(df$Proj_des)
> ## 设置颜色函数
> col_fun2 <- circlize::colorRamp2(c(min(df$gap_time),max(df$bus_time)), c('white','#D0355D'))
> # ComplexHeatmap层次聚类热力
> library(ComplexHeatmap)
> Heatmap(route_time, row_split = split1, col = col_fun2)

4.6 circlize绘制环形热图

> library(circlize)
> #全局变量控制
> circos.par(gap.after = c(2, 2, 2, 2, 9))
> circos.heatmap.initialize(route_time, split = split1)
> #外轨bus_time
> circos.heatmap(route_time[,2], col = col_fun2, rownames.side = 'outside', rownames.cex = 0.1,
+               track.height = 0.1, rownames.col = rownames(route_time))
> #中轨drive_time
> circos.heatmap(route_time[,1], col = col_fun2, track.height = 0.1)
> #内轨gap_time
> circos.heatmap(route_time[,3], col = col_fun2, track.height = 0.1, dend.side = 'inside') 
> 
> ### 添加组别名
> circos.track(track.index = get.current.track.index(), panel.fun = function(x, y) {
+        circos.text(CELL_META$xcenter, CELL_META$cell.ylim[2] + convert_y(-15, "mm"), 
+                              paste0('Des:',CELL_META$sector.index),
+                              facing = "bending.outside", cex = 0.6,
+                              adj = c(0.5, 0), niceFacing = TRUE)
+ },bg.border = NA)
> 
> circos.track(track.index = get.current.track.index(), panel.fun = function(x, y) {
+        if(CELL_META$sector.numeric.index == 5) { # 最后一个扇区
+              cn = colnames(route_time)
+              n = length(cn)
+              circos.text(rep(CELL_META$cell.xlim[2], n) + convert_x(1.5, "mm"), 
+                                        1:n*130 + 60, c(cn[3],cn[1],cn[2]), 
+                                        cex = 0.5, adj = c(0, 0.5), facing = "inside")
+          }
+    }, bg.border = NA)
> 
> ### 添加图例
> lgd = Legend(title = 'Route_time/min', col_fun = col_fun2, direction = 'horizontal',
+              title_position = 'topcenter')
> grid.draw(lgd)

> circos.clear()