Quantcast
Channel: Active questions tagged r - Stack Overflow
Viewing all articles
Browse latest Browse all 206235

Create %-contour in a 3d kernel density and find which points are within that contour

$
0
0

I want to plot the isosurface of a specific %-contour in a 3d kernel density estimate. Then, I want to know which points are within that 3d shape.

I'll show I approach the 2d situation to illustrate my problem (code imitated from R - How to find points within specific Contour and How to plot a contour line showing where 95% of values fall within, in R and in ggplot2).

library(MASS)
library(misc3d)
library(rgl)
library(sp)

# Create dataset
set.seed(42)
Sigma <- matrix(c(15, 8, 5, 8, 15, .2, 5, .2, 15), 3, 3)
mv <- data.frame(mvrnorm(400, c(100, 100, 100),Sigma))

### 2d ###
# Create kernel density
dens2d <- kde2d(mv[, 1], mv[, 2], n = 40)
# Find the contour level defined in prob
dx <- diff(dens2d$x[1:2])
dy <- diff(dens2d$y[1:2])
sd <- sort(dens2d$z)
c1 <- cumsum(sd) * dx * dy 
prob <- .5
levels <- sapply(prob, function(x) { 
  approx(c1, sd, xout = 1 - x)$y
})

# Find which values are inside the defined polygon
ls <- contourLines(dens2d, level = levels)
pinp <- point.in.polygon(mv[, 1], mv[, 2], ls[[1]]$x, ls[[1]]$y)

# Plot it
plot(mv[, 1], mv[, 2], pch = 21, bg = "gray")
contour(dens2d, levels = levels, labels = prob,
        add = T, col = "red")
points(mv[pinp == 1, 1], mv[pinp == 1, 2], pch = 21, bg = "orange")

The 2d situation So, the 50% contour is defined using approx, the contour is created using contourLines, and then point.in.polygon finds the points inside that contour.

I want to do the same, but in a 3d situation. This is what I've managed:

### 3d ###
# Create kernel density
dens3d <- kde3d(mv[,1], mv[,2], mv[,3], n = 40)

# Find the contour level defined in prob
dx <- diff(dens3d$x[1:2])
dy <- diff(dens3d$y[1:2])
dz <- diff(dens3d$z[1:2])
sd3d <- sort(dens3d$d)
c3d <- cumsum(sd3d) * dx * dy * dz
levels <- sapply(prob, function(x) {
  approx(c3d, sd3d, xout = 1 - x)$y
})

# Find which values are inside the defined polygon
# # No idea

# Plot it
points3d(mv[,1], mv[,2], mv[,3], size = 2)
box3d(col = "gray")
contour3d(dens3d$d, level = levels, x = dens3d$x, y = dens3d$y, z = dens3d$z, #exp(-12)
          alpha = .3, color = "red", color2 = "gray", add = TRUE)
title3d(xlab = "x", ylab = "y", zlab = "z")

The 3d situation

So, I haven't got far.

I realize that the way I define the level in the 3d case is incorrect and I'm guessing the problem lies within c3d <- cumsum(sd3d) * dx * dy * dz but I honestly don't know how to proceed.

And, once the 3d contour is correctly defined, I would appreciate any tips on how to approach which points are within that contour.

Many thanks!


Viewing all articles
Browse latest Browse all 206235

Trending Articles