log函数在图形映射中的妙用

王致远

2018/10/16

library(leaflet)
library(leafletCN)

今天在工作中遇到这样一个问题:将某数值映射到leaflet上点的颜色,比如数值越大红色越深,数值越小红色越浅。

我第一次是这样做的

reg <- leafletCN::leafletGeo("China")
pal <- colorNumeric("Reds",y$cars)
leaflet(y) %>% 
  addProviderTiles("OpenStreetMap.BlackAndWhite") %>% 
  addPolygons(data = reg, stroke = TRUE, smoothFactor = 1, fillOpacity = 0, weight = 1) %>% 
  addCircles(lng = ~lng,lat = ~lat,radius = ~cars/5,color = ~pal(y$cars))
## Warning in validateCoords(lng, lat, funcName): Data contains 61 rows with
## either missing or invalid lat/lon values and will be ignored

操作没啥大问题,但是由于数值差距太大,使得大数值的被映射为正常的红色,而小数值的是浅肉色,接近于底图的颜色,很不好分辨。

突然想起对数函数log能够将数值压缩到较小的区间,尝试之。

reg <- leafletCN::leafletGeo("China")
try(pal <- colorNumeric("Reds",log(y$cars)))

出现错误,看一看哪里错了

log(y$cars) %>% summary()
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    -Inf   8.726   9.512    -Inf  10.222  12.030

原来有负无穷值,也就是说原来的数据里有0值

summary(y$cars)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0    6158   13516   21262   27490  167793

果然如此,那就好办了,强行加个1!

summary(y$cars+1)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       1    6160   13516   21263   27491  167794

然后

reg <- leafletCN::leafletGeo("China")
pal <- colorNumeric("Reds",log(y$cars+1))
leaflet(y) %>% 
  addProviderTiles("OpenStreetMap.BlackAndWhite") %>% 
  addPolygons(data = reg, stroke = TRUE, smoothFactor = 1, fillOpacity = 0, weight = 1) %>% 
  addCircles(lng = ~lng,lat = ~lat,radius = ~cars/5,color = ~pal(log(y$cars+1)))
## Warning in validateCoords(lng, lat, funcName): Data contains 61 rows with
## either missing or invalid lat/lon values and will be ignored

完美解决~~