###########################################################################
# joint.density.plot #
# #
# The purpose of the joint.density.plot function is to produce a joint #
# density plot from samples of two marginal posterior distributions. This #
# function is derived from the kde2d and bandwidth.nrd functions from the #
# MASS package. #
###########################################################################
joint.density.plot <- function(x, y, Title=NULL, contour=TRUE, color=FALSE,
Trace=NULL)
{
### Initial Checks
xname <- deparse(substitute(x))
yname <- deparse(substitute(y))
x <- as.vector(x)
y <- as.vector(y)
if(!identical(length(y), length(x)))
stop("vectors x and y must be the same length.")
if(any(!is.finite(x)))
stop("x must have finite values.")
if(any(!is.finite(y)))
stop("y must have finite values.")
### Two-Dimensional Kernel Density Estimates
kde2d <- function(x, y, h, n=25, lims=c(range(x), range(y)))
{
nx <- length(x)
if(any(!is.finite(lims)))
stop("x and y must have finite values.")
n <- rep(n, length.out=2L)
gx <- seq.int(lims[1L], lims[2L], length.out=n[1L])
gy <- seq.int(lims[3L], lims[4L], length.out=n[2L])
h <- if(missing(h)) c(bandwidth.nrd(x), bandwidth.nrd(y))
else rep(h, length.out=2L)
h <- h / 4 # for S's bandwidth scale
ax <- outer(gx, x, "-" ) / h[1L]
ay <- outer(gy, y, "-" ) / h[2L]
z <- tcrossprod(matrix(dnorm(ax), , nx),
matrix(dnorm(ay), , nx)) / (nx * h[1L] * h[2L])
list(x=gx, y=gy, z=z)
}
bandwidth.nrd <- function(x)
{
r <- quantile(x, c(0.25, 0.75))
h <- (r[2L] - r[1L]) / 1.34
4 * 1.06 * min(sqrt(var(x)), h) * length(x) ^ (-1/5)
}
dd <- kde2d(x,y)
if(color == FALSE) {
plot(x, y, cex=0.1, main=Title, xlab=xname, ylab=yname, col="gray")}
else if(color == TRUE) {
crp <- colorRampPalette(c("black","red","yellow","white"), space="rgb")
image(dd, main=Title, xlab=xname, ylab=yname, col=crp(200))
}
if(contour == TRUE) {contour(dd, nlevels=10, add=TRUE)}
if(!is.null(Trace)) {
if(length(Trace) != 2) stop("Trace requires 2 elements.")
if(Trace[1] >= Trace[2])
stop("Trace[1] not smaller than Trace[2].")
if(Trace[1] < 1) stop("Trace[1] < 1.")
if(Trace[2] > length(x)) stop("Trace[2] > length(x).")
lines(x[Trace[1]:Trace[2]], y[Trace[1]:Trace[2]], col="green")
points(x[Trace[1]], y[Trace[1]], cex=0.5, col="green")
}
}
#End
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.