## f(x) is a one-dimensional PDF
# Compute the one- and two-sigma contour levels of a normal distribution,
# i.e. the values l such that
# integral over dnorm(x) >= l of dnorm(x) dx = p,
# where p = 68.3% and 95.4%.
l = contourlevel(dnorm, xmin = -10, xmax = 10, napprox = 0)
print(l)
# Compare these values with dnorm(1) and dnorm(2)
print(dnorm(c(1, 2)))
## f(x) is a two-dimensional likelihood function
# Produce 20%, 40%, 60%, and 80% highest-density contours.
f = function(x) {
cos(2*x[1]-x[2]-1)^2*exp(-x[1]^2-x[2]^2-x[1]*x[2])
}
p = c(0.2, 0.4, 0.6, 0.8)
# Values l such that
# integral over f(x) >= l of f(x) dx = p * integral f(x) dx
l = contourlevel(f, p, c(-5, -5), c(5, 5))
# Plot the function and contours at the levels l
x = seq(-3, 3, length.out = 200)
m = pracma::meshgrid(x)
z = array(Vectorize(function(x, y) f(c(x, y)))(m$Y, m$X), dim(m$X))
image(x, x, z, col = terrain.colors(100))
contour(x, x, z, levels = l, add = TRUE,
labels = sprintf("%.0f%%", p*100), labcex = 0.7)
## f is a 20-by-20 array representing a gridded point set
# Produce 1000 points drawn from a two-dimensional normal distribution.
set.seed(1)
x = MASS::mvrnorm(n = 1000, mu = c(0, 0), Sigma = matrix(c(3, 1, 1, 2), 2, 2))
# Grid these points onto a regular 20-by-20 grid
g = griddata(x, min = -6, max = 6)
# Find one- and two-sigma contour levels and draw the contours
l = contourlevel(g$field)
plot(x, xlim = g$grid[[1]]$lim, ylim = g$grid[[2]]$lim, pch = 20, cex = 0.5)
contour(g$grid[[1]]$mid, g$grid[[2]]$mid, g$field,
levels = l, add = TRUE, col = "red", lwd = c(2, 1), labels = NA)
Run the code above in your browser using DataLab