1

I thought stacking columns was the default action under ggplot2 but that does not seem to be happening for my plot. I am trying to take two vectors (may or may not have the same length) and graph them in the same plot as stacked bars. Here is a simple example:

z1<-c(500, 300, 200, 100)
z2<-c(800, 100, 50)

names(z1)<-c("a", "b", "c", "d")
names(z2)<-c("a", "c", "e")

z1<-as.data.frame(z1)
z2<-as.data.frame(z2)

colnames(z1)<-"total"
colnames(z2)<-"total"

ggplot()+ 
    labs(x="", y="") + 
    theme_bw() + theme(panel.border = element_blank(), panel.grid.major = element_blank(), 
    panel.grid.minor = element_blank(), axis.line = element_line(colour = "black")) +
    scale_y_continuous(labels=format_si()) +
    ggtitle("Test") +
    geom_bar(data=z1, aes(x=rownames(z1), y=total),position="identity",stat="identity",
    fill=rgb(red=200, green=0, blue=50, maxColorValue = 255)) +
    geom_bar(data=z2, aes(x=rownames(z2), y=total),position="identity",stat="identity",
    fill=rgb(red=0, green=200, blue=50, maxColorValue = 255))

Gives me:

enter image description here

As you can see, the a and c elements are in front of each other instead of stacked.

4
  • Bars from a single geom_bar call will be stacked. Different geom_bar calls don't stack with each other. If you tidy your data, everything will work as you expect. Commented Jan 6, 2017 at 21:31
  • how do I tidy my data? Commented Jan 6, 2017 at 21:35
  • Combine to one data frame. One column per dimension (in this case one column for x-axis position, one column for y-axis position, one column for fill color). A full-length explanation is here. You should use tidyr::gather or reshape2::melt to get your data in long format (lots of examples on Stack Overflow if you search for "wide to long data"), add a column indicating color, and then rbind the two data frames together. Commented Jan 6, 2017 at 21:40
  • Merge and melt and there you go: df <- merge(z1, z2, by = "row.names", all=T);df <- reshape(df, dir = "long", varying = 2:3);ggplot(df, aes(x=Row.names, y=total, fill=time)) + geom_bar(stat="identity". Commented Jan 6, 2017 at 22:07

2 Answers 2

1

Just try this:

df <- rbind(cbind(z1, type=rownames(z1), data='z1'), cbind(z2, type=rownames(z2), data='z2'))
ggplot(df, aes(type, total, fill=data)) + 
  geom_bar(stat="identity") +
  scale_fill_manual(values=c(rgb(red=200, green=0, blue=50, maxColorValue = 255), rgb(red=0, green=200, blue=50, maxColorValue = 255)))

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

1

This type of data organization would work better:

z1<-c(500, 300, 200, 100)
z2<-c(800, 100, 50)

names(z1)<-c("a", "b", "c", "d")
names(z2)<-c("a", "c", "e")

z1<-as.data.frame(z1)
z2<-as.data.frame(z2)

colnames(z1)<-"total"
colnames(z2)<-"total"

Add group (z1, z2) to the data

z1$Group <- "z1"
z2$Group <- "z2"

Add the rownames as a variable column

z1$rnm <- rownames(z1)
z2$rnm <- rownames(z2)

Bind these together

zt <- rbind(z1, z2)

A much simplified plot

ggplot(zt, aes(x=rnm, y=total, fill=Group)) +
  geom_bar(stat="identity") 

At its core here, you need to understand aesthetics and what type of data is most efficient with ggplot2. Having separate calls for each group/data ignores the power of a factor variable with several levels. For example, experiment with swapping Group for rnm in the example.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.