我正在使用D3创建直方图JS脚本,这一切似乎都正常工作......除了垃圾箱的数量。
以下是我的代码的相关部分:
//Define the scales for the x and y attributes
var x = d3.scaleBand()
.range([0, width])
.padding(configProperties.barPadding);
var y = d3.scaleLinear()
.range([height,0]);
//Create the bins
var bins = d3.histogram()
.domain(d3.extent(data))
.thresholds(configProperties.binsCount)
(data);
console.log("number of bins: " + bins.length); //9
console.log("intended number of bins: " + configProperties.binsCount); //10
如果我将configProperties.binsCount设置为9,则bins.length仍为9。 如果我将configProperties.binsCount设置为14,则bins.length仍为9.
如果我将binsCount设置为15或更高,但是... bins.length输出23。
我对histogram.thresholds如何基于the documentation的工作原理的理解是,如果我给它一个值,它会将数据分成多个+ 1个相等的段(即多个二进制数)。但是,它似乎根本就没有这样做。我能找到的所有示例代码似乎表明我正确使用它,但我无法获得所需的箱数。
我也尝试使用d3.ticks作为阈值参数,但我遇到了同样的问题。
有什么我想念的吗?这与我的域名有关吗?提前致谢。
答案 0 :(得分:1)
您将计数(即简单数字)传递给thresholds
函数,不数组。
您所看到的是传递号码时的预期行为。根据{{3}}:
如果指定了一个计数而不是一个阈值数组,那么该域将被统一划分为大约计数二进制位;
让我们在这个演示中看到它:
var data = d3.range(100);
const histogram = d3.histogram()
.value(d => d)
.thresholds(5);
var bins = histogram(data);
console.log("The number of bins is " + bins.length)
<script src="https://d3js.org/d3.v4.js"></script>
如您所见,count
为5,箱数也为5。
但是,如果传递数组,则行为符合您的预期:bin的数量将为 array.length + 1:
阈值定义为值数组[x0,x1,...]。任何小于x0的值都将放在第一个bin中;任何大于或等于x0但小于x1的值都将放在第二个bin中;等等。因此,生成的直方图将具有thresholds.length + 1个bin。
以下是演示:
var data = d3.range(100);
const histogram = d3.histogram()
.value(d => d)
.thresholds([10, 30, 50, 70, 90]);
var bins = histogram(data);
console.log("The number of bins is " + bins.length)
<script src="https://d3js.org/d3.v4.js"></script>
如您所见,数组有5个值,bin的数量为6。
最后,请记住,实际的数量取决于您传递给直方图生成器的数据。这解释了您在问题中描述的其他结果。
答案 1 :(得分:1)
我意识到这有点老了,Gerardo解释了如何做你所要求的,但他并没有真正回答为什么这个问题。所以,如果有其他人遇到这个问题并且很好奇,那么就是这样。如果您将一个数字传递给阈值函数,D3会找到一个接近该数字的多个二进制数,这样阈值就会很好[&#39;数字。并且选择那些“好”的#39;导致箱数不同于您指定的数量的数字。
因此,如果您的数据从0到24.37,并且您请求8个区间,则阈值不会是3.481428571428 ...(= 24.37 /(8-1))的倍数。相反,D3会挑选一个“好”的东西。最大值为25,阈值为2.5的倍数(10个箱子)或5的倍数(5个箱子)。这些数字在图表上显示得更好,并且是人们在手工制作直方图时可能选择的数字。