我有一个数组中的数据集,范围从 0.00164737 到 0.0021966
What I am trying to do is get the shape fixed by logarithmic scale, then to normalize it ready for drawing on the canvas. Say normalized to 0,100 or -100,0,100 so I can work in pixels
要在 0-100 之间简单地归一化(不执行日志函数),这在 for 循环中非常有效:
normalized[i] = ( ( close[i] - min ) / dif ) * 100;
dif 是封闭数组的最大值减去它的最小值 toFixed(7)
我不是数学家,但我认为我对日志部分“有点接近”,尽管我只在规范化期间应用日志函数时看到视觉上的差异。这显然打乱了归一化,它还会产生 Infinity 或 -Infinity 以及非常不必要的大数
请注意,图表现在不再以像素为单位进行管理,因为它没有正确地位于 Canvas 上,所以为了看看我做了什么,我在所有 y 点上添加 150 以使其可见
所以当我这样做时,我通过应用对数函数来破坏/改变同一行上的东西(我知道这部分是错误的)
function logWithBase(n,b){return Math.log(n)/Math.log(b);}
像这样改变行:
normalized[i] = logWithBase( ( close[i] - min ) / dif , 10 ) * 100;
以下是我尝试使其对数化前后的一小部分数据:
之前:
0: "0.00168927"
1: "0.00168742"
2: "0.0016818"
3: "0.00168124"
4: "0.00168067"
5: "0.0016805"
6: "0.00168657"
7: "0.00168362"
8: "0.00166886"
9: "0.00165052" // < why does 0.00165 cause -Infinity
10: "0.0016647"
11: "0.00166251"
12: "0.00166664"
13: "0.00167196"
14: "0.00167084"
15: "0.00167667"
之后的相同集合:
0: 38.93017025063121
1: 36.805636182304255
2: 29.629674005179268
3: 28.845120702345767
4: 28.03173121401521
5: 27.786162417624155
6: 35.79352647194307
7: 32.08579894397015
8: 6.4429326997987175
9: -Infinity // < WOW!!
10: -4.729377348896662
11: -12.015082123716525
12: 0.8395033133056131
13: 13.225477668471285
14: 10.8953699275865
15: 21.850168886727374
这里可能有相关线索
如果我得到 min 和 max/2 之间的差异(我可能会因此得到不好的分数)并将其用作我的基础(在我进行简单归一化之前),我会看到图表颠倒...
var logclose = [];
var base = ( Math.max.apply(this,close) - Math.min.apply(this,close) ) / 2;
for( var i = close.length - 1; i >= 0; i-- ){
logclose[i] = logWithBase( close[i] , base );
}
close=logclose;
结论;我认为最后一个示例说明基数应该以某种方式与数组编号范围相关,因为它确实有影响。
我如何驯服对数而不是大得离谱的数字,然后将其归一化以适合 Canvas 区域?
Please do not recommend I use a library (I prefer vanilla JavaScript where it can be used, plus, I would very much like to grasp this proccess)
编辑,这里是代码:
var close=[data]; // for example data see this question (line: 19) as the full data will not fit here (over 10000 entries)
//###
var max=Math.max.apply(this,close);
var min=Math.min.apply(this,close);
var dif=(max-min).toFixed(7);
var normalclose=[];
var logAttemptClose=[];
function logWithBase(n,b){return Math.log(n)/Math.log(b);}
for(var i=close.length-1;i>=0;i--){
normalclose[i]=((close[i]-min)/dif)*100;
logAttemptClose[i]=logWithBase( ( close[i] - min ) / dif , 10 ) * 100; // <-- here bad code
}
//drawing to canvas
var top=100;
var x=1000-100;
var pen=[];
pen[0]=document.getElementById("chart");
pen[0]=pen[0].getContext("2d");
pen[0].clearRect(0,0,1000,300);
pen[0].beginPath();
pen[0].moveTo(x,normalclose[normalclose.length-1]+top);
for(var i=close.length-1;i>=0;i--){
x=x-(2);
pen[0].lineTo(x,normalclose[i]+top);
}
pen[0].strokeStyle='#000000';
pen[0].stroke();
最佳答案
明白了!
好吧,这不是最好的解决方法,但它确实有效!如果有人可以做得更好,请发帖..
将此添加到上面代码的第 2 行(注释“###”所在的位置):
var Lmax=Math.max.apply(this,close);
var Lmin=Math.min.apply(this,close);
var Ldif=(Lmax-Lmin);
var Logar=[];
var infinity=[];
for(var i=close.length-1;i>=0;i--){
Logar[i]=Math.log((close[i]-Lmin)/Ldif);
if(Logar[i]===-Infinity){infinity.push(i);}
}
close=Logar;
现在我们有了对数尺度的数组,但总有 -Infinity 在某处,所以我们将其删除。在下一行写...
for(var i=0;i<=infinity.length-1;i++){close.splice(infinity[i],1);
然后我们可以继续代码以进行简单的规范化,我们有一个漂亮的新日志图表:
关于javascript - 管理用于 HTML Canvas 的对数数组数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25666864/