d3.js java_D3.js实现直方图的方法详解

本文介绍了直方图的概念及其在图像分析中的作用,通过D3.js库展示了如何生成直方图。首先,生成随机数据并利用d3.random.normal函数模拟正态分布。接着,通过d3.layout.histogram进行数据转换,定义区间范围、分隔数和频率。随后,创建比例尺以调整Y轴的伸缩,并绘制直方图的矩形、坐标轴及其分隔符。最后,文章总结了整个过程,旨在帮助读者理解和应用D3.js实现直方图。
摘要由CSDN通过智能技术生成

一、直方图简介

直方图就是一种照片的分析方式,横向代表亮度,纵向代表像素数量。首先分析出照片中所有像素的亮度,然后计算出具体数值,再把它们映射到横轴上。这样的话,越高,这个亮度上的像素就越多。

直方图的观看规则就是“左黑右白”,左边代表暗部,右边代表亮部,而中间则代表中间调。

纵向上的高度代表像素密集程度,越高,代表的就是分布在这个亮度上的像素很多。

直方图用于描述概率分布,D3 提供了直方图的布局 Histogram 用于转换数据。

d0db95fa3ee3912f1e7ee572eefda130.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

将这个用图形展示出来的,就是直方图。

好了,开始制作吧~

二、数据

首先生成随机数据:

var rand = d3.random.normal(0,25);

var dataset = [];

for(var i=0;i<100;i++){

dataset.push( rand() );

}

d3.random.normal生成一个函数,这个函数能够按正态(高斯)分布随机生成数值。要传入两个参数,第一个是位置参数,第二个是尺寸参数。关于正态分布的定义,可参见维基百科。将这个函数赋值给 rand 之后,接下来只要用 rand()即可生成随机数。

三、布局(数据转换)

接下来,要将上述数据进行转换,即确定一个区间和分隔数之后,另数组的数值落在各区域里。先定义一个布局:

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);

来看看转换前后的数据有什么分别吧。转换前:

bfd1f7c63e6bdd1abb41c1084fc08178.png

转换后:

5b9e07dc64fc3c0c8d2812b85b0bf639.png

可以看到,转换后的数组,长度即分隔数,每一个区间内有落到此区间的数值(图中的0,1,2,...),数值的个数(length),还

有三个参数:

x: 区间的起始位置

dx: 区间的宽度

y: 落到此区间的数值的数量(如果 frequency 为 true);落到此区间的概率(如果 frequency 为 false)

四、绘制

绘制之前,需要定义一个比例尺,因为通常我们需要让转换后的 y 在希望的范围内伸缩。

var max_height = 400;

var rect_step = 30;

var heights = [];

for(var i=0;i

heights.push( data[i].y );

}

var yScale = d3.scale.linear()

.domain([d3.min(heights),d3.max(heights)])

.range([0,max_height]);

最后,绘制图形:

//绘制图形

var graphics = svg.append("g")

.attr("transform","translate(30,20)");

//绘制矩形

graphics.selectAll("rect")

.data(data)

.enter()

.append("rect")

.attr("x",function(d,i){

return i * rect_step;

})

.attr("y", function(d,i){

return max_height - yScale(d.y);

})

.attr("width", function(d,i){

return rect_step - 2;

})

.attr("height", function(d){

return yScale(d.y);

})

.attr("fill","steelblue");

//绘制坐标轴的直线

graphics.append("line")

.attr("stroke","black")

.attr("stroke-width","1px")

.attr("x1",0)

.attr("y1",max_height)

.attr("x2",data.length * rect_step)

.attr("y2",max_height);

//绘制坐标轴的分隔符直线

graphics.selectAll(".linetick")

.data(data)

.enter()

.append("line")

.attr("stroke","black")

.attr("stroke-width","1px")

.attr("x1",function(d,i){

return i * rect_step + rect_step/2;

})

.attr("y1",max_height)

.attr("x2",function(d,i){

return i * rect_step + rect_step/2;

})

.attr("y2",max_height + 5);

//绘制文字

graphics.selectAll("text")

.data(data)

.enter()

.append("text")

.attr("font-size","10px")

.attr("x",function(d,i){

return i * rect_step;

})

.attr("y", function(d,i){

return max_height;

})

.attr("dx",rect_step/2 - 8)

.attr("dy","15px")

.text(function(d){

return Math.floor(d.x);

});

五、总结

以上就是这篇文章的全部内容了,希望能对大家的学习或者工作带来一定的帮助,如果有疑问大家可以留言交流。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值