
大卫克问到画椭圆围绕数据点。 前段时间我在这方面苦苦挣扎,这是我在真正知道自己在做什么的人的帮助下困惑的总结。 这里所有的错误都是我的,欢迎评论和更正!这张图片是 Bivariate 的输出,在脚本的最后生成。 该脚本的目标是计算绘制绿色椭圆的参数。 该脚本使用 JMP 的内置函数 Correlation、Mean、StdDev、Eigen 来完成工作。 特别是 Eigen 返回描述椭圆的参数。 这些参数被转换为 2D 3x3 变换矩阵,然后用于将 0,0 附近的单位圆上的点变换为所需的椭圆。
x = Open( "$sample_data\big class.jmp" );
H = x:height << get values; // column vectors
W = x:weight << get values;
data = H || W; // 2 columns by 40 rows
corr = Correlation( data );
mean = Mean( H ) || Mean( W );
stddev = Std Dev( H ) || Std Dev( W );
cov = Diag( stddev ) * corr * Diag( stddev );
{D, E} = Eigen( cov );
// sort columns of E. Don't know why; it controls which ellipse axis goes with the bigger vector, I think.
// you can see the gap in the ellipse change position if you use [1,2] (or just comment the next 3 lines)
jj = [2,1];
E = E[ 0, jj ];
D = D[ jj ];
// there seems to be a lot of opinions on how to do the confidence limit...
NormalContour = sqrt(ChiSquare Quantile( 0.95, 2 ));
T = NormalContour * E * Diag( Sqrt( D ) );
m = (T` |/ mean) || [0, 0, 1]; // transform matrix
unitCircle = J(100,3); // 2x2 transform uses 3x3 matrix for homogeneous coords
For( i = 1, i <= 100, i++,
unitCircle[i, 1] = Sin( (i - 1) * 2 * Pi() / 100 ); // divide by 99 to close the gap
unitCircle[i, 2] = Cos( (i - 1) * 2 * Pi() / 100 );
unitCircle[i, 3] = 1;
);
ellipse = unitCircle * m; // draw the ellipse as a unit circle transformed by m
New Window( "Ellipse from Eigen Values and Vectors",
Graph Box(xscale(50,75),yscale(40,180),
Marker( Marker State( 12 ), H, W ),
line( ellipse[0,1], ellipse[0,2])
)
);
// for comparison...
x<<BIVARIATE></BIVARIATE>

这是“手动”绘制的椭圆。 变换矩阵 m 也可用于(及其逆矩阵)将数据点转换为单位圆;对于椭圆内的点,距 0,0 的距离将小于 1。 请注意,双变量已经完成了所有工作,包括选择椭圆内部或外部的点。

如果您将变换矩阵与 JMP 的 Scene3D 一起使用,您可能需要转置“m”以匹配 Scene3D 对变换矩阵的期望。
编辑 2017 年 9 月 30 日:修复格式