I am trying to explore EnQuireR package for questionnaire analysis (for tea data). But ENbarplot & XvsYbarplot gives error:
ENbarplot(tea, 20, numr=1, numc=1, spl=TRUE)
Error in hsv(h = a * m, s = 0.4 + (cont[j]/max) * 0.6, v = 1, 1, 1) :
unused argument (1)
&
XvsYbarplot("socio.professional.category","sex",tea, legend.text=TRUE)
Error in hsv(h = a * i, s = 1, v = 1, 1, 1) : unused argument (1)
Also, I am facing problems in interpreting the output of chisq.desc() function. Does colored cells represent significant association between corresponding variables? Can anyone please explain in detail?
The issue was with the hsv function in the graphic devices utilities. There is an extra argument passed the function making it to fail. I tried fixing it. The code below should work if you're still interested in using the package
barplot_function1 <- function (dataset, X, spl = FALSE, numr = NULL, numc = NULL,
cex = 1, colour = NULL)
{
mult = length(X)
col = rep(0)
count_mod <- rep(0)
a <- 1/mult
for (m in 1:mult) {
if (spl) {
cont <- sort(table(dataset[, X[m]]))
}
else {
cont <- table(dataset[, X[m]])
}
NR <- dim(cont)
count_mod <- c(count_mod, NR)
max <- max(cont)
coli <- rep(0, NR)
for (j in 1:NR) {
if (cont[j] == max) {
coli[j] <- hsv(h = a * m, s = 1, v = 1, 1)
}
else {
coli[j] <- hsv(h = a * m, s = 0.4 + (cont[j]/max) *
0.6, v = 1, 1)
}
}
col <- c(col, coli)
}
col <- col[-1]
count_mod <- count_mod[-1]
summ <- cumsum(count_mod)
na = matrix(0, 1, mult)
if (is.null(numr)) {
if (is.null(numc)) {
numr = numc = 2
}
}
par(mfrow = c(numr, numc), yaxt = "n")
tpolice <- par("cex")
par(xpd = T, mar = par()$mar + c(0, 1, 0, 0))
for (m in 1:mult) {
for (i in 1:((dim(dataset)[2])/(numr * numc))) {
if (m == ((numr * numc) * i) + 1) {
x11()
par(mfrow = c(numr, numc), yaxt = "n")
}
}
k = 0
for (i in 1:length(dataset[, X[m]])) {
if ((is.na(dataset[, X[m]])[[i]]) == TRUE) {
k = k + 1
}
}
na[m] = k/length(dataset[, X[m]])
if (spl == TRUE) {
coord = barplot(sort(table(dataset[, X[m]])), beside = TRUE,
las = 2, horiz = TRUE, main = names(dataset)[X[m]],
col = col[(summ[m] - count_mod[m] + 1:summ[m])])
text(x = 2, y = coord, labels = names(sort(table(dataset[,
X[m]]))), adj = 0, cex = cex, col = colour)
}
if (spl == FALSE) {
coord = barplot(table(dataset[, X[m]]), beside = TRUE,
las = 2, horiz = TRUE, main = names(dataset)[X[m]],
col = col[(summ[m] - count_mod[m] + 1:summ[m])])
text(x = 2, y = coord, labels = levels(dataset[,
X[m]]), adj = 0, cex = cex, col = colour)
}
mtext(paste(c("Percentage of missing values =", round(na[m],
2) * 100, "%"), collapse = " "), side = 3, line = -0.1,
cex = tpolice, adj = 0)
}
}
ENbarplotfixed <- function (dataset, X, spl = FALSE, numr = NULL, numc = NULL,
report = FALSE)
{
if (report == FALSE) {
barplot_function1(dataset, X, spl, numr, numc)
}
if `enter code here`(report == TRUE) {
assign("X", X, envir = .GlobalEnv)
assign("dataset", dataset, envir = .GlobalEnv)
a = getwd()
dir.create(paste(a, "/EnQuireR/", sep = ""))
file.copy(paste(.libPaths()[1], "/EnQuireR/Sweave/sty/fancyvrb.sty",
sep = ""), paste(a, "/EnQuireR/fancyvrb.sty", sep = ""))
file.copy(paste(.libPaths()[1], "/EnQuireR/Sweave/sty/Sweave.sty",
sep = ""), paste(a, "/EnQuireR/Sweave.sty", sep = ""))
file.copy(paste(.libPaths()[1], "/EnQuireR/Sweave/sty/upquote.sty",
sep = ""), paste(a, "/EnQuireR/upquote.sty", sep = ""))
file.copy(paste(.libPaths()[1], "/EnQuireR/Sweave/sty/algorithmic.sty",
sep = ""), paste(a, "/EnQuireR/algorithmic.sty",
sep = ""))
setwd(paste(a, "/EnQuireR", sep = ""))
Sweave(paste(.libPaths()[1], "/EnQuireR/Sweave/barplot/Univariate_report.Rnw",
sep = ""), driver = RweaveLatex(), syntax = getOption("SweaveSyntax"))
tools::texi2dvi(paste(a, "/EnQuireR/Univariate_report.tex",
sep = ""), pdf = TRUE)
setwd(a)
}
}
#plot
ENbarplotfixed(tea,20,spl=T,numr=1,numc=1)
#plot upon condition
XvsYbarplotfixed <- XvsYbarplotfixed <- function (var1, var2, dataset, width = 1, space = NULL, names.arg = NULL,
legend.text = NULL, horiz = FALSE, density = NULL, angle = 45,
col = NULL, border = par("fg"), main = NULL, sub = NULL,
xlab = NULL, ylab = NULL, xlim = NULL, ylim = NULL, xpd = TRUE,
log = "", axes = TRUE, axisnames = TRUE, cex.axis = par("cex.axis"),
cex.names = par("cex.axis"), inside = TRUE, plot = TRUE,
axis.lty = 0, offset = 0, add = FALSE, ...)
{
dataset <- as.data.frame(dataset)
if (is.character(var1) & is.character(var2)) {
num_var1 <- match(var1, names(dataset))
num_var2 <- match(var2, names(dataset))
height <- table(dataset[, num_var1], dataset[, num_var2])
}
else {
height <- table(var1, var2)
}
if (!missing(inside))
.NotYetUsed("inside", error = FALSE)
if (is.null(space))
space <- if (is.matrix(height))
c(0, 1)
else 0.2
space <- space * mean(width)
if (plot && axisnames && is.null(names.arg))
names.arg <- if (is.matrix(height))
colnames(height)
else names(height)
if (is.vector(height) || (is.array(height) && (length(dim(height)) ==
1))) {
height <- cbind(height)
if (is.null(col))
if (is.null(col))
col <- rep(0)
NR <- length(height)
max <- max(height)
for (i in 1:NR) {
if (height[i] == max) {
coli <- hsv(h = 1, s = 1, v = 1, 1)
col <- cbind(col, coli)
}
else {
coli <- hsv(h = 1, s = 0.4 + (height[i]/max) *
0.6, v = 1, 1)
col <- c(col, coli)
}
}
col <- col[-1]
}
else if (is.matrix(height)) {
if (is.null(col))
NR <- nrow(height)
NC <- ncol(height)
col = rep(0)
a <- 1/NC
for (i in 1:NC) {
max <- max(height[, i])
coli <- rep(0, NR)
for (j in 1:NR) {
if (height[j, i] == max) {
coli[j] <- hsv(h = a * i, s = 1, v = 1, 1)
}
else {
coli[j] <- hsv(h = a * i, s = 0.4 + (height[j,
i]/max) * 0.6, v = 1, 1)
}
}
col <- c(col, coli)
}
col <- col[-1]
}
else stop("'height' must be a vector or a matrix")
if (is.logical(legend.text))
legend.text <- if (legend.text && is.matrix(height))
rownames(height)
stopifnot(is.character(log))
logx <- logy <- FALSE
if (log != "") {
logx <- length(grep("x", log)) > 0L
logy <- length(grep("y", log)) > 0L
}
if ((logx || logy) && !is.null(density))
stop("Cannot use shading lines in bars when log scale is used")
NR <- nrow(height)
NC <- ncol(height)
if (length(space) == 2)
space <- rep.int(c(space[2], rep.int(space[1], NR - 1)),
NC)
width <- rep(width, length.out = NR)
offset <- rep(as.vector(offset), length.out = length(width))
delta <- width/2
w.r <- cumsum(space + width)
w.m <- w.r - delta
w.l <- w.m - delta
log.dat <- (logx && horiz) || (logy && !horiz)
if (log.dat) {
if (min(height + offset, na.rm = TRUE) <= 0)
stop("log scale error: at least one 'height + offset' value <= 0")
if (logx && !is.null(xlim) && min(xlim) <= 0)
stop("log scale error: 'xlim' <= 0")
if (logy && !is.null(ylim) && min(ylim) <= 0)
stop("log scale error: 'ylim' <= 0")
rectbase <- if (logy && !horiz && !is.null(ylim))
ylim[1]
else if (logx && horiz && !is.null(xlim))
xlim[1]
else 0.9 * min(height, na.rm = TRUE)
}
else rectbase <- 0
rAdj <- offset + (if (log.dat)
0.9 * height
else -0.01 * height)
delta <- width/2
w.r <- cumsum(space + width)
w.m <- w.r - delta
w.l <- w.m - delta
num_mod <- nlevels(var1)
if (horiz) {
if (is.null(xlim))
xlim <- range(rAdj, height + offset, na.rm = TRUE)
if (is.null(ylim))
ylim <- c(min(w.l), max(w.r) + num_mod + (num_mod -
1))
}
else {
if (is.null(xlim))
xlim <- c(min(w.l), max(w.r))
if (is.null(ylim))
ylim <- range(rAdj, height + offset + num_mod * 5,
na.rm = TRUE)
}
w.m <- matrix(w.m, ncol = NC)
par(mar = par("mar") + c(1, 0, 0, 0))
if (plot) {
opar <- if (horiz)
par(xaxs = "i", xpd = xpd)
else par(yaxs = "i", xpd = xpd)
on.exit(par(opar))
if (!add) {
plot.new()
if (horiz) {
if (is.character(attributes(var1)$levels) ==
TRUE) {
if (max(nchar(attributes(var1)$levels)) > 8) {
par(mar = par("mar") + c(0, round(max(nchar(attributes(var1)$levels))/3),
0, 0))
}
}
else {
par(mar = par("mar") + c(0, 5, 0, 0))
}
plot.window(xlim, ylim, log = log, ...)
}
else plot.window(xlim, ylim, log = log, ...)
}
xyrect <- function(x1, y1, x2, y2, horizontal = TRUE,
...) {
if (horizontal)
rect(x1, y1, x2, y2, ...)
else rect(y1, x1, y2, x2, ...)
}
xyrect(rectbase + offset, w.l, c(height) + offset, w.r,
horizontal = horiz, angle = angle, density = density,
col = col, border = border)
if (axisnames && !is.null(names.arg)) {
at.l <- if (length(names.arg) != length(w.m)) {
if (length(names.arg) == NC)
colMeans(w.m)
else stop("incorrect number of names")
}
else w.m
if (!horiz)
if (is.character(attributes(var1)$levels) ==
TRUE) {
for (i in 1:nlevels(var2)) {
if (nchar(attributes(var2)$levels[i]) > 11)
names.arg[i] <- substring(attributes(var2)$levels[i],
1, 11)
}
}
if (horiz) {
axis(2, at = at.l, labels = names.arg, lty = axis.lty,
cex.axis = cex.names, las = 2)
}
else {
axis(1, at = at.l, labels = names.arg, lty = axis.lty,
cex.axis = cex.names, las = 0)
}
}
if (!is.null(legend.text)) {
legend.col <- rep(col, length.out = length(legend.text))
if (!horiz) {
legend.text <- legend.text
legend.col <- legend.col
density <- rev(density)
angle <- rev(angle)
}
num.legend <- c("1st", "2nd", "3rd")
for (i in 4:20) {
num.legendi <- c(paste(i, "th"))
num.legend <- c(num.legend, num.legendi)
}
num.legend <- num.legend[1:dim(height)[1]]
xy <- par("usr")
if (horiz) {
legend2(xy[2] - xinch(0.1), xy[4] - yinch(0.1),
legend = paste(num.legend, "bar:", legend.text),
angle = angle, density = density, fill = legend.col,
bty = "n", cex = 1 - 0.04 * num_mod, xjust = 1,
yjust = 1)
}
else {
legend2(xy[2] - xinch(0.1), xy[4] - yinch(0.1),
legend = paste(num.legend, "bar:", legend.text),
angle = angle, density = density, fill = legend.col,
bty = "n", xjust = 1, yjust = 1)
}
}
if (is.character(var1) & is.character(var2)) {
title(main = paste(names(dataset[num_var1]), "depending on",
names(dataset[num_var2])), sub = sub, xlab = xlab,
ylab = ylab, ...)
}
else {
for (i in 1:length(dataset)) {
a <- match(var1, dataset[, i])
b <- match(var2, dataset[, i])
if (any(is.na(a)) == FALSE) {
rep1 = i
}
if (any(is.na(b)) == FALSE) {
rep2 = i
}
}
title(main = paste(names(dataset[rep1]), "depending on",
names(dataset[rep2])), sub = sub, xlab = xlab,
ylab = ylab, ...)
}
if (axes)
if (horiz) {
axis(1, cex.axis = cex.axis, las = 0, ...)
}
else {
axis(2, cex.axis = cex.axis, las = 2, ...)
}
invisible(w.m)
}
else w.m
}
Related
I use this example
library(alluvial)
tit <- as.data.frame(Titanic)
# only two variables: class and survival status
tit2d <- aggregate( Freq ~ Class + Survived, data=tit, sum)
alluvial( tit2d[,1:2], freq=tit2d$Freq, xw=0.0, alpha=0.8,
gap.width=0.1, col= "steelblue", border="white",
layer = tit2d$Survived != "Yes" , cex.axis =8)
Pay attention I use cex.axis =8 and i get
Axis labels go beyond
I try to use par(mar=c(10, 10, 10, 10)) but no result
thanks for any idea
There is a bug in the source code of the alluvial function
The function sets par(mar=c(2,1,1,1)) hard coded so using the par() outside doesn't have any effect.
You could change locally the source code of the function to one of 2 options:
add an argument mar_ and pass the margin, and set at the right place par(mar=mar_).
just overwrite locally the line to the desired margins
I found the first option more appealing because you can then set the values from outside the function and optimise more easily.
The source code:
function (..., freq, col = "gray", border = 0, layer, hide = FALSE,
alpha = 0.5, gap.width = 0.05, xw = 0.1, cw = 0.1, blocks = TRUE,
ordering = NULL, axis_labels = NULL, cex = par("cex"), cex.axis = par("cex.axis"))
{
p <- data.frame(..., freq = freq, col, alpha, border, hide,
stringsAsFactors = FALSE)
np <- ncol(p) - 5
if (!is.null(ordering)) {
stopifnot(is.list(ordering))
if (length(ordering) != np)
stop("'ordering' argument should have ", np, " components, has ",
length(ordering))
}
n <- nrow(p)
if (missing(layer)) {
layer <- 1:n
}
p$layer <- layer
d <- p[, 1:np, drop = FALSE]
p <- p[, -c(1:np), drop = FALSE]
p$freq <- with(p, freq/sum(freq))
col <- col2rgb(p$col, alpha = TRUE)
if (!identical(alpha, FALSE)) {
col["alpha", ] <- p$alpha * 256
}
p$col <- apply(col, 2, function(x) do.call(rgb, c(as.list(x),
maxColorValue = 256)))
isch <- sapply(d, is.character)
d[isch] <- lapply(d[isch], as.factor)
if (length(blocks) == 1) {
blocks <- if (!is.na(as.logical(blocks))) {
rep(blocks, np)
}
else if (blocks == "bookends") {
c(TRUE, rep(FALSE, np - 2), TRUE)
}
}
if (is.null(axis_labels)) {
axis_labels <- names(d)
}
else {
if (length(axis_labels) != ncol(d))
stop("`axis_labels` should have length ", names(d),
", has ", length(axis_labels))
}
getp <- function(i, d, f, w = gap.width) {
a <- c(i, (1:ncol(d))[-i])
if (is.null(ordering[[i]])) {
o <- do.call(order, d[a])
}
else {
d2 <- d
d2[1] <- ordering[[i]]
o <- do.call(order, d2[a])
}
x <- c(0, cumsum(f[o])) * (1 - w)
x <- cbind(x[-length(x)], x[-1])
gap <- cumsum(c(0L, diff(as.numeric(d[o, i])) != 0))
mx <- max(gap)
if (mx == 0)
mx <- 1
gap <- gap/mx * w
(x + gap)[order(o), ]
}
dd <- lapply(seq_along(d), getp, d = d, f = p$freq)
rval <- list(endpoints = dd)
===============================================
===============Need to edit====================
op <- par(mar = c(2, 1, 1, 1))
===============================================
plot(NULL, type = "n", xlim = c(1 - cw, np + cw), ylim = c(0,
1), xaxt = "n", yaxt = "n", xaxs = "i", yaxs = "i", xlab = "",
ylab = "", frame = FALSE)
ind <- which(!p$hide)[rev(order(p[!p$hide, ]$layer))]
for (i in ind) {
for (j in 1:(np - 1)) {
xspline(c(j, j, j + xw, j + 1 - xw, j + 1, j + 1,
j + 1 - xw, j + xw, j) + rep(c(cw, -cw, cw),
c(3, 4, 2)), c(dd[[j]][i, c(1, 2, 2)], rev(dd[[j +
1]][i, c(1, 1, 2, 2)]), dd[[j]][i, c(1, 1)]),
shape = c(0, 0, 1, 1, 0, 0, 1, 1, 0, 0), open = FALSE,
col = p$col[i], border = p$border[i])
}
}
for (j in seq_along(dd)) {
ax <- lapply(split(dd[[j]], d[, j]), range)
if (blocks[j]) {
for (k in seq_along(ax)) {
rect(j - cw, ax[[k]][1], j + cw, ax[[k]][2])
}
}
else {
for (i in ind) {
x <- j + c(-1, 1) * cw
y <- t(dd[[j]][c(i, i), ])
w <- xw * (x[2] - x[1])
xspline(x = c(x[1], x[1], x[1] + w, x[2] - w,
x[2], x[2], x[2] - w, x[1] + w, x[1]), y = c(y[c(1,
2, 2), 1], y[c(2, 2, 1, 1), 2], y[c(1, 1),
1]), shape = c(0, 0, 1, 1, 0, 0, 1, 1, 0, 0),
open = FALSE, col = p$col[i], border = p$border[i])
}
}
for (k in seq_along(ax)) {
text(j, mean(ax[[k]]), labels = names(ax)[k], cex = cex)
}
}
axis(1, at = rep(c(-cw, cw), ncol(d)) + rep(seq_along(d),
each = 2), line = 0.5, col = "white", col.ticks = "black",
labels = FALSE)
axis(1, at = seq_along(d), tick = FALSE, labels = axis_labels,
cex.axis = cex.axis)
par(op)
invisible(rval)
}
I marked where the problem occur as:
================================================
==============Need to edit======================
op <- par(mar = c(2, 1, 1, 1))
================================================
After changing the line to par(mar=c(5, 5, 3, 10)) I got:
I am trying to use twoord.plot with different dates on x axis and counts for ly and percentages for ry, and I want to remove axis 3 or change its color. Setting axes = F does not work, neither does xaxt = 'n'.
In fact, axes = FALSE gives me this error message:
Error in plot.default(lx, ly, xlim = xlim, ylim = lylim, xlab = xlab, :
formal argument "axes" matched by multiple actual arguments
The solution given here:
Remove all axis values and labels in twoord plot does not work for me with different rx and lx.
Here is a similar code to that I'm using:
set.seed(123)
library(plotrix)
twoord.plot(
lx = seq(as.Date("2016-01-01"), as.Date("2017-01-01"), by = "days"),
ly = round(runif(367) * 6),
rx = seq(as.Date("2016-05-09"), as.Date("2017-01-12"), by = "days"),
ry = sort(rnorm(249, 60, 10)),
lylim = range(round(runif(367) * 6)) + c(0, 10),
rylim = range(sort(rnorm(249, 60, 10))) + c(-35, 10),
ylab.at = mean(round(runif(367) * 6)),
rylab.at = mean(sort(rnorm(249, 60, 10))),
rylab = "Percentages %", ylab = "No. of x",
type = c("l", "l"), lcol = "skyblue4", rcol = "chocolate1" ,
xtickpos = as.numeric(seq(as.Date("2016-01-01"), as.Date("2017-01-01"), by = "months")),
xticklab = seq(as.Date("2016-01-01"), as.Date("2017-01-01"), by = "months"))
Any ideas on how to this? Thanks in advance! :)
Just hack the twoord.plot function. Here's an example to make all axis labels black (Use twoord.plot2 instead of twoord.plot when creating the plot). If you want to remove the axes altogether, just comment (add # before the lines) Lines 88-90 (For ly) and Lines 123-125 (for ry). I have left notes for them in the function below.
twoord.plot2 = function (lx, ly, rx, ry, data = NULL, main = "", xlim = NULL,
lylim = NULL, rylim = NULL, mar = c(5, 4, 4, 4), lcol = 1,
rcol = 2, xlab = "", lytickpos = NA, ylab = "", ylab.at = NA,
rytickpos = NA, rylab = "", rylab.at = NA, lpch = 1, rpch = 2,
type = "b", xtickpos = NULL, xticklab = NULL, halfwidth = 0.4,
axislab.cex = 1, do.first = NULL, ...)
{
if (!is.null(data)) {
ly <- unlist(data[ly])
ry <- unlist(data[ry])
if (missing(lx))
lx <- 1:length(ly)
else lx <- unlist(data[lx])
if (missing(rx))
rx <- 1:length(ry)
else rx <- unlist(data[rx])
}
if (missing(lx))
lx <- 1:length(ly)
if (missing(ry)) {
if (missing(rx)) {
rx <- 1:length(ry)
ry <- ly
ly <- lx
lx <- 1:length(ly)
}
else {
ry <- rx
rx <- 1:length(ry)
}
}
oldmar <- par("mar")
par(mar = mar)
if (is.null(xlim))
xlim <- range(c(lx, rx))
if (missing(lx))
lx <- 1:length(ly)
if (is.null(lylim)) {
lylim <- range(ly, na.rm = TRUE)
lyspan <- diff(lylim)
if (lyspan == 0)
lyspan <- lylim[1]
lylim[2] <- lylim[2] + lyspan * 0.04
if (lylim[1] != 0)
lylim[1] <- lylim[1] - lyspan * 0.04
}
if (length(type) < 2)
type <- rep(type, 2)
if (match(type[1], "bar", 0)) {
oldcex <- par(cex = axislab.cex)
plot(lx, ly, xlim = xlim, ylim = lylim, xlab = xlab,
ylab = "", yaxs = "i", type = "n", main = "", axes = FALSE,
...)
par(oldcex)
if (!is.null(do.first))
eval(parse(text = do.first))
ybottom <- par("usr")[3]
if (lylim[1] < 0)
abline(h = 0, lty = 2)
rect(lx - halfwidth, ifelse(ly < 0, ly, ybottom), lx +
halfwidth, ifelse(ly > 0, ly, 0), col = lcol)
}
else {
oldcex <- par(cex = axislab.cex)
plot(lx, ly, xlim = xlim, ylim = lylim, xlab = xlab,
ylab = "", yaxs = "i", type = "n", main = "", axes = FALSE,
...)
par(oldcex)
if (!is.null(do.first))
eval(parse(text = do.first))
points(lx, ly, col = lcol, pch = lpch, type = type[1],
...)
}
title(main = main)
xylim <- par("usr")
box()
if (is.null(xticklab))
axis(1, cex.axis = axislab.cex)
else {
if (is.null(xtickpos))
xtickpos <- 1:length(xticklab)
axis(1, at = xtickpos, labels = xticklab, cex.axis = axislab.cex)
}
if (is.na(lytickpos[1]))
lytickpos <- pretty(ly)
if (is.na(ylab.at))
ylab.at <- mean(lytickpos)
color.axis(2, at = lytickpos, axlab = ylab, axlab.at = ylab.at, #LINE 88
col = "black", cex.axis = axislab.cex, #col = ifelse(is.na(lcol), 1, lcol), cex.axis = axislab.cex,
cex = axislab.cex) #LINE 90
if (is.null(rylim)) {
rylim <- range(ry, na.rm = TRUE)
ryspan <- diff(rylim)
if (ryspan == 0)
ryspan <- rylim[1]
rylim[2] <- rylim[2] + ryspan * 0.04
if (rylim[1] != 0)
rylim[1] <- rylim[1] - ryspan * 0.04
}
ymult <- diff(lylim)/diff(rylim)
yoff <- lylim[1] - rylim[1] * ymult
if (match(type[2], "bar", 0)) {
if (rylim[1] < 0)
abline("h", 0)
rect(rx - halfwidth, ifelse(ry < 0, ry, rylim[1] * ymult +
yoff), rx + halfwidth, ifelse(ry > 0, ry * ymult +
yoff, 0), col = rcol)
}
else points(rx, ry * ymult + yoff, col = rcol, pch = rpch,
type = type[2], ...)
if (is.na(rytickpos[1]))
rylabels <- pretty(rylim)
else rylabels <- rytickpos
if (min(rylabels) < rylim[1])
rylabels <- rylabels[rylabels >= rylim[1]]
if (max(rylabels) > rylim[2])
rylabels <- rylabels[rylabels <= rylim[2]]
axat <- rylabels * ymult + yoff
if (is.na(rylab.at))
rylab.at <- mean(rytickpos)
if (!is.na(rylab.at))
rylab.at <- rylab.at * ymult + yoff
color.axis(4, at = axat, labels = rylabels, axlab = rylab, #LINE 123
axlab.at = rylab.at, col = "black", #axlab.at = rylab.at, col = ifelse(is.na(rcol), 1, rcol),
cex.axis = axislab.cex, cex = axislab.cex) #LINE 125
par(mar = oldmar, new = FALSE, col.axis = "black")
}
I'm plotting an incidence curve using the survplot package in R. I'm using the xlim option to limit the x-axis of my graph from 0-28. However, when I do this the x-axis will always extend to 30. The maximum potential value I have in my data is 28. Is there a way I can trim the x-axis to 28 instead of 30?
Here is my code and an example of the graph with the extra x-axis.
survplot(Survobj,
ylim=c(0,10),
xlim=c(0,28),
ylab = "Cumulative Incidence, %",
conf=c("bands"),
fun=function(x) {100*(1-x)},
n.risk=FALSE,
time.inc=1,
cex.n.risk=0.9)
I would attach an image, but I need 10 reputations points to do so (sorry!)
The code for survplot.rms (which has the same parameters as you are using and does exhibit the behavior you're describing) is base-R-grphics and it uses the pretty function to build the x-axis:
pretty(c(0,28))
#[1] 0 5 10 15 20 25 30
So if you want to change its behavior you will need to hack the code. It's not that hard to hack R code, but it's unclear to me whether you are ready for that adventure since you didn't even name the package from which you got the function correctly. It is a fairly long function. Experience has taught me that I need to provide newbies with a turnkey solution rather than just telling them to add a parameter and find the sections in the code to tweak. Here's how to add a 'notpretty' parameter that is used to determine whether just the max or the pretty function is used on the xlim argument:
survplot2 <- function (fit, ..., xlim, ylim = if (loglog) c(-5, 1.5) else if (what ==
"survival" & missing(fun)) c(0, 1), xlab, ylab, time.inc,
what = c("survival", "hazard"), type = c("tsiatis", "kaplan-meier"),
conf.type = c("log", "log-log", "plain", "none"), conf.int = FALSE,
conf = c("bands", "bars"), add = FALSE, label.curves = TRUE,
abbrev.label = FALSE, levels.only = FALSE, lty, lwd = par("lwd"),
col = 1, col.fill = gray(seq(0.95, 0.75, length = 5)), adj.subtitle = TRUE,
loglog = FALSE, fun, n.risk = FALSE, logt = FALSE, dots = FALSE,
dotsize = 0.003, grid = NULL, srt.n.risk = 0, sep.n.risk = 0.056,
adj.n.risk = 1, y.n.risk, cex.n.risk = 0.6, pr = FALSE,notpretty=FALSE)
{
what <- match.arg(what)
polyg <- ordGridFun(grid = FALSE)$polygon
ylim <- ylim
type <- match.arg(type)
conf.type <- match.arg(conf.type)
conf <- match.arg(conf)
opar <- par(c("mar", "xpd"))
on.exit(par(opar))
psmfit <- inherits(fit, "psm")
if (what == "hazard" && !psmfit)
stop("what=\"hazard\" may only be used for fits from psm")
if (what == "hazard" & conf.int > 0) {
warning("conf.int may only be used with what=\"survival\"")
conf.int <- FALSE
}
if (loglog) {
fun <- function(x) logb(-logb(ifelse(x == 0 | x == 1,
NA, x)))
use.fun <- TRUE
}
else if (!missing(fun)) {
use.fun <- TRUE
if (loglog)
stop("cannot specify loglog=T with fun")
}
else {
fun <- function(x) x
use.fun <- FALSE
}
if (what == "hazard" & loglog)
stop("may not specify loglog=T with what=\"hazard\"")
if (use.fun | logt | what == "hazard") {
dots <- FALSE
grid <- NULL
}
cox <- inherits(fit, "cph")
if (cox) {
if (n.risk | conf.int > 0)
surv.sum <- fit$surv.summary
exactci <- !(is.null(fit$x) | is.null(fit$y))
ltype <- "s"
}
else {
if (n.risk)
stop("the n.risk option applies only to fits from cph")
exactci <- TRUE
ltype <- "l"
}
par(xpd = NA)
ciupper <- function(surv, d) ifelse(surv == 0, 0, pmin(1,
surv * exp(d)))
cilower <- function(surv, d) ifelse(surv == 0, 0, surv *
exp(-d))
labelc <- is.list(label.curves) || label.curves
units <- fit$units
if (missing(ylab)) {
if (loglog)
ylab <- "log(-log Survival Probability)"
else if (use.fun)
ylab <- ""
else if (what == "hazard")
ylab <- "Hazard Function"
else ylab <- "Survival Probability"
}
if (missing(xlab)) {
if (logt)
xlab <- paste("log Survival Time in ", units, "s",
sep = "")
else xlab <- paste(units, "s", sep = "")
}
maxtime <- fit$maxtime
maxtime <- max(pretty(c(0, maxtime)))
if (missing(time.inc))
time.inc <- fit$time.inc
if (missing(xlim))
xlim <- if (logt)
logb(c(maxtime/100, maxtime))
else c(0, maxtime)
if (length(grid) && is.logical(grid))
grid <- if (grid)
gray(0.8)
else NULL
if (is.logical(conf.int)) {
if (conf.int)
conf.int <- 0.95
else conf.int <- 0
}
zcrit <- qnorm((1 + conf.int)/2)
xadj <- Predict(fit, type = "model.frame", np = 5, factors = rmsArgs(substitute(list(...))))
info <- attr(xadj, "info")
varying <- info$varying
if (length(varying) > 1)
stop("cannot vary more than one predictor")
adjust <- if (adj.subtitle)
info$adjust
else NULL
if (length(xadj)) {
nc <- nrow(xadj)
covpres <- TRUE
}
else {
nc <- 1
covpres <- FALSE
}
y <- if (length(varying))
xadj[[varying]]
else ""
curve.labels <- NULL
xd <- xlim[2] - xlim[1]
if (n.risk & !add) {
mar <- opar$mar
if (mar[4] < 4) {
mar[4] <- mar[4] + 2
par(mar = mar)
}
}
lty <- if (missing(lty))
seq(nc + 1)[-2]
else rep(lty, length = nc)
col <- rep(col, length = nc)
lwd <- rep(lwd, length = nc)
i <- 0
if (levels.only)
y <- gsub(".*=", "", y)
abbrevy <- if (abbrev.label)
abbreviate(y)
else y
abbrevy <- if (is.factor(abbrevy))
as.character(abbrevy)
else format(abbrevy)
if (labelc || conf == "bands")
curves <- vector("list", nc)
for (i in 1:nc) {
ci <- conf.int
ay <- if (length(varying))
xadj[[varying]]
else ""
if (covpres) {
adj <- xadj[i, , drop = FALSE]
w <- survest(fit, newdata = adj, fun = fun, what = what,
conf.int = ci, type = type, conf.type = conf.type)
}
else w <- survest(fit, fun = fun, what = what, conf.int = ci,
type = type, conf.type = conf.type)
time <- w$time
if (logt)
time <- logb(time)
s <- !is.na(time) & (time >= xlim[1])
surv <- w$surv
if (is.null(ylim))
ylim <- range(surv, na.rm = TRUE)
stratum <- w$strata
if (is.null(stratum))
stratum <- 1
if (!is.na(stratum)) {
cl <- if (is.factor(ay))
as.character(ay)
else format(ay)
curve.labels <- c(curve.labels, abbrevy[i])
if (i == 1 & !add) {
plot(time, surv, xlab = xlab, xlim = xlim, ylab = ylab,
ylim = ylim, type = "n", axes = FALSE)
mgp.axis(1, at = if (logt)
pretty(xlim)
# This is the line that was changed -----------------------
else seq(xlim[1], if(notpretty){max(xlim)}else{max(pretty(xlim))}, time.inc),
# end of modifications ------------------------
labels = TRUE)
mgp.axis(2, at = pretty(ylim))
if (!logt & (dots || length(grid))) {
xlm <- pretty(xlim)
xlm <- c(xlm[1], xlm[length(xlm)])
xp <- seq(xlm[1], xlm[2], by = time.inc)
yd <- ylim[2] - ylim[1]
if (yd <= 0.1)
yi <- 0.01
else if (yd <= 0.2)
yi <- 0.025
else if (yd <= 0.4)
yi <- 0.05
else yi <- 0.1
yp <- seq(ylim[2], ylim[1] + if (n.risk &&
missing(y.n.risk))
yi
else 0, by = -yi)
if (dots)
for (tt in xp) symbols(rep(tt, length(yp)),
yp, circles = rep(dotsize, length(yp)),
inches = dotsize, add = TRUE)
else abline(h = yp, v = xp, col = grid, xpd = FALSE)
}
}
tim <- time[s]
srv <- surv[s]
if (conf.int > 0 && conf == "bands") {
blower <- w$lower[s]
bupper <- w$upper[s]
}
if (max(tim) > xlim[2]) {
if (ltype == "s") {
s.last <- srv[tim <= xlim[2] + 1e-06]
s.last <- s.last[length(s.last)]
k <- tim < xlim[2]
tim <- c(tim[k], xlim[2])
srv <- c(srv[k], s.last)
if (conf.int > 0 && conf == "bands") {
low.last <- blower[time <= xlim[2] + 1e-06]
low.last <- low.last[length(low.last)]
up.last <- bupper[time <= xlim[2] + 1e-06]
up.last <- up.last[length(up.last)]
blower <- c(blower[k], low.last)
bupper <- c(bupper[k], up.last)
}
}
else tim[tim > xlim[2]] <- NA
}
if (conf != "bands")
lines(tim, srv, type = ltype, lty = lty[i], col = col[i],
lwd = lwd[i])
if (labelc || conf == "bands")
curves[[i]] <- list(tim, srv)
if (pr) {
zest <- rbind(tim, srv)
dimnames(zest) <- list(c("Time", "Survival"),
rep("", length(srv)))
cat("\nEstimates for ", cl, "\n\n")
print(zest, digits = 3)
}
if (conf.int > 0) {
if (conf == "bands") {
polyg(x = c(tim, rev(tim)), y = c(blower, rev(bupper)),
col = col.fill[i], type = ltype)
}
else {
if (exactci) {
tt <- seq(0, maxtime, time.inc)
v <- survest(fit, newdata = adj, times = tt,
what = what, fun = fun, conf.int = ci,
type = type, conf.type = conf.type)
tt <- v$time
ss <- v$surv
lower <- v$lower
upper <- v$upper
if (!length(ylim))
ylim <- range(ss, na.rm = TRUE)
if (logt)
tt <- logb(ifelse(tt == 0, NA, tt))
}
else {
tt <- as.numeric(dimnames(surv.sum)[[1]])
if (logt)
tt <- logb(tt)
ss <- surv.sum[, stratum, "Survival"]^exp(w$linear.predictors)
se <- surv.sum[, stratum, "std.err"]
ss <- fun(ss)
lower <- fun(cilower(ss, zcrit * se))
upper <- fun(ciupper(ss, zcrit * se))
ss[is.infinite(ss)] <- NA
lower[is.infinite(lower)] <- NA
upper[is.infinite(upper)] <- NA
}
tt <- tt + xd * (i - 1) * 0.01
errbar(tt, ss, upper, lower, add = TRUE, lty = lty[i],
col = col[i])
}
}
if (n.risk) {
if (length(Y <- fit$y)) {
tt <- seq(max(0, xlim[1]), min(maxtime, xlim[2]),
by = time.inc)
ny <- ncol(Y)
if (!length(str <- fit$Strata))
Y <- Y[, ny - 1]
else Y <- Y[unclass(str) == unclass(stratum),
ny - 1]
nrisk <- rev(cumsum(table(cut(-Y, sort(unique(-c(tt,
range(Y) + c(-1, 1))))))[-length(tt) - 1]))
}
else {
if (is.null(surv.sum))
stop("you must use surv=T or y=T in fit to use n.risk=T")
tt <- as.numeric(dimnames(surv.sum)[[1]])
l <- (tt >= xlim[1]) & (tt <= xlim[2])
tt <- tt[l]
nrisk <- surv.sum[l, stratum, 2]
}
tt[1] <- xlim[1]
yd <- ylim[2] - ylim[1]
if (missing(y.n.risk))
y.n.risk <- ylim[1]
yy <- y.n.risk + yd * (nc - i) * sep.n.risk
nri <- nrisk
nri[tt > xlim[2]] <- NA
text(tt[1], yy, nri[1], cex = cex.n.risk, adj = adj.n.risk,
srt = srt.n.risk)
text(tt[-1], yy, nri[-1], cex = cex.n.risk, adj = 1)
text(xlim[2] + xd * 0.025, yy, adj = 0, curve.labels[i],
cex = cex.n.risk)
}
}
}
if (conf == "bands")
for (i in 1:length(y)) lines(curves[[i]][[1]], curves[[i]][[2]],
type = ltype, lty = lty[i], col = col[i], lwd = lwd[i])
if (labelc)
labcurve(curves, curve.labels, type = ltype, lty = lty,
col. = col, lwd = lwd, opts = label.curves)
if (length(adjust))
title(sub = paste("Adjusted to:", adjust), adj = 0, cex = 0.6)
invisible(list(adjust = adjust, curve.labels = curve.labels))
}
environment(survplot2) <- environment(rms:::survplot.rms)
Tested with the first example in rms::survplot using xlim=c(0,26) and xlim=c(0,28). Needed to assign the environment because otherwise you get this error:
Error in Predict(fit, type = "model.frame", np = 5,
factors = rmsArgs(substitute(list(...)))) :
could not find function "rmsArgs"
I am plotting correlation plot with corrplot. I want to plot also the correlation coefficients:
require(corrplot)
test <- matrix(data = rnorm(400), nrow=20, ncol=20)
corrplot(cor(test), method = "color", addCoef.col="grey", order = "AOE")
But they are too big in the plot:
Is there any way to make the font of the coefficent smaller? I've been looking at ?corrplot but there are only parameters to change the legend and axis font sizes (cl.cex and tl.cex). pch.cex doesn't work either.
The option to use is number.cex=.
As in the following:
corrplot(cor(test),
method = "color",
addCoef.col="grey",
order = "AOE",
number.cex=0.75)
To make it dynamic, try number.cex= 7/ncol(df) where df is dataframe for which the correlation was run.
It is far from the answer, it is kind of a dirty hack, but this works (thanks user20650 for the idea):
cex.before <- par("cex")
par(cex = 0.7)
corrplot(cor(envV), p.mat = cor1[[1]], insig = "blank", method = "color",
addCoef.col="grey",
order = "AOE", tl.cex = 1/par("cex"),
cl.cex = 1/par("cex"), addCoefasPercent = TRUE)
par(cex = cex.before)
I had exactly the same problem a little while ago when I had to do a corrplot similar to yours. After a lot of searching I found a solution which involves printing the correlation plot to a png file and altering the parameters there.
i.e.:
library(corrplot)
test <- matrix(data = rnorm(400), nrow=20, ncol=20)
png(height=1200, width=1500, pointsize=15, file="overlap.png")
corrplot(cor(test), method = "color", addCoef.col="grey", order = "AOE")
The part that increases/decreases the font inside the cells is parameter pointsize. setting it to 15 you can see that the numbers now fit the cells.
You may also find this link helpful. it certainly helped me.
I would define my own size value since the function just ommited allowing for a size to be added to that text. Below is the function recreated with an extra number.cex paramater added at the end, which controls the number label size now.
corrplot2 <- function (corr, method = c("circle", "square", "ellipse", "number",
"shade", "color", "pie"), type = c("full", "lower", "upper"),
add = FALSE, col = NULL, bg = "white", title = "", is.corr = TRUE,
diag = TRUE, outline = FALSE, mar = c(0, 0, 0, 0), addgrid.col = NULL,
addCoef.col = NULL, addCoefasPercent = FALSE, order = c("original",
"AOE", "FPC", "hclust", "alphabet"), hclust.method = c("complete",
"ward", "single", "average", "mcquitty", "median", "centroid"),
addrect = NULL, rect.col = "black", rect.lwd = 2, tl.pos = NULL,
tl.cex = 1, tl.col = "red", tl.offset = 0.4, tl.srt = 90,
cl.pos = NULL, cl.lim = NULL, cl.length = NULL, cl.cex = 0.8,
cl.ratio = 0.15, cl.align.text = "c", cl.offset = 0.5, addshade = c("negative",
"positive", "all"), shade.lwd = 1, shade.col = "white",
p.mat = NULL, sig.level = 0.05, insig = c("pch", "p-value",
"blank", "n"), pch = 4, pch.col = "black", pch.cex = 3,
plotCI = c("n", "square", "circle", "rect"), lowCI.mat = NULL,
uppCI.mat = NULL, number.cex = 0.7, ...)
{
method <- match.arg(method)
type <- match.arg(type)
order <- match.arg(order)
hclust.method <- match.arg(hclust.method)
plotCI <- match.arg(plotCI)
insig <- match.arg(insig)
if (!is.matrix(corr) & !is.data.frame(corr))
stop("Need a matrix or data frame!")
if (is.null(addgrid.col)) {
addgrid.col <- ifelse(method == "color" | method == "shade",
"white", "grey")
}
if (any(corr < cl.lim[1]) | any(corr > cl.lim[2]))
stop("color limits should cover matrix")
if (is.null(cl.lim)) {
if (is.corr)
cl.lim <- c(-1, 1)
if (!is.corr)
cl.lim <- c(min(corr), max(corr))
}
intercept <- 0
zoom <- 1
if (!is.corr) {
if (max(corr) * min(corr) < 0) {
intercept <- 0
zoom <- 1/max(abs(cl.lim))
}
if (min(corr) >= 0) {
intercept <- -cl.lim[1]
zoom <- 1/(diff(cl.lim))
}
if (max(corr) <= 0) {
intercept <- -cl.lim[2]
zoom <- 1/(diff(cl.lim))
}
corr <- (intercept + corr) * zoom
}
cl.lim2 <- (intercept + cl.lim) * zoom
int <- intercept * zoom
if (min(corr) < -1 - .Machine$double.eps || max(corr) > 1 +
.Machine$double.eps) {
stop("The matrix is not in [-1, 1]!")
}
if (is.null(col)) {
col <- colorRampPalette(c("#67001F", "#B2182B", "#D6604D",
"#F4A582", "#FDDBC7", "#FFFFFF", "#D1E5F0", "#92C5DE",
"#4393C3", "#2166AC", "#053061"))(200)
}
n <- nrow(corr)
m <- ncol(corr)
min.nm <- min(n, m)
ord <- 1:min.nm
if (!order == "original") {
ord <- corrMatOrder(corr, order = order, hclust.method = hclust.method)
corr <- corr[ord, ord]
}
if (is.null(rownames(corr)))
rownames(corr) <- 1:n
if (is.null(colnames(corr)))
colnames(corr) <- 1:m
getPos.Dat <- function(mat) {
x <- matrix(1:n * m, n, m)
tmp <- mat
if (type == "upper")
tmp[row(x) > col(x)] <- Inf
if (type == "lower")
tmp[row(x) < col(x)] <- Inf
if (type == "full")
tmp <- tmp
if (!diag)
diag(tmp) <- Inf
Dat <- tmp[is.finite(tmp)]
ind <- which(is.finite(tmp), arr.ind = TRUE)
Pos <- ind
Pos[, 1] <- ind[, 2]
Pos[, 2] <- -ind[, 1] + 1 + n
return(list(Pos, Dat))
}
Pos <- getPos.Dat(corr)[[1]]
n2 <- max(Pos[, 2])
n1 <- min(Pos[, 2])
nn <- n2 - n1
newrownames <- as.character(rownames(corr)[(n + 1 - n2):(n +
1 - n1)])
m2 <- max(Pos[, 1])
m1 <- min(Pos[, 1])
mm <- m2 - m1
newcolnames <- as.character(colnames(corr)[m1:m2])
DAT <- getPos.Dat(corr)[[2]]
len.DAT <- length(DAT)
assign.color <- function(DAT) {
newcorr <- (DAT + 1)/2
newcorr[newcorr == 1] <- 1 - 0.0000000001
col.fill <- col[floor(newcorr * length(col)) + 1]
}
col.fill <- assign.color(DAT)
isFALSE = function(x) identical(x, FALSE)
isTRUE = function(x) identical(x, TRUE)
if (isFALSE(tl.pos)) {
tl.pos <- "n"
}
if (is.null(tl.pos) | isTRUE(tl.pos)) {
if (type == "full")
tl.pos <- "lt"
if (type == "lower")
tl.pos <- "ld"
if (type == "upper")
tl.pos <- "td"
}
if (isFALSE(cl.pos)) {
cl.pos <- "n"
}
if (is.null(cl.pos) | isTRUE(cl.pos)) {
if (type == "full")
cl.pos <- "r"
if (type == "lower")
cl.pos <- "b"
if (type == "upper")
cl.pos <- "r"
}
if (outline)
col.border <- "black"
if (!outline)
col.border <- col.fill
if (!add) {
par(mar = mar, bg = "white")
plot.new()
xlabwidth <- ylabwidth <- 0
for (i in 1:50) {
xlim <- c(m1 - 0.5 - xlabwidth, m2 + 0.5 + mm * cl.ratio *
(cl.pos == "r"))
ylim <- c(n1 - 0.5 - nn * cl.ratio * (cl.pos == "b"),
n2 + 0.5 + ylabwidth)
plot.window(xlim + c(-0.2, 0.2), ylim + c(-0.2, 0.2),
asp = 1, xaxs = "i", yaxs = "i")
x.tmp <- max(strwidth(newrownames, cex = tl.cex))
y.tmp <- max(strwidth(newcolnames, cex = tl.cex))
if (min(x.tmp - xlabwidth, y.tmp - ylabwidth) < 0.0001)
break
xlabwidth <- x.tmp
ylabwidth <- y.tmp
}
if (tl.pos == "n" | tl.pos == "d")
xlabwidth <- ylabwidth <- 0
if (tl.pos == "td")
ylabwidth <- 0
if (tl.pos == "ld")
xlabwidth <- 0
laboffset <- strwidth("W", cex = tl.cex) * tl.offset
xlim <- c(m1 - 0.5 - xlabwidth - laboffset, m2 + 0.5 +
mm * cl.ratio * (cl.pos == "r")) + c(-0.35, 0.15)
ylim <- c(n1 - 0.5 - nn * cl.ratio * (cl.pos == "b"),
n2 + 0.5 + ylabwidth * abs(sin(tl.srt * pi/180)) +
laboffset) + c(-0.15, 0.35)
if (.Platform$OS.type == "windows") {
windows.options(width = 7, height = 7 * diff(ylim)/diff(xlim))
}
plot.window(xlim = xlim, ylim = ylim, asp = 1, xlab = "",
ylab = "", xaxs = "i", yaxs = "i")
}
laboffset <- strwidth("W", cex = tl.cex) * tl.offset
symbols(Pos, add = TRUE, inches = FALSE, squares = rep(1,
len.DAT), bg = bg, fg = bg)
if (method == "circle" & plotCI == "n") {
symbols(Pos, add = TRUE, inches = FALSE, bg = col.fill,
circles = 0.9 * abs(DAT)^0.5/2, fg = col.border)
}
if (method == "ellipse" & plotCI == "n") {
ell.dat <- function(rho, length = 99) {
k <- seq(0, 2 * pi, length = length)
x <- cos(k + acos(rho)/2)/2
y <- cos(k - acos(rho)/2)/2
return(cbind(rbind(x, y), c(NA, NA)))
}
ELL.dat <- lapply(DAT, ell.dat)
ELL.dat2 <- 0.85 * matrix(unlist(ELL.dat), ncol = 2,
byrow = TRUE)
ELL.dat2 <- ELL.dat2 + Pos[rep(1:length(DAT), each = 100),
]
polygon(ELL.dat2, border = col.border, col = col.fill)
}
if (method == "number" & plotCI == "n") {
text(Pos[, 1], Pos[, 2], font = 2, col = col.fill, labels = round((DAT -
int) * ifelse(addCoefasPercent, 100, 1)/zoom, ifelse(addCoefasPercent,
0, 2)))
}
if (method == "pie" & plotCI == "n") {
symbols(Pos, add = TRUE, inches = FALSE, circles = rep(0.5,
len.DAT) * 0.85)
pie.dat <- function(theta, length = 100) {
k <- seq(pi/2, pi/2 - theta, length = 0.5 * length *
abs(theta)/pi)
x <- c(0, cos(k)/2, 0)
y <- c(0, sin(k)/2, 0)
return(cbind(rbind(x, y), c(NA, NA)))
}
PIE.dat <- lapply(DAT * 2 * pi, pie.dat)
len.pie <- unlist(lapply(PIE.dat, length))/2
PIE.dat2 <- 0.85 * matrix(unlist(PIE.dat), ncol = 2,
byrow = TRUE)
PIE.dat2 <- PIE.dat2 + Pos[rep(1:length(DAT), len.pie),
]
polygon(PIE.dat2, border = "black", col = col.fill)
}
if (method == "shade" & plotCI == "n") {
addshade <- match.arg(addshade)
symbols(Pos, add = TRUE, inches = FALSE, squares = rep(1,
len.DAT), bg = col.fill, fg = addgrid.col)
shade.dat <- function(w) {
x <- w[1]
y <- w[2]
rho <- w[3]
x1 <- x - 0.5
x2 <- x + 0.5
y1 <- y - 0.5
y2 <- y + 0.5
dat <- NA
if ((addshade == "positive" || addshade == "all") &
rho > 0) {
dat <- cbind(c(x1, x1, x), c(y, y1, y1), c(x,
x2, x2), c(y2, y2, y))
}
if ((addshade == "negative" || addshade == "all") &
rho < 0) {
dat <- cbind(c(x1, x1, x), c(y, y2, y2), c(x,
x2, x2), c(y1, y1, y))
}
return(t(dat))
}
pos_corr <- rbind(cbind(Pos, DAT))
pos_corr2 <- split(pos_corr, 1:nrow(pos_corr))
SHADE.dat <- matrix(na.omit(unlist(lapply(pos_corr2,
shade.dat))), byrow = TRUE, ncol = 4)
segments(SHADE.dat[, 1], SHADE.dat[, 2], SHADE.dat[,
3], SHADE.dat[, 4], col = shade.col, lwd = shade.lwd)
}
if (method == "square" & plotCI == "n") {
symbols(Pos, add = TRUE, inches = FALSE, squares = abs(DAT)^0.5,
bg = col.fill, fg = col.border)
}
if (method == "color" & plotCI == "n") {
symbols(Pos, add = TRUE, inches = FALSE, squares = rep(1,
len.DAT), bg = col.fill, fg = col.border)
}
symbols(Pos, add = TRUE, inches = FALSE, bg = NA, squares = rep(1,
len.DAT), fg = addgrid.col)
if (plotCI != "n") {
if (is.null(lowCI.mat) || is.null(uppCI.mat))
stop("Need lowCI.mat and uppCI.mat!")
if (!order == "original") {
lowCI.mat <- lowCI.mat[ord, ord]
uppCI.mat <- uppCI.mat[ord, ord]
}
pos.lowNew <- getPos.Dat(lowCI.mat)[[1]]
lowNew <- getPos.Dat(lowCI.mat)[[2]]
pos.uppNew <- getPos.Dat(uppCI.mat)[[1]]
uppNew <- getPos.Dat(uppCI.mat)[[2]]
if (!(method == "circle" || method == "square"))
stop("method shoud be circle or square if draw confidence interval!")
k1 <- (abs(uppNew) > abs(lowNew))
bigabs <- uppNew
bigabs[which(!k1)] <- lowNew[!k1]
smallabs <- lowNew
smallabs[which(!k1)] <- uppNew[!k1]
sig <- sign(uppNew * lowNew)
if (plotCI == "circle") {
symbols(pos.uppNew[, 1], pos.uppNew[, 2], add = TRUE,
inches = FALSE, circles = 0.95 * abs(bigabs)^0.5/2,
bg = ifelse(sig > 0, col.fill, col[ceiling((bigabs +
1) * length(col)/2)]), fg = ifelse(sig > 0,
col.fill, col[ceiling((bigabs + 1) * length(col)/2)]))
symbols(pos.lowNew[, 1], pos.lowNew[, 2], add = TRUE,
inches = FALSE, circles = 0.95 * abs(smallabs)^0.5/2,
bg = ifelse(sig > 0, bg, col[ceiling((smallabs +
1) * length(col)/2)]), fg = ifelse(sig > 0,
col.fill, col[ceiling((smallabs + 1) * length(col)/2)]))
}
if (plotCI == "square") {
symbols(pos.uppNew[, 1], pos.uppNew[, 2], add = TRUE,
inches = FALSE, squares = abs(bigabs)^0.5, bg = ifelse(sig >
0, col.fill, col[ceiling((bigabs + 1) * length(col)/2)]),
fg = ifelse(sig > 0, col.fill, col[ceiling((bigabs +
1) * length(col)/2)]))
symbols(pos.lowNew[, 1], pos.lowNew[, 2], add = TRUE,
inches = FALSE, squares = abs(smallabs)^0.5,
bg = ifelse(sig > 0, bg, col[ceiling((smallabs +
1) * length(col)/2)]), fg = ifelse(sig > 0,
col.fill, col[ceiling((smallabs + 1) * length(col)/2)]))
}
if (plotCI == "rect") {
rect.width <- 0.25
rect(pos.uppNew[, 1] - rect.width, pos.uppNew[, 2] +
smallabs/2, pos.uppNew[, 1] + rect.width, pos.uppNew[,
2] + bigabs/2, col = col.fill, border = col.fill)
segments(pos.lowNew[, 1] - rect.width, pos.lowNew[,
2] + DAT/2, pos.lowNew[, 1] + rect.width, pos.lowNew[,
2] + DAT/2, col = "black", lwd = 1)
segments(pos.uppNew[, 1] - rect.width, pos.uppNew[,
2] + uppNew/2, pos.uppNew[, 1] + rect.width,
pos.uppNew[, 2] + uppNew/2, col = "black", lwd = 1)
segments(pos.lowNew[, 1] - rect.width, pos.lowNew[,
2] + lowNew/2, pos.lowNew[, 1] + rect.width,
pos.lowNew[, 2] + lowNew/2, col = "black", lwd = 1)
segments(pos.lowNew[, 1] - 0.5, pos.lowNew[, 2],
pos.lowNew[, 1] + 0.5, pos.lowNew[, 2], col = "grey70",
lty = 3)
}
}
if (!is.null(p.mat) & !insig == "n") {
if (!order == "original")
p.mat <- p.mat[ord, ord]
pos.pNew <- getPos.Dat(p.mat)[[1]]
pNew <- getPos.Dat(p.mat)[[2]]
ind.p <- which(pNew > (sig.level))
if (insig == "pch") {
points(pos.pNew[, 1][ind.p], pos.pNew[, 2][ind.p],
pch = pch, col = pch.col, cex = pch.cex, lwd = 2)
}
if (insig == "p-value") {
text(pos.pNew[, 1][ind.p], pos.pNew[, 2][ind.p],
round(pNew[ind.p], 2), col = pch.col)
}
if (insig == "blank") {
symbols(pos.pNew[, 1][ind.p], pos.pNew[, 2][ind.p],
inches = FALSE, squares = rep(1, length(pos.pNew[,
1][ind.p])), fg = addgrid.col, bg = bg, add = TRUE)
}
}
if (cl.pos != "n") {
colRange <- assign.color(cl.lim2)
ind1 <- which(col == colRange[1])
ind2 <- which(col == colRange[2])
colbar <- col[ind1:ind2]
if (is.null(cl.length))
cl.length <- ifelse(length(colbar) > 20, 11, length(colbar) +
1)
labels <- seq(cl.lim[1], cl.lim[2], length = cl.length)
at <- seq(0, 1, length = length(labels))
if (cl.pos == "r") {
vertical <- TRUE
xlim <- c(m2 + 0.5 + mm * 0.02, m2 + 0.5 + mm * cl.ratio)
ylim <- c(n1 - 0.5, n2 + 0.5)
}
if (cl.pos == "b") {
vertical <- FALSE
xlim <- c(m1 - 0.5, m2 + 0.5)
ylim <- c(n1 - 0.5 - nn * cl.ratio, n1 - 0.5 - nn *
0.02)
}
colorlegend(colbar = colbar, labels = round(labels, 2),
offset = cl.offset, ratio.colbar = 0.3, cex = cl.cex,
xlim = xlim, ylim = ylim, vertical = vertical, align = cl.align.text)
}
if (tl.pos != "n") {
ylabwidth2 <- strwidth(newrownames, cex = tl.cex)
xlabwidth2 <- strwidth(newcolnames, cex = tl.cex)
pos.xlabel <- cbind(m1:m2, n2 + 0.5 + laboffset)
pos.ylabel <- cbind(m1 - 0.5, n2:n1)
if (tl.pos == "td") {
if (type != "upper")
stop("type should be \"upper\" if tl.pos is \"dt\".")
pos.ylabel <- cbind(m1:(m1 + nn) - 0.5, n2:n1)
}
if (tl.pos == "ld") {
if (type != "lower")
stop("type should be \"lower\" if tl.pos is \"ld\".")
pos.xlabel <- cbind(m1:m2, n2:(n2 - mm) + 0.5 + laboffset)
}
if (tl.pos == "d") {
pos.ylabel <- cbind(m1:(m1 + nn) - 0.5, n2:n1)
pos.ylabel <- pos.ylabel[1:min(n, m), ]
symbols(pos.ylabel[, 1] + 0.5, pos.ylabel[, 2], add = TRUE,
bg = bg, fg = addgrid.col, inches = FALSE, squares = rep(1,
length(pos.ylabel[, 1])))
text(pos.ylabel[, 1] + 0.5, pos.ylabel[, 2], newcolnames[1:min(n,
m)], col = tl.col, cex = tl.cex, ...)
}
else {
text(pos.xlabel[, 1], pos.xlabel[, 2], newcolnames,
srt = tl.srt, adj = ifelse(tl.srt == 0, c(0.5,
0), c(0, 0)), col = tl.col, cex = tl.cex, offset = tl.offset,
...)
text(pos.ylabel[, 1], pos.ylabel[, 2], newrownames,
col = tl.col, cex = tl.cex, pos = 2, offset = tl.offset,
...)
}
}
title(title, ...)
if (!is.null(addCoef.col) & (!method == "number")) {
text(Pos[, 1], Pos[, 2], col = addCoef.col, labels = round((DAT -
int) * ifelse(addCoefasPercent, 100, 1)/zoom, ifelse(addCoefasPercent,
0, 2)), cex = number.cex)
}
if (type == "full" & plotCI == "n" & !is.null(addgrid.col))
rect(m1 - 0.5, n1 - 0.5, m2 + 0.5, n2 + 0.5, border = addgrid.col)
if (!is.null(addrect) & order == "hclust" & type == "full") {
corrRect.hclust(corr, k = addrect, method = hclust.method,
col = rect.col, lwd = rect.lwd)
}
invisible(corr)
}
I am currently using heatmap.plus to draw heatmaps with color side bars in each side (row, and column). An example of a code to plot a heatmap for a matrix of dim 18 by 50 bellow:
m.to.plot = matrix(rnorm(n=18*50,mean=3,sd=2), nrow=18, ncol=50)
colc = rainbow(2)[c(rep(x=2,30), rep(x=1,20))]
tmp = runif(n=18, min=0,max = 1)
rowc = rgb(tmp^1.5+(1-tmp^1.5)*0.742,tmp^1.5+(1-tmp^1.5)*0.742,(1-tmp^1.5)*0.742);
heatmap.plus(m.to.plot,
scale="none",
ColSideColors=colc,
RowSideColors=rowc,
Rowv=NA, Colv=NA,
col=c("green2","red2"))
Such code produce a figure like this:
But what I really want is a two column colored side bar, an example of the 'unfinished' code and it's 'in theory' image would look like this:
m.to.plot = matrix(rnorm(n=18*50,mean=3,sd=2), nrow=18, ncol=50)
colc = rainbow(2)[c(rep(x=2,30), rep(x=1,20))]
tmp = runif(n=18, min=0,max = 1)
rowc = rgb(tmp^1.5+(1-tmp^1.5)*0.742,tmp^1.5+(1-tmp^1.5)*0.742,(1-tmp^1.5)*0.742);
tmp2 = runif(n=50, min=0,max = 1)
extra.colc = rgb(tmp^1.5+(1-tmp^1.5)*0.742,tmp^1.5+(1-tmp^1.5)*0.742,(1-tmp^1.5)*0.742);
Then I need to call heatmap.plus (or change/use another heatmap.plus) such that I can visualize two column colored sided bars in the same plot
And it'd be...
voila!
Any ideas on how to modify heatmap.plus and/or the way I call the function?
Note: the heatmap function I am using is heatmap.plus, taken from bioconductor. A copy of it below (in case someone is interested).
heatmap.plus = function (x, Rowv = NULL, Colv = if (symm) "Rowv" else NULL,
distfun = dist, hclustfun = hclust, reorderfun = function(d,w) reorder(d, w),
add.expr, symm = FALSE, revC = identical(Colv, "Rowv"), scale = c("row", "column", "none"), na.rm = TRUE,
margins = c(5, 5), ColSideColors, RowSideColors, cexRow = 0.2 +
1/log10(nr), cexCol = 0.2 + 1/log10(nc), labRow = NULL,
labCol = NULL, cRow=NULL, cCol=NULL, main = NULL, xlab = NULL, ylab = NULL, keep.dendro = FALSE,
verbose = getOption("verbose"), ...)
{
scale <- if (symm && missing(scale))
"none"
else match.arg(scale)
if (length(di <- dim(x)) != 2 || !is.numeric(x))
stop("'x' must be a numeric matrix")
nr <- di[1]
nc <- di[2]
if (nr <= 1 || nc <= 1)
stop("'x' must have at least 2 rows and 2 columns")
if (!is.numeric(margins) || length(margins) != 2)
stop("'margins' must be a numeric vector of length 2")
doRdend <- !identical(Rowv, NA)
doCdend <- !identical(Colv, NA)
if (is.null(Rowv))
Rowv <- rowMeans(x, na.rm = na.rm)
if (is.null(Colv))
Colv <- colMeans(x, na.rm = na.rm)
if (doRdend) {
if (inherits(Rowv, "dendrogram"))
ddr <- Rowv
else {
hcr <- hclustfun(distfun(x))
ddr <- as.dendrogram(hcr)
if (!is.logical(Rowv) || Rowv)
ddr <- reorderfun(ddr, Rowv)
}
if (nr != length(rowInd <- order.dendrogram(ddr)))
stop("row dendrogram ordering gave index of wrong length")
}
else rowInd <- 1:nr
if (doCdend) {
if (inherits(Colv, "dendrogram"))
ddc <- Colv
else if (identical(Colv, "Rowv")) {
if (nr != nc)
stop("Colv = \"Rowv\" but nrow(x) != ncol(x)")
ddc <- ddr
}
else {
hcc <- hclustfun(distfun(if (symm)
x
else t(x)))
ddc <- as.dendrogram(hcc)
if (!is.logical(Colv) || Colv)
ddc <- reorderfun(ddc, Colv)
}
if (nc != length(colInd <- order.dendrogram(ddc)))
stop("column dendrogram ordering gave index of wrong length")
}
else colInd <- 1:nc
x <- x[rowInd, colInd]
labRow <- if (is.null(labRow))
if (is.null(rownames(x)))
(1:nr)[rowInd]
else rownames(x)
else labRow[rowInd]
labCol <- if (is.null(labCol))
if (is.null(colnames(x)))
(1:nc)[colInd]
else colnames(x)
else labCol[colInd]
if (scale == "row") {
x <- sweep(x, 1, rowMeans(x, na.rm = na.rm))
sx <- apply(x, 1, sd, na.rm = na.rm)
x <- sweep(x, 1, sx, "/")
}
else if (scale == "column") {
x <- sweep(x, 2, colMeans(x, na.rm = na.rm))
sx <- apply(x, 2, sd, na.rm = na.rm)
x <- sweep(x, 2, sx, "/")
}
lmat <- rbind(c(NA, 3), 2:1)
lwid <- c(if (doRdend) 1 else 0.05, 4)
lhei <- c((if (doCdend) 1 else 0.05) + if (!is.null(main)) 0.2 else 0,
4)
if (!missing(ColSideColors))
{
lmat <- rbind(lmat[1, ] + 1, c(NA, 1), lmat[2, ] + 1)
lhei <- c(lhei[1], 0.125/par()$fin[2]*10, lhei[2])
}
if (!missing(RowSideColors)) {
lmat <- cbind(lmat[, 1] + 1, c(rep(NA, nrow(lmat) - 1),
1), lmat[, 2] + 1)
lwid <- c(lwid[1], 0.135/par()$fin[1]*10, lwid[2])
}
lmat[is.na(lmat)] <- 0
if (verbose) {
cat("layout: widths = ", lwid, ", heights = ", lhei,
"; lmat=\n")
print(lmat)
}
op <- par(no.readonly = TRUE)
on.exit(par(op))
layout(lmat, widths = lwid, heights = lhei, respect = FALSE)
if (!missing(RowSideColors)) {
par(mar = c(margins[1L], 0, 0, 0.5))
image(rbind(1L:nr), col = RowSideColors[rowInd], axes = FALSE)
}
if (!missing(ColSideColors)) {
par(mar = c(0.5, 0, 0, margins[2L]))
image(cbind(1L:nc), col = ColSideColors[colInd], axes = FALSE)
}
par(mar = c(margins[1], 0, 0, margins[2]))
if (!symm || scale != "none") {
x <- t(x)
}
if (revC) {
iy <- nr:1
ddr <- rev(ddr)
x <- x[, iy]
}
else iy <- 1:nr
image(1:nc, 1:nr, x, xlim = 0.5 + c(0, nc), ylim = 0.5 +
c(0, nr), axes = FALSE, xlab = "", ylab = "", ...)
axis(1, 1:nc, labels = labCol, las = 2, line = -0.5, tick = 0,
cex.axis = cexCol)
if (!is.null(xlab))
mtext(xlab, side = 1, line = margins[1] - 1.25)
axis(4, iy, labels = labRow, las = 2, line = -0.5, tick = 0,
cex.axis = cexRow)
if (!is.null(ylab))
mtext(ylab, side = 4, line = margins[2] - 1.25)
if (!missing(add.expr))
eval(substitute(add.expr))
par(mar = c(margins[1], 0, 0, 0))
if (doRdend)
plot(ddr, horiz = TRUE, axes = FALSE, yaxs = "i", leaflab = "none")
else frame()
par(mar = c(0, 0, if (!is.null(main)) 1 else 0, margins[2]))
if (doCdend)
plot(ddc, axes = FALSE, xaxs = "i", leaflab = "none")
else if (!is.null(main))
frame()
if (!is.null(main))
title(main, cex.main = 1.5 * op[["cex.main"]])
invisible(list(rowInd = rowInd, colInd = colInd, Rowv = if (keep.dendro &&
doRdend) ddr, Colv = if (keep.dendro && doCdend) ddc))
}
You can use a matrix for ColSideColor instead of a vector.
For example:
you have two vectors :
A B
Red Blue
green black
Red yellow
purple Blue
create a matrix:
colormatrix <- cbind(A,B)
and use it as for ColSideColor then you will have two ColSideColors in your sample code: instead
of colc use colormatrix.
heatmap.plus(m.to.plot,
scale="none",
ColSideColors=colormatrix,
RowSideColors=rowc,
Rowv=NA, Colv=NA,
col=c("green2","red2"))