首先,加载recharts
:
library(recharts)
地图包含4种基本类型:
关键是:
type
和/或subtype
得到地图底图x
x[,1]
必须是有效的地理名称,比如’United States of America’而非’USA’或’U.S.’y
y[,1]
: 数值y[,2]
: 是否选中。也可用1代表TRUE, 0代表FALSEaddNameMap
添加地理名称翻译字典addHeatMap
添加额外的热力图图层addMarkLine
或addMarkPoint
添加标注线/标注点
addGeoCoord
定义标注线/标注点的地理坐标echartr(data, <x>, <y>, <series>, <facet>, <lng>, <lat>, <t>, <type>, <subtype>)
参数 | 要求 |
---|---|
data |
数据框格式的源数据 |
x |
文本型自变量。 |
y |
数值型应变量。如提供多个变量,只传入前两个。 |
series |
series转为因子后计算。 |
facet |
facet转为因子后计算。 |
t |
时间轴变量,转为因子后计算。如提供多个变量,只传入第一个。 |
type |
‘map_world’, ‘map_world_multi’, ‘map_china’, ‘map_china_multi’. |
subtype |
|
如果其他参数均为NULL,只设置type
和/或subtype
,就可以得到地图底图,不显示任何数据。
type
设为’map_world’或’map_china’,其他参数为NULL(忽略)。
echartr(NULL, type='map_world') %>% setTitle('World Map')
echartr(NULL, type='map_china') %>% setTitle('China Map')
也可以只显示部分底图。中国的省级行政区可以作为独立的mapType,从而看到下辖的市级行政区。
echartr(NULL, type='map_world', subtype='United States of America') %>%
setTitle('World Map|USA')
echartr(NULL, type='map_china', subtype='上海') %>%
setTitle('China Map|Shanghai')
type
设为’map_world_multi’或’map_china_multi’,获得可多选的地图底图。也可以设置subtype。
echartr(NULL, type='map_world_multi') %>% setTitle('World Map')
echartr(NULL, type='map_china_multi', subtype='上海') %>%
setTitle('China Map|Shanghai')
如设置facet
和subtype
(有效的地理名称),可得到独立的地图。注意subtype
要整理成list。
data <- data.frame(x=c('United States of America', 'China', 'Japan'))
echartr(data, x, facet=x, type='map_world', subtype=as.list(data$x))
也可以在底图上加载数据,提高其信息性。
如果未指定series
,地图不会区分数据系列。
worldgdp <- data.frame(
country=c('United States of America', 'China', 'Japan', 'Germany',
'United Kingdom', 'France', 'Brazil', 'Italy', 'India', 'Russia',
'Canada', 'Australia', 'South Korea', 'Spain', 'Mexico',
'Indonesia', 'Netherlands', 'Turkey', 'Saudi Arabia',
'Switzerland'),
GDP=c(17418925, 10380380, 4616335, 3859547, 2945146, 2846889, 2353025,
2147952, 2049501, 1857461, 1788717, 1444189, 1416949, 1406855, 1282725,
888648, 866354, 806108, 752459, 712050))
echartr(worldgdp, country, GDP, type="map_world") %>%
setTitle("World GDP Top 20, 2014")
然而点标注信息性不强,可以映射值域选择,给地图区块填色。顺便把地图漫游模式改为’move’并’scale’。
echartr(worldgdp, country, GDP, type="map_world", subtype="move + scale") %>%
setDataRange(splitNumber=0, color=getColFromPal('rainbow')) %>%
setTitle("World GDP Top 20, 2014")
用ChinaGDP
数据集作图,’Year’作为数据系列变量。
str(ChinaGDP)
## 'data.frame': 93 obs. of 3 variables:
## $ Year: num 2014 2014 2014 2014 2014 ...
## $ Prov: chr "广东" "江苏" "山东" "浙江" ...
## $ GDP : num 1103605 1059587 967419 653668 568786 ...
totGDP <- data.table::dcast(ChinaGDP, Prov~., sum, value.var='GDP')
## Warning in split_indices(.group, .n): '.Random.seed' is not an integer
## vector but of type 'NULL', so ignored
ChinaGDP <- ChinaGDP[order(ChinaGDP$Year),]
echartr(ChinaGDP, Prov, GDP, Year, type="map_china") %>%
setDataRange(splitNumber=0, valueRange=range(totGDP[, 2]),
color=c('red','orange','yellow','limegreen','green')) %>%
setTitle("China GDP by Provice, 2012-2014")
这里,mapValueCalculation
方法是求和。在subtype
添加’average’,就改为平均法。
echartr(ChinaGDP, Prov, GDP, Year, type="map_china", subtype='average') %>%
setDataRange(splitNumber=0,
color=c('red','orange','yellow','limegreen','green')) %>%
setTitle("China GDP by Provice, 2012-2014")
把t
设为’Year’,可获得带时间轴的地图。
echartr(ChinaGDP, Prov, GDP, t=Year, type="map_china", subtype='average') %>%
setDataRange(splitNumber=0,
color=c('red','orange','yellow','limegreen','green')) %>%
setTitle("China GDP by Provice, 2012-2014")
设type
为’map_world_multi’或’map_china_multi’,其余与上述相似。
把GDP前十名国家平铺,而非原位展示。
worldgdp <- worldgdp[order(worldgdp$GDP, decreasing=TRUE),]
worldgdp10 <- worldgdp[1:10, ]
echartr(worldgdp10, country, GDP, facet=country, type='map_world',
subtype=as.list(worldgdp10$country)) %>%
setDataRange(color=c(
'red', 'orange', 'yellow', 'limegreen', 'green'), pos=4) %>%
setSymbols('none')
接下来可以配置控件、添加标注点/标注线,以及美化成图。
或许你想让中国省份显示为英文。可以使用addNameMap
或overideNameMap
函数。
recharts内置了一个geoNameMap数据集,包含了一部分中英文地理名称。’LEVEL’列是0-3的数值: 0代表国家, 1代表省份, 2 代表城市, 3代表区县。’FKEY’是上级行政区的外键,比如’China’的ID为31,所以可以通过geoNameMap[geoNameMap$FKEY==31,]
获得中国所有的省份。
str(geoNameMap)
## 'data.frame': 3735 obs. of 5 variables:
## $ ID : int 1 2 3 4 5 6 7 8 9 10 ...
## $ EN : chr "Afghanistan" "Angola" "Albania" "United Arab Emirates" ...
## $ CN : chr "阿富汗" "安哥拉" "阿尔巴尼亚" "阿联酋" ...
## $ FKEY : int 0 0 0 0 0 0 0 0 0 0 ...
## $ LEVEL: int 0 0 0 0 0 0 0 0 0 0 ...
所以准备一个两列的数据框作为地名字典:第1列是源语言,第2列是目标语言。这就是addNameMap
函数要求的合法数据结构。
dict <- geoNameMap[geoNameMap$FKEY==31, c("CN", "EN")]
echartr(NULL, type="map_china_multi") %>% addNameMap(dict, mode='overide')
addMarkLine
基于底图,可通过addMarkLine
(或简写为addML
) 或overideMarkLine
增加/覆写标注线。
下例使用的是另一个内置数据集flight。
str(flight)
## List of 2
## $ route:'data.frame': 150 obs. of 2 variables:
## ..$ From: chr [1:150] "北京" "北京" "北京" "北京" ...
## ..$ To : chr [1:150] "包头" "北海" "广州" "郑州" ...
## $ coord:'data.frame': 114 obs. of 3 variables:
## ..$ Place: chr [1:114] "上海" "东莞" "东营" "中山" ...
## ..$ Lng : num [1:114] 121 114 119 113 111 ...
## ..$ Lat : num [1:114] 31.3 22.9 37.6 22.5 36.2 ...
route <- flight$route
names(route) <- c('name1', 'name2')
coord <- flight$coord
g <- echartr(NULL, type='map_china') %>%
addML(series='北京', data=route[route$name1=='北京',]) %>%
addML(series='上海', data=route[route$name1=='上海',]) %>%
addML(series='广州', data=route[route$name1=='广州',])
g
该命令等价于
g <- echartr(NULL, type='map_china') %>%
addML(series=c('北京', '上海', '广州), data=route)
addGeoCoord
这样做仍不能显示标注线。必须通过addGeoCoord
添加上述标注线涉及到的地名的经纬度。
g %>% addGeoCoord(coord)
addMarkPoint
基于底图,可通过addMarkPoint
(或简写为addMP
) 或overideMarkPoint
增加/覆写标注点。
下例使用的是另一个内置数据集chinapm25。
str(chinapm25)
## 'data.frame': 190 obs. of 4 variables:
## $ City : chr "海门" "鄂尔多斯" "招远" "舟山" ...
## $ Value: num 9 12 12 12 14 15 16 18 18 19 ...
## $ Lng : num 121 110 120 122 124 ...
## $ Lat : num 31.9 39.6 37.4 30 47.3 ...
names(chinapm25) <- c('name', 'value', 'lng', 'lat')
g <- echartr(NULL, type='map_china') %>%
addMP(data=chinapm25[,c('name', 'value')], symbolSize=5, itemStyle=list(
normal=list(borderColor='#87cefa', borderWidth=1,
label=list(show=FALSE)),
emphasis=list(borderColor='#1e90ff', borderWidth=5,
label=list(show=FALSE))
)) %>%
addMP(series='Top 5',
data=data.frame(
name=c('廊坊', '合肥', '菏泽', '武汉', '大庆'),
value=c(193, 194, 229, 273, 279)),
symbol='emptyCircle',
symbolSize=JS('function (v) {return 10 + v/100;}'),
effect=list(show=TRUE)
) %>%
setDataRange(splitNumber=0, valueRange=c(0, 500), color=c(
'maroon', 'purple', 'red', 'orange', 'yellow', 'lightgreen'))
g
addGeoCoord
尽管recharts
能够识别多数城市的坐标,但仍有一些坐标识别不了。同样,我们需要用addGeoCoord
添加坐标。
addGeoCoord
有求一个三列数据框,依次包含name
, longitude
和latitude
。注意lng
和lat
的顺序。
g %>% addGeoCoord(chinapm25[,c('name', 'lng', 'lat')]) %>%
setTitle('PM2.5 in China Cities', 'Fictious Data')
如果不知道某些地名的坐标怎么办?可以用geocode
(转自geoChina)。这个函数可通过Google (首先你得能访问Google)或百度 (需要有百度开发者密钥)。
geocode(c('北京', '上海'), api='google')
## lat lng
## 1 39.90281 116.4012
## 2 31.23236 121.4692
或geocode(c('北京', '上海'), api='baidu', key='xxxxx')
。
默认获得的是WGS-84坐标。如果要用于Echarts,需要用convWGS2BD
函数或geocode
(ocs
=‘BD-09’) 转为BD-09坐标。
convWGS2BD(geocode(c('北京', '上海'), api='google'))
## lat lng
## 1 39.91053 116.4138
## 2 31.23636 121.4803
或geocode(c('北京', '上海'), api='google', ocs='BD-09')
addMarkLine
和标注点addMarkPoint
在标注线addMarkLine
案例的基础上,用addMarkPOint
实现虚构百度迁徙的案例。
route <- flight$route
names(route) <- c('name1', 'name2')
coord <- flight$coord
target <- data.frame(
name1=c(rep('北京', 10), rep('上海', 10), rep('广州', 10)),
name2=c(
"上海","广州","大连","南宁","南昌","拉萨","长春","包头","重庆","常州",
"包头","昆明","广州","郑州","长春","重庆","长沙","北京","丹东","大连",
"福州","太原","长春","重庆","西安","成都","常州","北京","北海","海口"),
value=c(95,90,80,70,60,50,40,30,20,10,95,90,80,70,60,50,40,30,20,10,95,90,
80,70,60,50,40,30,20,10))
# series column mapping series of addML/addMP
target$series <- paste0(target$name1, 'Top10')
## apply addGeoCoord, and add markLines without values
g <- echartr(NULL, type='map_china') %>% addGeoCoord(coord) %>%
addML(series=1, data=route, symbol=c('none', 'circle'), symbolSize=1,
smooth=TRUE, itemStyle=list(normal=itemStyle(
color='#fff', borderWidth=1, borderColor='rgba(30,144,255,0.5)')))
## modify itemStyle of the base map to align the areaStyle with bgColor and
## disable `hoverable`
g <- g %>% setSeries(hoverable=FALSE, itemStyle=list(
normal=itemStyle(
borderColor='rgba(100,149,237,1)', borderWidth=0.5,
areaStyle=areaStyle(color='#1b1b1b'))
))
g
## add markLines with values
line.effect <- list(
show=TRUE, scaleSize=1, period=30, color='#fff', shadowBlur=10)
line.style <- list(normal=itemStyle(
borderWidth=1, lineStyle=lineStyle(type='solid', shadowBlur=10)))
g1 <- g %>%
addML(series=c('北京Top10', '上海Top10', '广州Top10'), data=target,
smooth=TRUE, effect=line.effect, itemStyle=line.style)
g1
## add markPoints
## series better be 2, 3, 4 rather than the series names
jsSymbolSize <- JS('function (v) {return 10+v/10;}')
mp.style <- list(normal=itemStyle(label=labelStyle(show=FALSE)),
emphasis=itemStyle(label=labelStyle(position='top')))
g2 <- g1 %>%
addMP(series=2:4, data=target[,c("name2", "value", "series")],
effect=list(show=TRUE), symbolSize=jsSymbolSize,
itmeStyle=mp.style)
g2
## setDataRange
g3 <- g2 %>%
setDataRange(
color=c('#ff3333', 'orange', 'yellow','limegreen','aquamarine'),
valueRange=c(0, 100), textStyle=list(color='#fff'),
splitNumber=0)
## setTheme
g3 <- g3 %>% setLegend(pos=10, selected='上海Top10', textStyle=list(color='#fff')) %>%
setTheme(palette=c('gold','aquamarine','limegreen'), bgColor='#1b1b1b') %>%
setToolbox(pos=3) %>%
setTitle('Baidu Migration', 'Fictious Data', pos=12,
textStyle=list(color='white'))
g3
构建一个虚构数据集,必须包含lng
, lat
和heat value
。
heatmap <- sapply(1:15, function(i){
x <- 100 + runif(1, 0, 1) * 16
y <- 24 + runif(1, 0, 1) * 12
lapply(0:floor(50 * abs(rnorm(1))), function(j){
c(x+runif(1, 0, 1)*2, y+runif(1, 0, 1)*2, runif(1, 0, 1))
})
})
heatmap <- data.frame(matrix(unlist(heatmap), byrow=TRUE, ncol=3))
str(heatmap)
## 'data.frame': 573 obs. of 3 variables:
## $ X1: num 111 111 112 111 112 ...
## $ X2: num 31.5 30.6 31.5 31.8 30.4 ...
## $ X3: num 0.612 0.453 0.418 0.256 0.193 ...
用addHeatmap
/ overideHeatmap
将热力图数据集添加/修改到echarts对象上。
echartr(NULL, type="map_china") %>% addHeatmap(data=heatmap)
参考相关函数,尽情探索吧。