Nothing
#---------------------------------------------------------------------------------------------------------
# labeledHeatmap.R
#---------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------
#
# .reverseRows = function(Matrix)
#
#--------------------------------------------------------------------------
#
.reverseRows = function(Matrix)
{
ind = seq(from=dim(Matrix)[1], to=1, by=-1);
Matrix[ind,, drop = FALSE];
#Matrix
}
.extend = function(x, n)
{
nRep = ceiling(n/length(x));
rep(x, nRep)[1:n];
}
# Adapt a numeric index to a subset
# Aim: if 'index' is a numeric index of special entries of a vector,
# create a new index that references 'subset' elements of the vector
.restrictIndex = function(index, subset)
{
out = match(index, subset);
out[!is.na(out)];
}
#--------------------------------------------------------------------------
#
# labeledHeatmap
#
#--------------------------------------------------------------------------
# This function plots a heatmap of the specified matrix
# and labels the x and y axes wit the given labels.
# It is assumed that the number of entries in xLabels and yLabels is consistent
# with the dimensions in.
# If colorLabels==TRUE, the labels are not printed and instead interpreted as colors --
# -- a simple symbol with the appropriate color is printed instead of the label.
# The x,yLabels are expected to have the form "..color" as in "MEgrey" or "PCturquoise".
# xSymbol, ySymbols are additional markers that can be placed next to color labels
labeledHeatmap = function (
Matrix,
xLabels, yLabels = NULL,
xSymbols = NULL, ySymbols = NULL,
colorLabels = NULL,
xColorLabels = FALSE, yColorLabels = FALSE,
checkColorsValid = TRUE,
invertColors = FALSE,
setStdMargins = TRUE,
xLabelsPosition = "bottom",
xLabelsAngle = 45,
xLabelsAdj = 1,
yLabelsPosition = "left",
xColorWidth = 2*strheight("M"),
yColorWidth = 2*strwidth("M"),
xColorOffset = strheight("M")/3,
yColorOffset = strwidth("M")/3,
# Content of heatmap
colorMatrix = NULL,
colors = NULL,
naColor = "grey",
textMatrix = NULL, cex.text = NULL,
textAdj = c(0.5, 0.5),
# labeling of rows and columns
cex.lab = NULL,
cex.lab.x = cex.lab,
cex.lab.y = cex.lab,
colors.lab.x = 1,
colors.lab.y = 1,
font.lab.x = 1,
font.lab.y = 1,
bg.lab.x = NULL,
bg.lab.y = NULL,
x.adj.lab.y = 1,
plotLegend = TRUE,
keepLegendSpace = plotLegend,
legendLabel = "",
cex.legendLabel = 1,
# Separator line specification
verticalSeparator.x = NULL,
verticalSeparator.col = 1,
verticalSeparator.lty = 1,
verticalSeparator.lwd = 1,
verticalSeparator.ext = 0,
verticalSeparator.interval = 0,
horizontalSeparator.y = NULL,
horizontalSeparator.col = 1,
horizontalSeparator.lty = 1,
horizontalSeparator.lwd = 1,
horizontalSeparator.ext = 0,
horizontalSeparator.interval = 0,
# optional restrictions on which rows and columns to actually show
showRows = NULL,
showCols = NULL,
# Other arguments...
... )
{
textFnc = match.fun("text");
if (!is.null(colorLabels)) {xColorLabels = colorLabels; yColorLabels = colorLabels; }
if (is.null(yLabels) & (!is.null(xLabels)) & (dim(Matrix)[1]==dim(Matrix)[2]))
yLabels = xLabels;
nCols = ncol(Matrix);
nRows = nrow(Matrix);
if (length(xLabels)!=nCols)
stop("Length of 'xLabels' must equal the number of columns in 'Matrix.'");
if (length(yLabels)!=nRows)
stop("Length of 'yLabels' must equal the number of rows in 'Matrix.'");
if (is.null(showRows)) showRows = c(1:nRows);
if (is.null(showCols)) showCols = c(1:nCols);
nShowCols = length(showCols);
nShowRows = length(showRows);
if (nShowCols==0) stop("'showCols' is empty.");
if (nShowRows==0) stop("'showRows' is empty.");
if (checkColorsValid)
{
xValidColors = !is.na(match(substring(xLabels, 3), colors()));
yValidColors = !is.na(match(substring(yLabels, 3), colors()));
} else {
xValidColors = rep(TRUE, length(xLabels));
yValidColors = rep(TRUE, length(yLabels));
}
if (sum(xValidColors)>0) xColorLabInd = xValidColors[showCols]
if (sum(!xValidColors)>0) xTextLabInd = !xValidColors[showCols]
if (sum(yValidColors)>0) yColorLabInd = yValidColors[showRows]
if (sum(!yValidColors)>0) yTextLabInd = !yValidColors[showRows]
if (setStdMargins)
{
if (xColorLabels & yColorLabels)
{
par(mar=c(2,2,3,5)+0.2);
} else {
par(mar = c(7,7,3,5)+0.2);
}
}
xLabels.show = xLabels[showCols];
yLabels.show = yLabels[showRows];
if (!is.null(xSymbols))
{
if (length(xSymbols)!=nCols)
stop("When 'xSymbols' are given, their length must equal the number of columns in 'Matrix.'");
xSymbols.show = xSymbols[showCols];
} else
xSymbols.show = NULL;
if (!is.null(ySymbols))
{
if (length(ySymbols)!=nRows)
stop("When 'ySymbols' are given, their length must equal the number of rows in 'Matrix.'");
ySymbols.show = ySymbols[showRows];
} else
ySymbols.show = NULL;
xLabPos = charmatch(xLabelsPosition, c("bottom", "top"));
if (is.na(xLabPos))
stop("Argument 'xLabelsPosition' must be (a unique abbreviation of) 'bottom', 'top'");
yLabPos = charmatch(yLabelsPosition, c("left", "right"));
if (is.na(yLabPos))
stop("Argument 'yLabelsPosition' must be (a unique abbreviation of) 'left', 'right'");
if (is.null(colors)) colors = heat.colors(30);
if (invertColors) colors = rev(colors);
labPos = .heatmapWithLegend(Matrix[showRows, showCols, drop = FALSE],
signed = FALSE, colorMatrix = colorMatrix, colors = colors, naColor = naColor,
cex.legendAxis = cex.lab, plotLegend = plotLegend, keepLegendSpace = keepLegendSpace,
legendLabel = legendLabel, cex.legendLabel = cex.legendLabel, ...)
plotbox = labPos$box;
xmin = plotbox[1]; xmax = plotbox[2]; ymin = plotbox[3]; yrange = plotbox[4]-ymin;
ymax = plotbox[4]; xrange = xmax - xmin;
# The positions below are for showCols/showRows-restriceted data
xLeft = labPos$xLeft;
xRight = labPos$xRight;
yTop = labPos$yTop;
yBot = labPos$yBot;
xspacing = labPos$xMid[2] - labPos$xMid[1];
yspacing = abs(labPos$yMid[2] - labPos$yMid[1]);
offsetx = .extend(xColorOffset, nCols)[showCols]
offsety = .extend(yColorOffset, nRows)[showRows]
xColW = xColorWidth;
yColW = yColorWidth;
# Additional angle-dependent offsets for x axis labels
textOffsetY = strheight("M") * cos(xLabelsAngle/180 * pi);
if (any(xValidColors)) offsetx = offsetx + xColW;
if (any(yValidColors)) offsety = offsety + yColW;
# Create the background for column and row labels.
extension.left = par("mai")[2] * # left margin width in inches
par("cxy")[1] / par("cin")[1] # character size in user corrdinates/character size in inches
extension.right = par("mai")[4] * # right margin width in inches
par("cxy")[1] / par("cin")[1] # character size in user corrdinates/character size in inches
extension.bottom = par("mai")[1] *
par("cxy")[2] / par("cin")[2]- # character size in user corrdinates/character size in inches
offsetx
extension.top = par("mai")[3] *
par("cxy")[2] / par("cin")[2]- # character size in user corrdinates/character size in inches
offsetx
figureBox = par("usr");
figXrange = figureBox[2] - figureBox[1];
figYrange = figureBox[4] - figureBox[3];
if (!is.null(bg.lab.x))
{
bg.lab.x = .extend(bg.lab.x, nCols)[showCols];
if (xLabPos==1)
{
y0 = ymin;
ext = extension.bottom;
sign = 1;
} else {
y0 = ymax;
ext = extension.top;
sign = -1;
}
figureDims = par("pin");
angle = xLabelsAngle/180*pi;
ratio = figureDims[1]/figureDims[2] * figYrange/figXrange;
ext.x = -sign * ext * 1/tan(angle)/ratio;
ext.y = sign * ext * sign(sin(angle))
#offset = (sum(xValidColors)>0) * xColW + offsetx + textOffsetY;
offset = offsetx + textOffsetY;
for (cc in 1:nShowCols)
polygon(x = c(xLeft[cc], xLeft[cc], xLeft[cc] + ext.x, xRight[cc] + ext.x, xRight[cc], xRight[cc]),
y = c(y0, y0-sign*offset[cc], y0-sign*offset[cc] - ext.y, y0-sign*offset[cc] - ext.y,
y0-sign*offset[cc], y0),
border = bg.lab.x[cc], col = bg.lab.x[cc], xpd = TRUE);
}
if (!is.null(bg.lab.y))
{
bg.lab.y = .extend(bg.lab.y, nRows)
reverseRows = TRUE;
if (reverseRows) bg.lab.y = rev(bg.lab.y);
bg.lab.y = bg.lab.y[showRows];
if (yLabPos==1)
{
xl = xmin-extension.left;
xr = xmin;
} else {
xl = xmax;
xr = xmax + extension.right;
}
for (r in 1:nShowRows)
rect(xl, yBot[r], xr, yTop[r],
col = bg.lab.y[r], border = bg.lab.y[r], xpd = TRUE);
}
colors.lab.x = .extend(colors.lab.x, nCols)[showCols];
font.lab.x = .extend(font.lab.x, nCols)[showCols];
# Write out labels
if (sum(!xValidColors)>0)
{
xLabYPos = if(xLabPos==1) ymin - offsetx- textOffsetY else ymax + offsetx + textOffsetY;
if (is.null(cex.lab)) cex.lab = 1;
mapply(textFnc, x = labPos$xMid[xTextLabInd],
y = xLabYPos, labels = xLabels.show[xTextLabInd],
col = colors.lab.x[xTextLabInd],
font = font.lab.x[xTextLabInd],
MoreArgs = list(srt = xLabelsAngle,
adj = xLabelsAdj, xpd = TRUE, cex = cex.lab.x));
}
if (sum(xValidColors)>0)
{
baseY = if (xLabPos==1) ymin-offsetx else ymax + offsetx;
deltaY = if (xLabPos==1) xColW else -xColW;
rect(xleft = labPos$xMid[xColorLabInd] - xspacing/2, ybottom = baseY[xColorLabInd],
xright = labPos$xMid[xColorLabInd] + xspacing/2, ytop = baseY[xColorLabInd] + deltaY,
density = -1, col = substring(xLabels.show[xColorLabInd], 3),
border = substring(xLabels.show[xColorLabInd], 3), xpd = TRUE)
if (!is.null(xSymbols))
mapply(textFnc, x = labPos$xMid[xColorLabInd],
y = baseY[xColorLabInd] -textOffsetY - sign(deltaY)* strwidth("M")/3,
labels = xSymbols.show[xColorLabInd],
col = colors.lab.x[xColorLabInd],
font = font.lab.x[xColorLabInd],
MoreArgs = list( adj = xLabelsAdj,
xpd = TRUE, srt = xLabelsAngle, cex = cex.lab.x));
}
x.adj.lab.y = .extend(x.adj.lab.y, nRows)[showRows]
if (yLabPos==1)
{
marginWidth = par("mai")[2] / par("pin")[1] * xrange
} else {
marginWidth = par("mai")[4] / par("pin")[1] * xrange
}
xSpaceForYLabels = marginWidth-2*strwidth("M")/3 - ifelse(yValidColors[showRows], yColW, 0);
xPosOfYLabels.relative = xSpaceForYLabels * (1-x.adj.lab.y) + offsety
colors.lab.y = .extend(colors.lab.y, nRows)[showRows];
font.lab.y = .extend(font.lab.y, nRows)[showRows];
if (sum(!yValidColors)>0)
{
if (is.null(cex.lab)) cex.lab = 1;
if (yLabPos==1)
{
x = xmin - strwidth("M")/3 - xPosOfYLabels.relative[yTextLabInd]
adj = x.adj.lab.y[yTextLabInd]
} else {
x = xmax + strwidth("M")/3 + xPosOfYLabels.relative[yTextLabInd];
adj = 1-x.adj.lab.y[yTextLabInd];
}
mapply(textFnc, y = labPos$yMid[yTextLabInd], labels = yLabels.show[yTextLabInd],
adj = lapply(adj, c, 0.5),
x = x,
col = colors.lab.y[yTextLabInd],
font = font.lab.y[yTextLabInd],
MoreArgs = list(srt = 0, xpd = TRUE, cex = cex.lab.y));
}
if (sum(yValidColors)>0)
{
if (yLabPos==1)
{
xl = xmin-offsety;
xr = xmin-offsety + yColW;
xtext = xmin - strwidth("M")/3 - xPosOfYLabels.relative[yColorLabInd];
adj = x.adj.lab.y[yColorLabInd]
} else {
xl = xmax + offsety - yColW;
xr = xmax + offsety;
xtext = xmin + strwidth("M")/3 + xPosOfYLabels.relative[yColorLabInd]
adj = 1-x.adj.lab.y[yColorLabInd];
}
rect(xleft = xl[yColorLabInd], ybottom = rev(labPos$yMid[yColorLabInd]) - yspacing/2,
xright = xr[yColorLabInd], ytop = rev(labPos$yMid[yColorLabInd]) + yspacing/2,
density = -1, col = substring(rev(yLabels.show[yColorLabInd]), 3),
border = substring(rev(yLabels.show[yColorLabInd]), 3), xpd = TRUE)
#for (i in yColorLabInd)
#{
# lines(c(xmin- offsetx, xmin- offsetx+yColW), y = rep(labPos$yMid[i] - yspacing/2, 2), col = i, xpd = TRUE)
# lines(c(xmin- offsetx, xmin- offsetx+yColW), y = rep(labPos$yMid[i] + yspacing/2, 2), col = i, xpd = TRUE)
#}
if (!is.null(ySymbols))
mapply(textFnc, y = labPos$yMid[yColorLabInd], labels = ySymbols.show[yColorLabInd],
adj = lapply(adj, c, 0.5),
x = xtext, col = colors.lab.y[yColorLabInd],
font = font.lab.y[yColorLabInd],
MoreArgs = list(srt = 0, xpd = TRUE, cex = cex.lab.y));
}
# Draw separator lines, if requested
showCols.ext = c(if (1 %in% showCols) 0 else NULL, showCols);
showCols.shift = if (0 %in% showCols.ext) 1 else 0;
if (length(verticalSeparator.x) > 0)
{
if (any(verticalSeparator.x < 0 | verticalSeparator.x > nCols))
stop("If given. 'verticalSeparator.x' must all be between 0 and the number of columns.");
colSepShowIndex = which(verticalSeparator.x %in% showCols.ext);
verticalSeparator.x.show = .restrictIndex(verticalSeparator.x, showCols.ext)-showCols.shift;
} else if (verticalSeparator.interval > 0)
{
verticalSeparator.x.show = verticalSeparator.x =
seq(from = verticalSeparator.interval, by = verticalSeparator.interval,
length.out = floor(length(showCols)/verticalSeparator.interval));
colSepShowIndex = 1:length(verticalSeparator.x);
} else
verticalSeparator.x.show = NULL;
if (length(verticalSeparator.x.show) > 0)
{
nLines = length(verticalSeparator.x);
vs.col = .extend(verticalSeparator.col, nLines)[colSepShowIndex];
vs.lty = .extend(verticalSeparator.lty, nLines)[colSepShowIndex];
vs.lwd = .extend(verticalSeparator.lwd, nLines)[colSepShowIndex];
vs.ext = .extend(verticalSeparator.ext, nLines)[colSepShowIndex];
x.lines = ifelse(verticalSeparator.x.show>0, labPos$xRight[verticalSeparator.x.show], labPos$xLeft[1]);
nLines.show = length(verticalSeparator.x.show);
for (l in 1:nLines.show)
lines(rep(x.lines[l], 2), c(ymin, ymax), col = vs.col[l], lty = vs.lty[l], lwd = vs.lwd[l]);
angle = xLabelsAngle/180*pi;
if (angle==0) angle = pi/2;
if (xLabelsPosition =="bottom")
{
sign = 1;
y0 = ymin;
ext = extension.bottom;
} else {
sign = -1;
y0 = ymax;
ext = extension.top;
}
figureDims = par("pin");
ratio = figureDims[1]/figureDims[2] * figYrange/figXrange;
ext.x = -sign * ext * 1/tan(angle)/ratio;
ext.y = sign * ext * sign(sin(angle))
#offset = (sum(xValidColors)>0) * xColW + offsetx + textOffsetY;
offset = offsetx + textOffsetY;
for (l in 1:nLines.show)
lines(c(x.lines[l], x.lines[l], x.lines[l] + vs.ext[l] * ext.x[l]),
c(y0, y0-sign*offset[l], y0-sign*offset[l] - vs.ext[l] * ext.y[l]),
col = vs.col[l], lty = vs.lty[l], lwd = vs.lwd[l], xpd = TRUE);
}
showRows.ext = c(if (1 %in% showRows) 0 else NULL, showRows);
showRows.shift = if (0 %in% showRows.ext) 1 else 0;
if (length(horizontalSeparator.y) >0)
{
if (any(horizontalSeparator.y < 0 | horizontalSeparator.y > nRows))
stop("If given. 'horizontalSeparator.y' must all be between 0 and the number of rows.");
rowSepShowIndex = which( horizontalSeparator.y %in% showRows.ext);
horizontalSeparator.y.show = .restrictIndex(horizontalSeparator.y, showRows.ext)-showRows.shift;
} else if (horizontalSeparator.interval > 0)
{
horizontalSeparator.y.show = horizontalSeparator.y =
seq(from = horizontalSeparator.interval, by = horizontalSeparator.interval,
length.out = floor(length(showRows)/horizontalSeparator.interval));
rowSepShowIndex = 1:length(horizontalSeparator.y);
} else
horizontalSeparator.y.show = NULL;
if (length(horizontalSeparator.y.show) > 0)
{
reverseRows = TRUE;
if (reverseRows)
{
horizontalSeparator.y.show = nShowRows - horizontalSeparator.y.show+1;
y.lines = ifelse( horizontalSeparator.y.show <=nShowRows,
labPos$yBot[horizontalSeparator.y.show], labPos$yTop[nShowRows]);
} else {
y.lines = ifelse( horizontalSeparator.y.show > 0, labPos$yBot[horizontalSeparator.y.show], labPos$yTop[1]);
}
nLines = length(horizontalSeparator.y);
vs.col = .extend(horizontalSeparator.col, nLines)[rowSepShowIndex];
vs.lty = .extend(horizontalSeparator.lty, nLines)[rowSepShowIndex];
vs.lwd = .extend(horizontalSeparator.lwd, nLines)[rowSepShowIndex];
vs.ext = .extend(horizontalSeparator.ext, nLines)[rowSepShowIndex];
nLines.show = length(horizontalSeparator.y.show);
for (l in 1:nLines.show)
{
if (yLabPos==1)
{
xl = xmin-vs.ext[l]*extension.left;
xr = xmax;
} else {
xl = xmin;
xr = xmax + vs.ext[l]*extension.right;
}
lines(c(xl, xr), rep(y.lines[l], 2),
col = vs.col[l], lty = vs.lty[l], lwd = vs.lwd[l], xpd = TRUE);
}
}
if (!is.null(textMatrix))
{
if (is.null(cex.text)) cex.text = par("cex");
if (is.null(dim(textMatrix)))
if (length(textMatrix)==prod(dim(Matrix))) dim(textMatrix)=dim(Matrix);
if (!isTRUE(all.equal(dim(textMatrix), dim(Matrix))))
stop("labeledHeatmap: textMatrix was given, but has dimensions incompatible with Matrix.");
for (rw in 1:nShowRows)
for (cl in 1:nShowCols)
{
text(labPos$xMid[cl], labPos$yMid[rw],
as.character(textMatrix[showRows[rw],showCols[cl]]), xpd = TRUE, cex = cex.text, adj = textAdj);
}
}
axis(1, labels = FALSE, tick = FALSE)
axis(2, labels = FALSE, tick = FALSE)
axis(3, labels = FALSE, tick = FALSE)
axis(4, labels = FALSE, tick = FALSE)
invisible(labPos)
}
#===================================================================================================
#
# multi-page labeled heatmap
#
#===================================================================================================
labeledHeatmap.multiPage = function(
# Input data and ornament[s
Matrix,
xLabels, yLabels = NULL,
xSymbols = NULL, ySymbols = NULL,
textMatrix = NULL,
# Paging options
rowsPerPage = NULL, maxRowsPerPage = 20,
colsPerPage = NULL, maxColsPerPage = 10,
addPageNumberToMain = TRUE,
# Further arguments to labeledHeatmap
zlim = NULL,
signed = TRUE,
main = "",
...)
{
nr = nrow(Matrix);
nc = ncol(Matrix);
if (is.null(rowsPerPage))
{
nPages.rows = ceiling(nr/maxRowsPerPage);
rowsPerPage = allocateJobs(nr, nPages.rows);
} else
nPages.rows = length(rowsPerPage);
if (is.null(colsPerPage))
{
nPages.cols = ceiling(nc/maxColsPerPage);
colsPerPage = allocateJobs(nc, nPages.cols);
} else
nPages.cols = length(colsPerPage);
if (is.null(zlim))
{
zlim = range(Matrix, na.rm = TRUE)
if (signed) zlim = c(-max(abs(zlim)), max(abs(zlim)));
}
page = 1;
multiPage = (nPages.cols > 1 | nPages.rows > 1)
for (page.col in 1:nPages.cols) for (page.row in 1:nPages.rows)
{
rows = rowsPerPage[[page.row]];
cols = colsPerPage[[page.col]];
main.1 = main;
if (addPageNumberToMain & multiPage) main.1 = spaste(main, "(page ", page, ")");
labeledHeatmap(Matrix = Matrix,
xLabels = xLabels, xSymbols = xSymbols,
yLabels = yLabels, ySymbols = ySymbols,
textMatrix = textMatrix,
zlim = zlim, main = main.1,
showRows = rows, showCols = cols,
...);
page = page + 1;
}
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.