rplotcovarianceellipser-car

Obtain vertices of the ellipse on an ellipse covariance plot (created by `car::ellipse`)


By following this post one can draw an ellipse with a given shape matrix (A):

library(car)
A <- matrix(c(20.43, -8.59,-8.59, 24.03), nrow = 2)
ellipse(c(-0.05, 0.09), shape=A, radius=1.44, col="red", lty=2, asp = 1)

Now how to get the major/minor (pair of intersect points of the major/minor axis and the ellipse) vertices of this ellipse?


Solution

  • For practical purposes, @Tensibai's answer is probably good enough. Just use a large enough value for the segments argument so that the points give a good approximation to the true vertices.

    If you want something a bit more rigorous, you can solve for the location along the ellipse that maximises/minimises the distance from the center, parametrised by the angle. This is more complex than just taking angle={0, pi/2, pi, 3pi/2} because of the presence of the shape matrix. But it's not too difficult:

    # location along the ellipse
    # linear algebra lifted from the code for ellipse()
    ellipse.loc <- function(theta, center, shape, radius)
    {
        vert <- cbind(cos(theta), sin(theta))
        Q <- chol(shape, pivot=TRUE)
        ord <- order(attr(Q, "pivot"))
        t(center + radius*t(vert %*% Q[, ord]))
    }
    
    # distance from this location on the ellipse to the center 
    ellipse.rad <- function(theta, center, shape, radius)
    {
        loc <- ellipse.loc(theta, center, shape, radius)
        (loc[,1] - center[1])^2 + (loc[,2] - center[2])^2
    }
    
    # ellipse parameters
    center <- c(-0.05, 0.09)
    A <- matrix(c(20.43, -8.59, -8.59, 24.03), nrow=2)
    radius <- 1.44
    
    # solve for the maximum distance in one hemisphere (hemi-ellipse?)
    t1 <- optimize(ellipse.rad, c(0, pi - 1e-5), center=center, shape=A, radius=radius, maximum=TRUE)$m
    l1 <- ellipse.loc(t1, center, A, radius)
    
    # solve for the minimum distance
    t2 <- optimize(ellipse.rad, c(0, pi - 1e-5), center=center, shape=A, radius=radius)$m
    l2 <- ellipse.loc(t2, center, A, radius)
    
    # other points obtained by symmetry
    t3 <- pi + t1
    l3 <- ellipse.loc(t3, center, A, radius)
    
    t4 <- pi + t2
    l4 <- ellipse.loc(t4, center, A, radius)
    
    # plot everything
    MASS::eqscplot(center[1], center[2], xlim=c(-7, 7), ylim=c(-7, 7), xlab="", ylab="")
    ellipse(center, A, radius, col="red", lty=2)
    points(rbind(l1, l2, l3, l4), cex=2, col="blue", lwd=2)
    

    enter image description here