【问题标题】:Why is d3.histogram merging the last two bins of this chart?为什么 d3.histogram 会合并此图表的最后两个 bin?
【发布时间】:2017-03-27 01:05:07
【问题描述】:

在我正在处理的这个 D3 图表中,我有一个包含 60 个非线性模式的元素(101-110;201-210;301-310;401-410;501-510 和 601- 610——第一位代表季节,后两位代表最后两位)。

我可以完美地呈现图表,但最后一个栏被合并到它之前的一个:

(忽略x轴标签都搞砸的事实。)

知道为什么会这样吗?是因为我完全曲解了直方图的含义,还是什么?

完整示例代码here

【问题讨论】:

    标签: javascript d3.js histogram


    【解决方案1】:

    你是对的:你完全歪曲了直方图的含义!这应该是一个条形图。

    条形图本质上是由代表分类变量的条形组成的。这意味着条形图位于代表分类变量(即定性变量)的标签上。条形图和直方图都使用矩形对数据进行编码,但在直方图中,与条形图不同,标签表示定量变量。这是很常见的,如果你在网上搜索,找到实际上是条形图的“直方图”,或者实际上是直方图的“条形图”。

    回到您的问题:可以将直方图保留在一个 hacky 解决方案中:您只需定义 domain

    如果指定了域,则将域访问器设置为指定的函数或数组并返回此直方图生成器。

    所以,你的直方图生成器应该是这样的:

    const histogram = d3.histogram()
        .value(d => d.death)
        .domain([0, 1000])//in your case: [101 or less, more than 610]
        .thresholds(x.domain());
    

    (我在这里使用幻数只是为了说明这个想法,请相应地更改它们)

    这是更新后的代码:https://www.webpackbin.com/bins/-KgCh8IjK6J56Dj_SA9X

    分析

    显然,当值与阈值一致时,d3.histogram 不会创建最后一个 bin。根据文档,应该创建最后一个 bin,因为 x1(每个 bin 的最大值)不包含在内。

    让我们看看这个sn-p:

    var data = d3.range(10);
    
    const histogram = d3.histogram()
      .value(d => d)
      .thresholds(data);
    
    var bins = histogram(data);
    
    console.log(bins)
    <script src="https://d3js.org/d3.v4.js"></script>

    您可以看到 8 和 9 一起放在最后一个 bin 中。

    其他阈值不会发生同样的事情。一、thresholdFreedmanDiaconis

    var data = d3.range(100);
    
    const histogram = d3.histogram()
      .value(d => d)
      .thresholds(d3.thresholdFreedmanDiaconis(data, d3.min(data), d3.max(data)));
    
    var bins = histogram(data);
    
    console.log(bins)
    <script src="https://d3js.org/d3.v4.js"></script>

    那么,thresholdScott

    var data = d3.range(100);
    
    const histogram = d3.histogram()
      .value(d => d)
      .thresholds(d3.thresholdScott(data, d3.min(data), d3.max(data)));
    
    var bins = histogram(data);
    
    console.log(bins)
    <script src="https://d3js.org/d3.v4.js"></script>

    最后,thresholdSturges

    var data = d3.range(100);
    
    const histogram = d3.histogram()
      .value(d => d)
      .thresholds(d3.thresholdSturges(data, d3.min(data), d3.max(data)));
    
    var bins = histogram(data);
    
    console.log(bins)
    <script src="https://d3js.org/d3.v4.js"></script>

    【讨论】:

    • 那个更新的例子不起作用,但我完全明白你在说什么,这也完全有效。非常感谢你,我已经为此扯了很多年的头发了!知道为什么它会表现出这种行为吗?您链接到的相同文档指出,当未定义时,域是extent;直方图生成器的本质是它不包括最后一个(也可能是第一个)值吗?
    • 这很有趣,更新后的示例对我有用。我添加了一些 sn-ps 以更好地探索这一点,看看。好吧,关于你的最后一个问题,我不能说这是期望的行为还是错误。我相信你应该打开一个 GitHub 问题,这样 Bostock 自己就可以解释这里发生了什么。
    • 太棒了,感谢您的深入探索!将打开一个问题!
    • 不用担心。请,如果您打开问题,请在此处粘贴链接,我想查看 Bostock 的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    • 2015-10-20
    • 1970-01-01
    • 1970-01-01
    • 2015-02-04
    相关资源
    最近更新 更多