Klaus
Klaus

Reputation: 2056

Split bar chart

How can I change the following bar chart so that:

1) no spaces between the bars. 2) the colors of the stacked bars should look, if the higher one is filled by the smaller one.

tim.seq<-seq(as.POSIXlt("2013-07-01 00:00:00",origin = "1960-01-01",tz="GMT"),
            as.POSIXlt("2013-07-8 00:00:00",origin = "1960-01-01",tz="GMT"),by="1 day")

library(ggplot2)
times<-rep(tim.seq,2)
key<-rep(LETTERS[1:2],each=length(times)/2)
times<-c(times,times)
key<-c(key,key)
ref<-rep(LETTERS[1:2],each=length(times)/2)
value<-to<-sample(1:20,length(times),T)  
df<-data.frame(times=times,key=key,ref=ref,value=value)

p<-ggplot(df, aes(x=times)) 
p<-p + geom_bar(subset = .(ref =="A"), aes(y = value, fill = key), stat = "identity")
p<-p + geom_bar(subset = .(ref =="B"), aes(y = -value, fill = key), stat = "identity")
p<-p + geom_hline(yintercept = 0, colour = "grey90")
p

Upvotes: 1

Views: 887

Answers (1)

Ram Narasimhan
Ram Narasimhan

Reputation: 22506

It looks like you don't want stacked bars, and you want bars of different widths instead. To get that you have to experiment with different width parameters and position="identity"

For each time instant, you have 4 different possible combinations: key = {A or B} and Ref = {A or B} Just to illustrate how this might look, here's a throw-away graph that you can experiment with:

#create a new column to have Bar width be based on the Key
df$w <- ifelse(key=="A", 5, 3)

p <- ggplot(df, aes(x=times, y=value)) 
p <- p + geom_bar(data = subset(df, ref =="A"), aes(width=w*10000, fill=key), stat = "identity", position = "identity")  
p <- p + geom_bar(data = subset(df, ref =="B"), aes(width=w*5000, fill=key), colour="black", stat = "identity", position="identity")

This produces: enter image description here But this is surely not what you want. It is just to illustrate that you can play around with position="identity", position="dodge" and various width values.

Creating a summary data frame

In ggplot, you can almost always get what you want by dealing with the data frame itself. Here's another attempt with summarized data that holds the y-totals and also adds up the values when ref is "A"

library(plyr)

#Create a summary data frame with y-value Totals
new.df <- ddply(df, .(times), summarize,  total=sum(value))

#add a column to sum up values when Ref is "A"
ref.df <- ddply(df, .(times, ref), summarize, reftotal = sum(value))
new.df$reftotal <- ref.df$reftotal[ref.df$ref=="A"] #filter to the Ref value we are interested in

p2 <- ggplot(new.df, aes(x=times)) 
p2 <- p2 + geom_bar(aes(y=total, width=50000), stat = "identity", position = "identity", fill="darkgreen")  
p2 <- p2 + geom_bar(aes(y=reftotal, width=30000), stat = "identity", position = "identity", fill="red")  
p2 <- p2 + geom_hline(yintercept = 0, colour = "blue")
p2

which produces: enter image description here

Hope this gets you closer to what you have in mind.

Upvotes: 1

Related Questions