使用d3和numericjs在javascript中绘制错误椭圆

时间:2015-04-02 20:17:36

标签: javascript d3.js computer-vision data-analysis jstat

我试图在javascript中实现this方法来绘制协方差错误省略号。

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中绘制错误/置信省略号的任何示例。

我正在使用库numericjs作为特征向量和值,jstat和d3用于绘图。

Here is a plnkr使用当前代码。

errorEllipse函数位于“script.js”文件中。可以通过编辑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()返回的。

1 个答案:

答案 0 :(得分:2)

原始问题是我在绘图时没有缩放椭圆的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;
}