2015-04-02 54 views
0

我試圖落實在JavaScript繪製協方差誤差橢圓this方法。繪製在JavaScript與D3的誤差橢圓和numericjs

errorEllipse = function(stdDevX, stdDevY, cor, center, level) { 
    var errEllipse, 
    cov = cor * stdDevX * stdDevY, 
    covmat = [ 
    [stdDevX * stdDevX, cov], 
    [cov, stdDevY * stdDevY] 
    ], 
    eig = numeric.eig(covmat), 
    scale = Math.sqrt(jStat.chisquare.inv(level, 2)), 
    maxLambdaI = indexOfMax(eig.lambda.x), 
    minLambdaI = indexOfMin(eig.lambda.x), 
    rx = stdDevX > stdDevY ? Math.sqrt(eig.lambda.x[maxLambdaI]) * scale : Math.sqrt(eig.lambda.x[minLambdaI]) * scale, 
    ry = stdDevY > stdDevX ? Math.sqrt(eig.lambda.x[maxLambdaI]) * scale : Math.sqrt(eig.lambda.x[minLambdaI]) * scale, 
    v1 = eig.E.x[maxLambdaI], 
    theta = Math.atan2(v1[1], v1[0]) * 180/Math.PI; 

    if (theta < 0) { 
    theta += 360; 
    } 
    //make the ellipse object 
    errEllipse = { 
    rx: rx, 
    ry: ry, 
    cx: center.x, 
    cy: center.y, 
    orient: -theta 
    }; 

    return errEllipse; 
}; 

我在當前嘗試的結果中看到的最明顯的問題是橢圓不符合數據。很難找到我要出錯的地方。

任何人都可以告訴我: 1.)我如何得到或繪製橢圓的半徑和角度有什麼問題。 或 2.)在javascript中繪製錯誤/置信橢圓的任何示例。

我使用的特徵值和值,jstat和D3密謀庫numericjs。

Here is a plnkr與當前代碼。

的errorEllipse功能處於「的script.js」 file.Test數據可以通過編輯testData.js改變。

更新:

我加入的代碼,繪圖與D3橢圓的情況下,即其中的問題是:

svg.append('ellipse') 
    .attr('class', 'q-ellipse-99') 
    .attr('rx', Math.abs(xScale(xExtent[0] + ellipse99.rx) - xScale(xExtent[0]))) 
    .attr('ry', Math.abs(yScale(yExtent[0] + ellipse99.ry) - yScale(yExtent[0]))) 
    .attr('transform', 'translate(' + xScale(ellipse99.cx) + ',' + yScale(ellipse99.cy) + ')rotate(' + ellipse99.orient + ')'); 

無論是xExtent和yExtent陣列從調用返回數據上的d3.extent()。

+0

飛度其實不壞。一切似乎都沒問題,我認爲省略號不符合數據的原因是你可以在右上角看到一堆異常值。 – xEviL 2015-09-07 13:03:34

+0

感謝您的評論。幾乎忘了這一點。我認爲也可以。用一些其他數據測試它。最初發布時,我認爲問題出現在d3可視化方面。從此修復了這個plnkr。接受。 – BPhlin 2015-09-08 13:54:39

回答

1

原來的問題是,打印時我沒有縮放橢圓形的RX和RY值。似乎現在使用上面的代碼(在更新下)可以正常工作。這是一個fork of plnkr,它使用隨機正常測試數據(下面)。

function genTestData(numPoints){ 
    var data = {x:[], y:[]}; 
    for(var i = 0; i < numPoints; i++){ 
    data.x[i] = jStat.normal.inv(Math.random(), 8.5, 2); 
    data.y[i] = jStat.normal.inv(Math.random(), 6.5, 3); 
    data.y[i] += data.x[i] * 2.1; //to test ellipse 
    } 
    return data; 
}