作者:李誉辉
四川大学在读研究生
这次,我们接着上一篇讲
将变量映射到颜色是地理信息可视化的一个重要组成部分。
为了实现数值映射到颜色色值,leaflet中内置了一些color*
开头的函数,
非常方便将数值变量与颜色进行匹配,然后产生一个palette函数。
这些palette函数, 能够根据输入数字向量返回一个ARGB颜色空间的向量。
ARGB颜色空间与HEX颜色空间类似,如“#AARRGGBB”中,前2个十六进制的数代表透明度,
后面三组数字分别代表Red, green, blue。具体见(https://coderwall.com/p/dedqca/argb-colors-in-android)。leaflet
中有4个palette生成函数。
colorNumeric()
,colorBin()
和colorQuantile()
,(均针对连续数字变量)。colorFactor()
,(针对类别型变量)。
使用方法如下:
1library(leaflet)
2
3# 调动颜色函数,生成一个palette函数
4pal <- colorNumeric(c("red", "green", "blue"), 1:10)
5# 给色板函数传进一个数字向量,返回颜色色值向量。
6pal(c(1, 6, 9))
1## [1] "#FF0000" "#52E74B" "#6754D8"
7.1
公共参数
4个颜色函数拥有几个公共参数:palette
和domain
。palette
参数用于指定要与数据匹配的颜色向量,有下面几种指定形式:
RColorBrewer
包中palette的名字,eg: “RdYlBu”, “Accent”, “Greens”。viridis
中的palette的名字,如:“viridis”, “magma”, “inferno”, “plasma”。颜色向量,可以由色条函数生成,也可HEX色值组成的向量。
如:palette()
,topo.colors(10)
,c("#000000", "#0000FF", "#FFFFFF")
。其它使用0到1之间的数字生成颜色向量的函数,
如:colorRamp(c("#000000", "#FFFFFF"), interpolate = "spline")
domain
参数用于确定输入值的范围。
可以指定domain = NULL
,则生成的palette函数没有预设范围,
当调用该palette函数时,会根据传入数据自动确定范围。
但当对不同数据应用同一个palette函数多次,最好具体指定domain
参数为非null, 这样数据与颜色才会匹配。
alpha
用于指定透明度。reverse
,为逻辑值,用于翻转颜色与输入数字变量的匹配顺序。
7.2
连续数字变量
1library(leaflet)
2library(rgdal)
3
4filepath <- "E:/R_input_output/data_input/JSON/TopoJson/China.json"
5# filepath <- 'E:/R_input_output/data_input/JSON/GeoJSON/China.geojson' #
6# 结果一样
7China_map <- readOGR(filepath, stringsAsFactors = FALSE)
8# China_map <- geojsonio::geojson_read(filepath,what = 'sp') # 结果一样
9Encoding(China_map@data$name) <- "UTF-8" # 纠正中文字符乱码
10
11# 编造GDP向量
12set.seed(234)
13values_fabricate <- runif(34, 0.1, 0.9) * 2000 # 全国34个行政区
14China_map$GDP_fabricate <- c(values_fabricate, NA) # 经过China_map$name查询最后一个为占位
15
16map_draw <- leaflet(China_map) %>% setView(lng = 106.33, lat = 29.35, zoom = 3.5) # 以重庆城区经纬度为中心
1## OGR data source with driver: GeoJSON
2## Source: "E:\R_input_output\data_input\JSON\TopoJson\China.json", layer: "中国"
3## with 35 features
4## It has 11 fields
7.2.1 连续型数据,连续型颜色(colorNumeric()
)
首先,我们尝试将GDP值与RColorBrewer中的“Blues”色条进行匹配。
我们使用colorNumeric()
函数创建一个映射函数。
“Blues”色条是仅仅包含9种颜色的离散色板,但是colorNumeric()
函数能够插值然后返回连续性色板。
palette参数仅仅是一个颜色向量,只需要注意其中的元素顺序。不一定非要RColorBrewer色板,其它也行,
甚至自定义都行,如: c("white", "navy")
或c("#FFFFFF", "#000080")
,
palette长度不等,长度为3也行,这样适合多级渐变,如diverging palette两极渐变。
甚至可以传递一个函数,指定数值在[0, 1]区间外应该返回的颜色。
第2个参数,domain
, 用于指定与颜色向量匹配的输入数字。
对于colorNumeric()
而言,可以用数字指定范围(最大值/最小值),也可以用数字向量指定。colorNumeric()
函数返回的结果,pal
色条函数,
可以接受在range(countries$gdp_md_est)
范围内的数字向量,
然后返回ARGB格式的颜色向量。
1library(leaflet)
2library(rgdal)
3
4Npal <- colorNumeric(palette = "YlGnBu", domain = China_map$GDP_fabricate)
5
6map_draw %>% addPolygons(stroke = TRUE, smoothFactor = 0.3, fillOpacity = 0.8,
7 color = ~Npal(GDP_fabricate)) # 默认fillColor = color
7.2.2 连续型数据,离散型颜色(colorBin()
, colorQuantile()
)
colorBin()
相当于对数据切片分箱,将数字性向量数据与固定数量的颜色输出相匹配。
可以通过指定breaks分割点来分箱,也可以指定分箱数来分箱,通过参数bin
。
注意在按分箱数分箱时,如果pretty = TRUE
(默认),
将得到nice round的分割点,但是可能分箱数并不非你指定的。
1library(leaflet)
2
3Bpal <- colorBin(palette = "Blues", China_map$GDP_fabricate, 6, pretty = FALSE)
4
5map_draw %>% addPolygons(stroke = FALSE, smoothFactor = 0.2, fillOpacity = 1,
6 color = ~Bpal(GDP_fabricate))
colorQuantile()
同样是对输入数据进行分箱,只是每个子集中的observation数量相等,
默认分成4个箱子,5个breaks。
1library(leaflet)
2
3Qpal <- colorQuantile("Blues", China_map$GDP_fabricate, n = 7)
4map_draw %>% addPolygons(stroke = FALSE, smoothFactor = 0.2, fillOpacity = 1,
5 color = ~Qpal(GDP_fabricate))
7.3
类别型数据着色
对于类别型数据(categorical data), 使用colorFactor()
函数生成色板函数。
如果palette包含的颜色数量与因子水平一致,则为一一对应匹配。
否则,palette中的颜色将会进行插值,然后产生合适数量的颜色。
可以通过给domain
参数指定一个因子或字符串向量,或直接用levels
参数指定因子水平。levels
参数优先级比domain
更高,如同时指定,则会忽略domain
参数
1library(leaflet)
2
3# 生成一些随机levels
4China_map$category <- as.factor(c(sample.int(5L, 34, TRUE),NA))
5
6Fpal <- colorFactor(topo.colors(5), China_map$category) # 因为是因子对象,第2个参数与levels参数匹配
7
8leaflet(China_map) %>%
9 setView(lng = 106.33, lat = 29.35, zoom = 3.5) %>% # 以重庆城区经纬度为中心%>%
10 addPolygons(stroke = FALSE, smoothFactor = 0.2, fillOpacity = 1,
11 color = ~Fpal(category))
Leaflet包中,创建图例也非常方便,
这个小节中,我们将在Colors小节基础上创建图例。
使用addLegend()
函数添加图例,最方便的方法是:
将colorNumeric()
等函数产生的色板函数指定给addLegend()
函数中的pal
参数, 然后指定values
参数,
就会自动计算图例箱体的颜色和刻度标签。
1library(leaflet)
2library(rgdal)
3
4filepath <- "E:/R_input_output/data_input/JSON/TopoJson/China.json"
5# filepath <- "E:/R_input_output/data_input/JSON/GeoJSON/China.geojson" # 结果一样
6China_map <- readOGR(filepath, stringsAsFactors = FALSE)
7# China_map <- geojsonio::geojson_read(filepath,what = "sp") # 结果一样
8Encoding(China_map@data$name) <- "UTF-8" # 纠正中文字符乱码
9
10# 编造GDP向量
11set.seed(234)
12values_fabricate <- runif(34, 0.1, 0.9) * 2000 # 全国34个行政区
13China_map$GDP_fabricate <- c(values_fabricate, NA)# 经过China_map$name查询最后一个为占位
14
15map_draw <- leaflet(China_map) %>%
16 setView(lng = 106.33, lat = 29.35, zoom = 3.5) # 以重庆城区经纬度为中心
17
18Npal <- colorNumeric(palette = "YlGnBu", domain = China_map$GDP_fabricate)
19
20map_draw %>%
21 addPolygons(stroke = FALSE, smoothFactor = 0.2, fillOpacity = 1,
22 color = ~Npal(GDP_fabricate)) %>%
23
24 addLegend("bottomright", pal = Npal, values = ~GDP_fabricate, # 生成图例
25 title =