3

In R, how to use ellipses to represent error bars (standard deviation) for x and y variables if only summary data, i.e. mean and SD for different data sets, are available. Any feedback is appreciated.

peanut
  • 33
  • 4

3 Answers3

2

You can write your own function like this one:

draw_ellipse = function (mean_x, mean_y, sd_x, sd_y)
{
    ellipse <- function (x) { sin(acos(x)) }
    t = seq(-1, 1, length.out = 100)
    el_y = sd_y*ellipse(t)
    newx = mean_x + sd_x * t
    polygon(c(newx, rev(newx)), c(mean_y + el_y, rev(mean_y - el_y)), col = "grey", border = NA)
}

You can use it very easily using apply():

x = runif(10)
y = runif(10)
sd_x = abs(rnorm(10, 0.1, 0.02))
sd_y = abs(rnorm(10, 0.05, 0.01))
plot(x, y)
df = data.frame(x, y, sd_x, sd_y)
apply(df, 1, function (x) { draw_ellipse(x[1], x[2], x[3], x[4]) })
points(x, y, pch = 3)

Solution for plotting ellipses with different colors:

draw_ellipse = function (mean_x, mean_y, sd_x, sd_y, colidx)
{
    ellipse <- function (x) { sin(acos(x)) }
    t = seq(-1, 1, length.out = 100)
    el_y = sd_y*ellipse(t)
    newx = mean_x + sd_x * t
    polygon(c(newx, rev(newx)), c(mean_y + el_y, rev(mean_y - el_y)), col = as.character(colors[colidx]), border = NA)
}

x = runif(10)
y = runif(10)
sd_x = abs(rnorm(10, 0.1, 0.02))
sd_y = abs(rnorm(10, 0.05, 0.01))
plot(x, y)
colors = rainbow(length(x))
df = data.frame(x, y, sd_x, sd_y, colidx = 1:length(x))
apply(df, 1, function (x) { draw_ellipse(x[1], x[2], x[3], x["sd_y"], x["colidx"]) })
points(x, y, pch = 3)
Tomas
  • 57,621
  • 49
  • 238
  • 373
  • Tomas, thanks for your quick response. Great. I applied the code to my data, which worked fine. However, data ellipses are partially overlapping. As data represented different resources, is it possible to use a different colour coding for the ellipses? Ta very much. This is how my data looks like... x <- c(0.42, 1.25, 0.02, 0.47, 3.78, -0.0288, 0.41, 6.33, -0.2888) y <- c(3.3, 4.7, 1.6, 3.4, 6.7, 2.6, 3.8, 5.9, 0.2) sd_x <- c(0.16, 0.25, 0.02, 0.32, 1.35, 0.0264, 0.18, 3.78, 0.64) sd_y <- c(0.4, 0.5, 2.6, 1.9, 1.55, 2.9, 1, 2, 0.2) plot(x, y, xlim=c(-2,12), ylim=c(-2,9)) – peanut Sep 22 '11 at 10:14
  • @peanut, welcome, it's great that it helped. You have two possibilities - either try to remove the `border = NA` which will print you border around each ellipse, or try to change the col argument to change along some pallete (see `?palette`). You would then need to add additional argument `col` to the `draw_ellipse` function and supply it in the `apply` call. – Tomas Sep 22 '11 at 10:25
  • Tomas, one last question. I go with the the boarder now, but would like to stay with coloured ellipses. How to a supply a "col" argument to they "apply" call? – peanut Sep 22 '11 at 11:01
  • @peanut, just add a new column to data frame, e.g. `df = data.frame(x, y, sd_x, sd_y, col = 1:length(x))`, and then use it in the apply call. See my updated answer. – Tomas Sep 22 '11 at 11:22
1

You might like the function car::ellipse , i.e., the ellipse() function in the car package.

Carl Witthoft
  • 20,573
  • 9
  • 43
  • 73
0

The ellipse function in the ellipse package will take summary information (including correlation) and provide the ellipse representing the confidence region.

Greg Snow
  • 48,497
  • 6
  • 83
  • 110