One way is to explicitly draw ellipses with axes determined by the size of the errors.
x <- -10*cos(seq(0, pi, length.out = 10))+1 y <- 10*seq(0, pi, length.out = 10) xerr <- runif(10, 1, 5) yerr <- runif(10, 1, 5) dd <- as.data.frame(cbind(x, y, xerr, yerr)) dd$frame <- factor(seq(1:10))
For this purpose, we define our function for generating ellipses:
ellipseFun <- function(center = c(0, 0), axes = c(1, 1), npoints = 101){ tt <- seq(0,2*pi, length.out = npoints) xx <- center[1] + axes[1] * cos(tt) yy <- center[2] + axes[2] * sin(tt) return(data.frame(x = xx, y = yy)) }
Then we create matrices for all ellipses:
ddEll <- data.frame() for(k in levels(dd$frame)){ ddEll <- rbind(ddEll, cbind(as.data.frame(with(dd[dd$frame == k,], ellipseFun(center = c(x, y), axes = c(xerr, yerr), npoints = 101))),frame = k)) }
And finally, we can build them:
library(ggplot2) ggplot() + geom_point(data = dd, aes(x, y)) + geom_polygon(data=ddEll, aes(x = x, y = y, group = frame), colour = "gray", fill = "red", alpha = .2) + scale_size_identity() + theme_bw() + xlim(c(-20, 20)) + ylim(c(-5, 35)) + coord_fixed()
