Last active
February 25, 2019 18:38
-
-
Save menugget/7864471 to your computer and use it in GitHub Desktop.
Stacked plot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#plot.stacked makes a stacked plot where each y series is plotted on top | |
#of the each other using filled polygons | |
# | |
#Arguments include: | |
#'x' - a vector of values | |
#'y' - a matrix of data series (columns) corresponding to x | |
#'order.method' = c("as.is", "max", "first") | |
# "as.is" - plot in order of y column | |
# "max" - plot in order of when each y series reaches maximum value | |
# "first" - plot in order of when each y series first value > 0 | |
#'col' - fill colors for polygons corresponding to y columns (will recycle) | |
#'border' - border colors for polygons corresponding to y columns (will recycle) (see ?polygon for details) | |
#'lwd' - border line width for polygons corresponding to y columns (will recycle) | |
#'...' - other plot arguments | |
plot.stacked <- function( | |
x, y, | |
order.method = "as.is", | |
ylab="", xlab="", | |
border = NULL, lwd=1, | |
col=rainbow(length(y[1,])), | |
ylim=NULL, | |
... | |
){ | |
if(sum(y < 0) > 0) error("y cannot contain negative numbers") | |
if(is.null(border)) border <- par("fg") | |
border <- as.vector(matrix(border, nrow=ncol(y), ncol=1)) | |
col <- as.vector(matrix(col, nrow=ncol(y), ncol=1)) | |
lwd <- as.vector(matrix(lwd, nrow=ncol(y), ncol=1)) | |
if(order.method == "max") { | |
ord <- order(apply(y, 2, which.max)) | |
y <- y[, ord] | |
col <- col[ord] | |
border <- border[ord] | |
} | |
if(order.method == "first") { | |
ord <- order(apply(y, 2, function(x) min(which(x>0)))) | |
y <- y[, ord] | |
col <- col[ord] | |
border <- border[ord] | |
} | |
top.old <- x*0 | |
polys <- vector(mode="list", ncol(y)) | |
for(i in seq(polys)){ | |
top.new <- top.old + y[,i] | |
polys[[i]] <- list(x=c(x, rev(x)), y=c(top.old, rev(top.new))) | |
top.old <- top.new | |
} | |
if(is.null(ylim)) ylim <- range(sapply(polys, function(x) range(x$y, na.rm=TRUE)), na.rm=TRUE) | |
plot(x,y[,1], ylab=ylab, xlab=xlab, ylim=ylim, t="n", ...) | |
for(i in seq(polys)){ | |
polygon(polys[[i]], border=border[i], col=col[i], lwd=lwd[i]) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Replaced top.old <- x*0 by top.old <- rep(0,length(x)) to enable time series (Posix) compatibility.
Also I'm not sure why you don't allow negative numbers here : if(sum(y < 0) > 0) error("y cannot contain negative numbers"). I personnaly use negative Y's and it works.
Thank you for this simple and efficient function !