plot error ellipse

It would be nice to have an option to plot error ellipses instead of error bars or boxes for individual points.

It would be even nicer if one could select a wave of covariances or correlation coefficients and have the ellipses plotted accordingly...

It would, wouldn't it? It's an obvious extension of error bars. I will put it on the wish list for IP10.

I sent a note to your personal email from a time a few years ago when you contacted us. Maybe its out of date. In any case, I said this:

I'm thinking about this topic... no promises, though. I'm doing a bit of reading.

How would error ellipse info be transmitted to Igor's error bar code? Perhaps a three-column wave with sigma_x, sigma_y, covariance? Then the error bar specification would include the desired confidence interval? Or would some other format be preferable- like three columns with major axis, minor axis and angle? That would put extra computation on your end if what you have is a covariance matrix, but would perhaps be more flexible.
 

I would suggest three waves holding sigmaX, sigmaY and correlation coefficient (or covariance as an alternative option), since we already supply sigmaX and sigmaY as separate waves. If a confidence level is given, then plot as confidence ellipses, otherwise as an "error ellipse" that represents the sigma level as supplied (so 95.45% if the selected error waves contain 2-sigma errors).

An option for filled ellipses (matching the color of the plotted point) would be nice.

I don't think that axes and angles are useful for the standard dialog input. As an additional option for commandline use that could be interesting, but for users wanting to plot their data with known correlated errors it would be better to have Igor make the calculation correctly.

My reference point for this is software used in isotope geochemistry, where measured isotope ratios often have strongly correlated errors. Isoplot is a venerable but deprecated excel plugin and IsoplotR is a port of Isoplot to R.

Note that I have no clue about statistics, other users may have better suggestions.

I think you are using an out-of-date email address! I'll copy this to an email.

Thanks, Tony. That's helpful. I hope others will see this thread and comment. I can't believe you're the only one that wants this. Perhaps someone has written some sort of procedure to do it.

Writing a procedure to calculate the ellipse for a point/error/covariance/confidence is one thing, but dealing with the plotting and keeping things synced is non-trivial in a roll-your-own procedure. It would perhaps be easier to do if drawing objects could be rotated.

If I were going to attempt it I would put a dummy wave in a package folder for each graph/trace combination that has ellipses plotted, set up a dependence on the input waves to fire a plot update, maybe think about some kind of hook to clean up when a trace is removed from a plot and keep the ellipse wave plotted in sequence with the data. The ellipses would be plotted as outlines based on x-y coordinates stored in a wave.

But I would much rather wait for this to appear in the "What's new in Igor 11" help file.

If I'm still working at Igor 11...

I only mentioned a procedure in hopes that someone has already worked out all the math! Indeed, keeping the graph properly updated is easier internally than in procedure code.

You *can* rotate draw elements. The documentation is somewhat confusing, but check out the "rotate" keyword for SetDrawEnv.

You can even rotate stuff by dragging with the mouse- hover just outside a handle on a drawing object. The cursor will change to a diagonal pair of arrows. When that happens, you can click and drag to rotate. Naturally, that's not quantitatively accurate :)

As I'm just writing some drawing code. You can also rotate about an arbitrary point using a coordinate systems of your choice.

In reply to by thomas_braun

I did try to rotate an ellipse by hand before posting, but I didn't notice the diagonal arrows. They aren't very easy to summon!

Here is how I have calculated an error ellipse. I'm sure that there are better ways to code this. Neither stats nor linear algebra are my strong points.

// returns a 2-column free wave containing x-y coordinates
function /wave ErrorEllipse(pointX, pointY, sigmaX, sigmaY, correlation, probability)
    variable pointX, pointY, sigmaX, sigmaY, correlation, probability
   
    variable covariance=correlation*sigmaX*sigmaY
    // create covariance matrix
    Make /free Mcovar={{sigmaX^2,covariance},{covariance,sigmaY^2}}
    // calculate eigenvectors and eigenvalues
    MatrixEigenV /SYM/EVEC Mcovar
    wave W_eigenValues, M_eigenVectors
    // scale eigenvalues (Mahalanobis scale factor)
    W_eigenValues*=StatsInvChiCDF(probability, 2)
    // create a 2 row 2D wave and calculate error ellipse
    Make /free/n=(2,181) ellipse
    SetScale /i y, 0, 2*Pi, ellipse
    ellipse = p==0 ? cos(y)*sqrt(W_eigenValues[0]) : sin(y)*sqrt(W_eigenValues[1])
    MatrixOP /o/free ellipse = M_eigenVectors x ellipse
    // center ellipse at point
    ellipse += p==0 ? pointX : pointY
    MatrixOP /o/free ellipse = ellipse^t
    return ellipse
end

 

Cool, Tony! I knew I could goad you into doing something like that :)

At some point I will take a look at it and see what can be done internally.

I'm part way there. See the attachment.

I have options to use sigmaX, sigmaY and correlation, or varianceX, varianceY and covariance.

I am also contemplating taking in a, b and theta so that you can have complete control over the ellipses. I'm a bit concerned, though- seems like a and b should be in axis coordinates, but in fact, they are some weird combination of the axes. I suppose it would really only be valid if the axes were in the same units. Any opinion?

ErrorEllipses.png (73.95 KB)

Would it ever be valid to use error ellipses on log axes? Would you plot weirdly non-elliptical ellipses? Perhaps there would be cases where a non-distorted ellipse might represent errors in log space, but my inclination is to make folks who want that to do the transformations themselves.

Ah, one more thing- the ellipse specification allows you to set the confidence level (p value). At present it's in percent from zero to 100; perhaps it should be fraction from zero to one?

In reply to by johnweeks

Thank you, John, for your work on this.

Indeed, the semimajor and semiminor axes must vary with the aspect ratio of the graph. A typical use case may have x and y quantities that differ by orders of magnitude, so the a, b, theta thing wouldn't be useful because equal axis scaling is unlikely. I ran into similar issues when trying to draw shapes that surround a cloud of points with an inset defined by different axis units.

I think either p value (0-1) or 'probability cutoff' (1-p) would be fine for defining the confidence value. probably best to make it consistent with Igor's confidence interval calculation for curve fitting.

If I set point color as f(z), do the ellipses plot in the expected colors?

I would typically want to produce a scatter plot where the point (center of each ellipse) is not visible (plotting as dots is probably sufficient), together with a maximum likelihood fit that takes into account the covariance.

sigma/sigma/correlation and var/var/covar are sensible options, IMO.

Looks really good!

Thanks for the comments, Tony. I did, in fact, worry about axes with widely different ranges. I will have to test that carefully; I think what I have done so far should work correctly. I think unless I get some requests after IP 9 is released, I will abandon the (a,b,theta) option. I was thinking in terms of some sort of map info where the axes are in the same units, and the ellipse shows spatial uncertainty.

It is my intention that color as f(z) should do the right thing, but I haven't had a chance to test yet.

Ah, but wait- I have an option for fill color, but it simply sets a color for all ellipses in a given trace. Hmm... I could do something hackish like use the trace color with alpha=0.3 or something.

Since the ellipses are error bars, there must be a data point to attach them to. But you can always use lines between points with a zero-width line, or dots with zero size, or some such.