[R] stacked area chart

Dimitri Liakhovitski dimitri.liakhovitski at gmail.com
Mon Sep 27 20:05:46 CEST 2010


I found a solution to my original question (see code below).
But I have a question about cosmetics, which I always find very challenging.
1. How can I make all dates appear on the X axis (rotated at 90
degrees vs. horizontal)?
2. How can I create vertical grid lines so that at each date there is
a gridline?
3. How can I create a legend for colors, but not on top of the graph
but on the right side, outside of the graph (because in my real data
set I have a lot of variables - so that there'll never be enough space
for the legend in the graph itself)

Thanks a lot!
Dimitri


### Creating a data set with both positives and negatives
my.data<-data.frame(date=c(20080301,20080402,20080503,20090301,20090402,20090503,20100301,20100402,20100503),
x=c(1.1,1.0,1.6,1,2,1.5,2.1,1.3,1.9),y=c(-4,-3,-6,-5,-7,-5.2,-6,-4,-4.9),
z=c(-0.2,-0.3,-0.4,-0.1,-0.2,-0.05,-0.2,-0.15,-0.06),a=c(10,13,15,15,16,17,15,16,14))
my.data$date<-as.character(my.data$date)
my.data$date<-as.Date(my.data$date,"%Y%m%d")
(my.data)

positives<-which(colSums(my.data[2:ncol(my.data)])>0) # which vars
have positive column sums?
negatives<-which(colSums(my.data[2:ncol(my.data)])<0) # which vars
have negative column sums?

y.max<-1.1*max(rowSums(my.data[names(positives)])) # the max on the y
axis of the chart
y.min<-1.1*min(rowSums(my.data[names(negatives)])) # the min on the y
axis of the chart
ylim <- c(y.min, y.max)
order.positives<-rev(rank(positives))
order.of.pos.vars<-names(order.positives)
order.negatives<-rev(rank(negatives))
order.of.neg.vars<-names(order.negatives)
order<-c(order.negatives,order.positives)
order.of.vars<-names(order)   # the order of variables on the chart -
from the bottom up
### so, the bottom-most area should be for z, the second from the
bottom area- for y (above z)

all.colors<-c('red','blue','green','orange','yellow','purple')
xx <- c(my.data$date, rev(my.data$date))
bottom.y.coordinates<-rowSums(my.data[names(negatives)])

plot(x=my.data$date, y=bottom.y.coordinates, ylim=ylim, col='white',
type='l', xaxt='n',
    ylab='Title for Y', xlab='Date', main='Chart Title')

for(var in order.of.neg.vars){
	top.line.coords<-bottom.y.coordinates-my.data[[var]]
	bottom.coords<-c(bottom.y.coordinates,rev(top.line.coords))
	polygon(xx,bottom.coords,col=all.colors[which(names(my.data) %in% var)])
	bottom.y.coordinates<-top.line.coords
}

for(var in order.of.pos.vars){
	top.line.coords<-bottom.y.coordinates+my.data[[var]]
	bottom.coords<-c(bottom.y.coordinates,rev(top.line.coords))
	polygon(xx,bottom.coords,col=all.colors[which(names(my.data) %in% var)])
	bottom.y.coordinates<-top.line.coords
}



On Mon, Sep 27, 2010 at 11:47 AM, Dimitri Liakhovitski
<dimitri.liakhovitski at gmail.com> wrote:
> Dear R-ers!
>
> Asking for your help with building the stacked area chart for the
> following simple data (several variables - with date on the X axis):
>
> ### Creating a data set
> my.data<-data.frame(date=c(20080301,20080402,20080503,20090301,20090402,20090503,20100301,20100402,20100503),
> x=c(1.1,1.0,1.6,1,2,1.5,2.1,1.3,1.9),y=c(-4,-3,-6,-5,-7,-5.2,-6,-4,-4.9),
> z=c(-0.2,-0.3,-0.4,-0.1,-0.2,-0.05,-0.2,-0.15,-0.06),a=c(4,3,5,5,6,7,5,6,4))
> my.data$date<-as.character(my.data$date)
> my.data$date<-as.Date(my.data$date,"%Y%m%d")
> (my.data)
>
> I'd like the variables whose column values sum up to a negative number
> to be below zero on that chart and those that add up to a positive
> number to be above zero in the chart. I am calculating values for ylim
> and for the order of the variable entry (bottom up) like this:
>
> positives<-which(colSums(my.data[2:ncol(my.data)])>0) # which vars
> have positive column sums?
> negatives<-which(colSums(my.data[2:ncol(my.data)])<0) # which vars
> have negative column sums?
>
> y.max<-1.1*max(rowSums(my.data[names(positives)])) # the max on the y
> axis of the chart
> y.min<-1.1*min(rowSums(my.data[names(negatives)])) # the min on the y
> axis of the chart
> ylim <- c(y.min, y.max)  # ylim for the stacked area chart
>
> order.positives<-rev(rank(positives))
> order.negatives<-rev(rank(negatives))
> order<-c(order.negatives,order.positives)
> order.of.vars<-names(order)   # the order of variables on the chart - bottom up
> ### so, the bottom-most area should be for z, and the second from the
> bottom area- for y (above z) - they'll be below zero
> ### and above zero we'll have a first and x second (on top of a).
>
> Thanks a lot for your advice!
>
> --
> Dimitri Liakhovitski
> Ninah Consulting
> www.ninah.com
>



-- 
Dimitri Liakhovitski
Ninah Consulting
www.ninah.com



More information about the R-help mailing list