#' @title Draw axis labels for 3d persp plots
#' @description This function draws axis labels for a 3d plot generated by graphics::persp
#' @param xlab String - X axis annotation. Defaults to "x".
#' @param ylab String - Y axis annotation. Defaults to "y".
#' @param zlab String - Z axis annotation. Defaults to "z".
#' @param cex double - character magnification. Defaults to 2.
#' @param pmat matrix of type double - A 4x4 matrix returned by calling graphics::persp
#' @param dist vector of type double - A three-dimensional vector containing the distances in (x,y,z)-direction between
#' axis and annotation. Defaults to c(1.4,1.3,1.4).
#' @param x vector of type double - The x range. It suffices, to supply c(min(x),max(x))
#' @param y vector of type double - The y range. It suffices, to supply c(min(y),max(y))
#' @param z vector of type double - The z range. It suffices, to supply c(min(z),max(z))
#' @details This function is especially designed for persp plots, since these lack manipulation options for
#' individual axis annotation texts. Please supply empty axis labels to persp, i.e. persp(xlab = "",ylab = "",zlab="",...).
#' @return No return value
#' @author Philipp van Wickevoort Crommelin
#' @examples
#' x = seq(from = -10,
#' to = 10,
#' length.out = 30)
#' y = x
#' f = function(x,y) {
#' r =sqrt(x^2+y^2)
#' 10 * sin(r)/r
#' }
#' z = outer(x, y, f)
#' z[is.na(z)] = 1
#'
#' par(mfrow=c(2, 1))
#'
#' p1 = persp(x = x,
#' y = y,
#' z = z,
#' theta = 30,
#' phi = 30,
#' expand = 0.5,
#' col = "lightblue",
#' ticktype="detailed",
#' xlab="",
#' ylab="",
#' zlab="",
#' r = 10)
#' myBayes::axLabels3d(x = x,
#' y = y,
#' z = c(min(z),max(z)),
#' pmat = p1,
#' xlab = "x label",
#' ylab = "y label",
#' zlab = "z label")
#'
#' p1 = persp(x = x,
#' y = y,
#' z = z,
#' theta = 30,
#' phi = 30,
#' expand = 0.5,
#' col = "lightblue",
#' ticktype="detailed",
#' xlab="",
#' ylab="",
#' zlab="",
#' r = 10)
#' myBayes::axLabels3d(x = x,
#' y = y,
#' z = c(min(z),max(z)),
#' pmat = p1,
#' dist = c(1.6,1.5,1.6),
#' xlab = "x label",
#' zlab = "z label")
#'
#' @export
axLabels3d = function(xlab = "x", ylab = "y", zlab = "z", cex = 2, pmat,
dist = c(1.4,1.3,1.4),
x,y,z){
gpar = par()
project2d = function(v) trans3d(x = v[1],
y = v[2],
z = v[3],
pmat = pmat)
xmin=min(x)
xmax=max(x)
ymin=min(y)
ymax=max(y)
zmin=min(z)
zmax=max(z)
xrng = xmax-xmin
yrng = ymax-ymin
zrng = zmax-zmin
#x axis
if(xlab!=""){
bot3d = c(xmin,ymax-yrng*dist[1],zmin)
top3d = c(xmax,ymax-yrng*dist[1],zmin)
mid3d = c(mean(range(x)),ymax-yrng*dist[1],zmin)
bot2d = project2d(bot3d)
mid2d = project2d(mid3d)
top2d = project2d(top3d)
angle = 180 * atan((top2d$y-bot2d$y)/(top2d$x-bot2d$x))/pi
par(xpd = NA, #enable drawing out of plotting area
srt = angle) #rotate text by angle
text(x = mid2d$x,
y = mid2d$y,
labels = xlab,
cex = cex)
}
#y axis
if(ylab!=""){
bot3d = c(xmin+xrng*dist[2],ymin,zmin)
mid3d = c(xmin+xrng*dist[2],mean(range(y)),zmin)
top3d = c(xmin+xrng*dist[2],ymax,zmin)
bot2d = project2d(bot3d)
mid2d = project2d(mid3d)
top2d = project2d(top3d)
angle = 180 * atan((top2d$y-bot2d$y)/(top2d$x-bot2d$x))/pi
par(srt = angle) #rotate text by angle
text(x = mid2d$x,
y = mid2d$y,
labels = ylab,
cex = cex)
}
#z axis
if(zlab!=""){
bot3d = c((xmax-xrng*dist[3])/sqrt(2),(ymax-yrng*dist[3])/sqrt(2),zmin)
mid3d = c((xmax-xrng*dist[3])/sqrt(2),(ymax-yrng*dist[3])/sqrt(2),mean(range(z)))
top3d = c((xmax-xrng*dist[3])/sqrt(2),(ymax-yrng*dist[3])/sqrt(2),zmax)
bot2d = project2d(bot3d)
mid2d = project2d(mid3d)
top2d = project2d(top3d)
angle = 180 * atan((top2d$y-bot2d$y)/(top2d$x-bot2d$x))/pi + 180
par(srt = angle) #rotate text by angle
text(x = mid2d$x,
y = mid2d$y,
labels = zlab,
cex = cex)
}
#reset par
par(srt = gpar$srt,
xpd = gpar$xpd)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.