Javascript D3 直方图:产生错误数量的 bin 的阈值

use*_*002 2 javascript data-visualization histogram d3.js

我正在使用 D3 创建直方图 JS 脚本,它似乎一切正常……除了 bin 的数量。

以下是我的代码的相关部分:

//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
Run Code Online (Sandbox Code Playgroud)

如果我将 configProperties.binsCount 设置为 9,bins.length 仍然是 9。如果我将 configProperties.binsCount 设置为 14,bins.length 仍然是 9。

如果我将 binsCount 设置为 15 或更高,但是... bins.length 输出 23。

我根据文档对 histogram.thresholds 如何工作的理解是,如果我给它一个值,它会将数据分成许多 + 1 个相等的部分(即许多 bin)。然而,它似乎根本没有这样做。我能找到的所有示例代码似乎都表明我正在正确使用它,但是我无法获得所需的 bin 数量。

我也试过使用d3.ticks作为阈值参数,但我遇到了同样的问题。

有什么我想念的吗?跟我的域名有关系吗?提前致谢。

Ger*_*ado 5

您将一个计数(即一个简单的数字)传递给函数thresholds而不是一个数组。

\n\n

您所看到的是传递数字时的预期行为。根据相同的文档

\n\n
\n

如果指定计数而不是阈值数组,则域将被均匀地划分为近似计数仓;

\n
\n\n

让我们在这个演示中看看:

\n\n

\r\n
\r\n
var data = d3.range(100);\r\n\r\nconst histogram = d3.histogram()\r\n  .value(d => d)\r\n  .thresholds(5);\r\n\r\nvar bins = histogram(data);\r\n\r\nconsole.log("The number of bins is " + bins.length)
Run Code Online (Sandbox Code Playgroud)\r\n
<script src="https://d3js.org/d3.v4.js"></script>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n\n

正如你所看到的,count是 5,bin 的数量也是 5。

\n\n

但是,如果您传递array,则行为符合您的预期:bin 的数量将为array.length + 1:

\n\n
\n

阈值定义为值数组 [x0, x1, \xe2\x80\xa6]。任何小于 x0 的值都将被放入第一个 bin 中;任何大于或等于 x0 但小于 x1 的值都将被放入第二个 bin 中;等等。因此,生成的直方图将具有thresholds.length + 1 bin。

\n
\n\n

这是演示:

\n\n

\r\n
\r\n
var data = d3.range(100);\r\n\r\nconst histogram = d3.histogram()\r\n  .value(d => d)\r\n  .thresholds([10, 30, 50, 70, 90]);\r\n\r\nvar bins = histogram(data);\r\n\r\nconsole.log("The number of bins is " + bins.length)
Run Code Online (Sandbox Code Playgroud)\r\n
<script src="https://d3js.org/d3.v4.js"></script>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n\n

如您所见,数组有 5 个值,bin 数量为 6。

\n\n

最后,请记住,实际的箱数取决于您传递给直方图生成器的数据。这解释了您在问题中描述的其他结果。

\n


Dav*_*ist 5

我意识到这有点老了,Gerardo 解释了如何做你问的事情,但他实际上并没有回答这个问题的原因。所以这就是,以防其他人遇到这个问题并且很好奇。如果您将一个数字传递给阈值函数,D3 会找到一些接近该数字的 bin,从而使阈值成为“不错”的数字。选择那些“不错”的数字会导致 bin 数量与您指定的数量不同。

因此,如果您的数据从 0 变为 24.37,并且您请求 8 个 bin,则阈值不会是 3.481428571428...(= 24.37 / (8-1))的倍数。相反,D3 将选择一个“不错”的最大值 25,阈值将是 2.5 的倍数(制作 10 个箱子)或 5 的倍数(制作 5 个箱子)。这些数字更适合显示在图表上,如果人们手工制作直方图,他们可能会选择这些数字。