直方图
最后更新于:2022-04-01 20:04:41
直方图用于描述概率分布,D3 提供了直方图的布局 Histogram 用于转换数据。
[![501](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-17_57b41784c800b.png)](http://www.ourd3js.com/wordpress/wp-content/uploads/2014/12/501.png)
假设有数组 a = [10, 11, 11.5, 12.5, 13, 15, 19, 20 ],现在把10~20的数值范围分为5段,即:
10~12, 12~14, 14~16, 16~18, 18~20
那么数组 a 的各数值都落在这几段区域的哪一部分呢?经过计算,可以知道,这5段分别具有的元素个数为:
3, 2, 1, 0 , 2
将这个用图形展示出来的,就是直方图。好了,开始制作吧~
## 1. 数据
首先生成随机数据:
~~~
var rand = d3.random.normal(0,25);
var dataset = [];
for(var i=0;i<100;i++){
dataset.push( rand() );
}
~~~
d3.random.normal 生成一个函数,这个函数能够按正态(高斯)分布随机生成数值。要传入两个参数,第一个是位置参数,第二个是尺寸参数。关于正态分布的定义,可参见[维基百科](http://zh.wikipedia.org/wiki/%E6%AD%A3%E6%80%81%E5%88%86%E5%B8%83)。将这个函数赋值给 rand 之后,接下来只要用 rand() 即可生成随机数。
## 2. 布局(数据转换)
接下来,要将上述数据进行转换,即确定一个区间和分隔数之后,另数组的数值落在各区域里。先定义一个布局:
~~~
var bin_num = 15;
var histogram = d3.layout.histogram()
.range([-50,50])
.bins(bin_num)
.frequency(true);
~~~
- d3.layout.histogram: 直方图的布局
- range: 区间的范围
- bins: 分隔数
- frequency: 若值为 true,则统计的是个数;若值为 false,则统计的是概率
接下来即可转换数据:
~~~
var data = histogram(dataset);
~~~
来看看转换前后的数据有什么分别吧。转换前:
[![502](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-17_57b41784dc743.png)](http://www.ourd3js.com/wordpress/wp-content/uploads/2014/12/502.png)
转换后:
[![503](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-17_57b4178509651.png)](http://www.ourd3js.com/wordpress/wp-content/uploads/2014/12/503.png)
可以看到,转换后的数组,长度即分隔数,每一个区间内有落到此区间的数值(图中的0,1,2,...),数值的个数(length),还有三个参数:
- x: 区间的起始位置
- dx: 区间的宽度
- y: 落到此区间的数值的数量(如果 frequency 为 true);落到此区间的概率(如果 frequency 为 false)
## 3. 绘制
绘制之前,需要定义一个比例尺,因为通常我们需要让转换后的 y 在希望的范围内伸缩。
~~~
var max_height = 400;
var rect_step = 30;
var heights = [];
for(var i=0;i
';