对数刻度 returns NaN
Logarithmic scale returns NaN
我在 d3 中创建对数刻度时遇到问题。如果设置为线性,则比例可以正常工作。
这个有效:
var myLinScale = d3.scale.linear()
.domain([0, 100])
.range([50, 1150]);
console.log(myLinScale(71)); //output = 831
但是,这不起作用:
var myLogScale = d3.scale.log()
.domain([0, 100])
.range([50, 1150]);
console.log(myLogScale(71)); //output = NaN
对数刻度有什么问题?
新解决方案(使用 D3 v5.8)
经过 2 年多的时间,这个问题终于有了一个基于 D3 的答案,它不建议从域中删除 0,就像我在原始答案中所做的那样(见下文)。
这是可能的,因为新的 Symlog scale in D3 v5.8, based on a by-symmetric log transformation 允许域中的 0。
因此,使用您的域和范围而不做任何修改:
var myLogScale = d3.scaleSymlog()
.domain([0, 100])
.range([50, 1150]);
console.log(myLogScale(71));
<script src="https://d3js.org/d3.v5.min.js"></script>
甚至更短,使用 D3 v5.8 中的新比例构造函数:
var myLogScale = d3.scaleSymlog([0, 100], [50, 1150]);
console.log(myLogScale(71));
<script src="https://d3js.org/d3.v5.min.js"></script>
原始答案(针对 D3 v3)
更改您的域,使其不包含或越过零:
var myLogScale = d3.scale.log()
.domain([1e-6, 100])//domain doesn't include zero now
.range([50, 1150]);
console.log(myLogScale(71));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
在上面的演示中,我使用的是 1e-6
,即 0.000001
。
解释:
零的对数未定义(或未定义)。例如,在基数 10 中,log(0) 是一个数字 x
,因此 10 的 x
次方为零……当然,这个数字不存在。然而,当我们从正向接近零时,极限是负无穷大。
纯JavaScript:
console.log("Log of 0 is: " + Math.log(0))
因此,在JavaScript中,log(0)
是负无穷大,或负无穷大。
也就是说,根据 API:
a log scale must have either an exclusively-positive or exclusively-negative domain; the domain must not include or cross zero. (emphasis mine)
我在 d3 中创建对数刻度时遇到问题。如果设置为线性,则比例可以正常工作。
这个有效:
var myLinScale = d3.scale.linear()
.domain([0, 100])
.range([50, 1150]);
console.log(myLinScale(71)); //output = 831
但是,这不起作用:
var myLogScale = d3.scale.log()
.domain([0, 100])
.range([50, 1150]);
console.log(myLogScale(71)); //output = NaN
对数刻度有什么问题?
新解决方案(使用 D3 v5.8)
经过 2 年多的时间,这个问题终于有了一个基于 D3 的答案,它不建议从域中删除 0,就像我在原始答案中所做的那样(见下文)。
这是可能的,因为新的 Symlog scale in D3 v5.8, based on a by-symmetric log transformation 允许域中的 0。
因此,使用您的域和范围而不做任何修改:
var myLogScale = d3.scaleSymlog()
.domain([0, 100])
.range([50, 1150]);
console.log(myLogScale(71));
<script src="https://d3js.org/d3.v5.min.js"></script>
甚至更短,使用 D3 v5.8 中的新比例构造函数:
var myLogScale = d3.scaleSymlog([0, 100], [50, 1150]);
console.log(myLogScale(71));
<script src="https://d3js.org/d3.v5.min.js"></script>
原始答案(针对 D3 v3)
更改您的域,使其不包含或越过零:
var myLogScale = d3.scale.log()
.domain([1e-6, 100])//domain doesn't include zero now
.range([50, 1150]);
console.log(myLogScale(71));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
在上面的演示中,我使用的是 1e-6
,即 0.000001
。
解释:
零的对数未定义(或未定义)。例如,在基数 10 中,log(0) 是一个数字 x
,因此 10 的 x
次方为零……当然,这个数字不存在。然而,当我们从正向接近零时,极限是负无穷大。
纯JavaScript:
console.log("Log of 0 is: " + Math.log(0))
因此,在JavaScript中,log(0)
是负无穷大,或负无穷大。
也就是说,根据 API:
a log scale must have either an exclusively-positive or exclusively-negative domain; the domain must not include or cross zero. (emphasis mine)