我们之前讲过一次用gganimate
在R语言里面实现动图。
如何让你的基因放烟花?
当时我还看到有人用到了足球的数据上,

除了觉得炸裂,很好奇每个主球运动员代表的点所在的那个面积是什么意思。
问题放在心里,总会有答案,最近我知道了,那个是Voronoi图(维诺图)。
我们国家著名的奥林匹克水立方,他表面的那个格子就是维诺图。

这种格子也出现在了很多设计中


不过这些都是感性认识,最让我涨知识的是下面这一段话,他解答了我心中一个长久的疑惑:
我们常听电视台说一个地区的降雨量,那么这个地区是如何界定大小的?
下面是我的摘抄
荷兰气候学家A•H•Thiessen提出了一种根据离散分布的气象站的降雨量来计算平均降雨量的方法,即将所有相邻气象站连成三角形,作这些三角形各边的垂直平分线,于是每个气象站周围的若干垂直平分线便围成一个多边形。用这个多边形内所包含的一个唯一气象站的降雨强度来表示这个多边形区域内的降雨强度,并称这个多边形为泰森多边形。
http://muchong.com/html/201207/4675940.html
实际上泰森多边形仅仅维诺图在其中中的一个运用,维诺图在1908年就被提出。他是有意义的,他的绘制过程如下:
1.黑色是原点,又叫生成点
2.连接生成点,会得到很多三角形
3.每个三角形的边作垂直平分线
4.得到相交的点,连线得到维诺图

这时候,每一个小方块中只有一个生成点,方块中的任何一点到其对应的生成点的距离都小于到其他生成点的距离。
这个特性可以用来做疆域规划,比如我们国家每个省市的形状是否合理,跟省会的距离是否符合维诺图呢?有人画过这样的图
http://www.dataguru.cn/article-836-1.html

他还得出了一些建议:
- 内蒙古应该好好的规划一下,从东边到西边实在太远了,把西边的划给宁夏可能好点;东边划给北京、东三省;
- 河北北部,不论是属于北京还是天津都会好些
- 青海应该把甘肃的北部包括进去;
除了疆域规划,生物医学也有人用维诺图来研究毛细血管网对肌肉的供应。
而我关系的问题是,怎么画?既然已经知道了他的名字,那么检索起来就很方便,很快,我就知道,ggvoronoi
这个R包可以画。我喜欢gg
系列,就是因为他能更好地跟ggplot2
匹配。
https://cran.r-project.org/web/packages/ggvoronoi/vignettes/ggvoronoi.html
首先安装并加载R包
install.packages("ggvoronoi")
library(ggvoronoi)
生成数据
所需要的数据很简单,就是随机的点。我们这里根据官方教程生成在1:200之间波动的100个点,最终他们会出现在200*200的正方形区域。
x <- sample(1:200,100)
y <- sample(1:200,100)
points1 <- data.frame(x, y)
生成维诺图
library(ggplot2)
ggplot(points1,aes(x,y)) +
stat_voronoi(geom="path") +
geom_point()

上面的图还可以用以下代码实现
ggplot(points,aes(x,y)) +
geom_voronoi(fill=NA,color="black")
这里是把geom_voronoi
的填充fill
给去掉了,如果加上颜色,会对面积进行填充。
ggplot(points,aes(x,y)) +
geom_voronoi(fill="#4dffb8",color="black")

不过官方教程里面给出了更加精致的方案,设定一个变量,这个变量是图上的点到(100,100)这个点的距离,这样他就有了梯度,然后把这个变量放在aes
参数中,就实现了渐变效果。
points2 <- data.frame(x, y,
distance = sqrt((x-100)^2 + (y-100)^2))
ggplot(points2,aes(x,y)) +
geom_voronoi(aes(fill=distance),color="#4dffb8",size=.125) +
scale_fill_gradient(low="#4dffb8",high="black",guide=F)+
theme_void()

这个配色真是欲罢不能。用来做为PPT的背景也是很好的。

好了,明天见。其实我很怕突然间有一次说着明天见,但是不能相见。
网友评论