r - How do you create a stacked barplot with X labels and borders grouped by a factor? -
i create stacked barplot structure plot (using program distruct). how can group x labels common factor , display factor once? example, below there 6 individuals 2 populations, , want there 2 labels centered on population groups. also, there way place box around each group?
here have:
df <- data.frame(a1=c(0.000, 0.000, 0.020, 0.000, 0.000, 0.000), a2=c(0.000, 0.000, 0.235, 0.195, 0.166, 0.205), a3=c(0.065, 0.027, 0.000, 0.027, 0.000, 0.036), a4=c(0.000, 0.000, 0.007, 0.011, 0.000, 0.000), a5=c(0.000, 0.000, 0.000, 0.002, 0.028, 0.000), a6=c(0.000, 0.041, 0.021, 0.068, 0.106, 0.105), a7=c(0.093, 0.085, 0.001, 0.056, 0.110, 0.000), a8=c(0.000, 0.000, 0.000, 0.000, 0.000, 0.029), a9=c(0.000, 0.000, 0.058, 0.027, 0.096, 0.156), a10=c(0.000, 0.023, 0.129, 0.012, 0.074, 0.117), a11=c(0.000, 0.041, 0.000, 0.000, 0.000, 0.000), a12=c(0.024, 0.000, 0.000, 0.000, 0.000, 0.000), a13=c(0.817, 0.783, 0.527, 0.446, 0.258, 0.321), a14=c(0.000, 0.000, 0.000, 0.006, 0.000, 0.000), a15=c(0.000, 0.000, 0.000, 0.054, 0.143, 0.027), a16=c(0.000, 0.000, 0.000, 0.000, 0.000, 0.003), a17=c(0.000, 0.000, 0.000, 0.097, 0.019, 0.000)) barplot(t(df), col=rainbow(17), border=na,space=0.05, names.arg=c("1","1","2","2","2","2"), xlab="population", ylab="ancestry")
and here's want:
if possible, nice set space=
parameter , still independently choose width black borders between groups.
here's program referenced: http://pritchardlab.stanford.edu/structure.html
maybe ggplot better equipped this? sorry if answer obvious, can't figure out.
note realize can manually fill in ""
specific names.arg
values, laborious huge dataset, doesn't center labels well, , won't solve border issue.
here solution using ggplot2. have added columns subject , population ids, , have melted data. have used faceting group populations. unfortunately, ggplot2 cannot place facet labels @ bottom of plot. can recommend editing pdf file inkscape or adobe illustrator.
library(ggplot2) library(reshape2) # add id , population label columns. needed melting , plotting. df$population = c("p1", "p1", "p2", "p2", "p2", "p2") df$subject_id = paste("id", 1:6, sep="") # melt (reshape data wide format long format). mdat = melt(df, id.vars=c("subject_id", "population"), variable.name="ancestry", value.name="fraction") # simple stacked bar plot: p = ggplot(mdat, aes(x=subject_id, y=fraction, fill=ancestry)) + geom_bar(stat="identity", position="stack") + facet_grid(. ~ population, drop=true, space="free", scales="free") # customized stacked bar plot: # sort ancestry order overall 'abundance' of each ancestry. mdat$ancestry = factor(mdat$ancestry, levels=names(sort(colsums(df[, 1:17]), decreasing=true))) # colors taken from: # https://github.com/mbostock/d3/wiki/ordinal-scales#category20 col17 = c("#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd", "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf", "#aec7e8", "#ffbb78", "#98df8a", "#ff9896", "#c5b0d5", "#c49c94", "#c7c7c7") names(col17) = levels(mdat$ancestry) p2 = ggplot(mdat, aes(x=subject_id, y=fraction, fill=ancestry, order=ancestry)) + geom_bar(stat="identity", position="fill", width=1, colour="grey25") + facet_grid(. ~ population, drop=true, space="free", scales="free") + theme(panel.grid=element_blank()) + theme(panel.background=element_rect(fill=na, colour="grey25")) + theme(panel.margin.x=grid:::unit(0.5, "lines")) + theme(axis.title.x=element_blank()) + theme(axis.text.x=element_blank()) + theme(axis.ticks.x=element_blank()) + theme(strip.background=element_blank()) + theme(strip.text=element_text(size=12)) + theme(legend.key=element_rect(colour="grey25")) + scale_x_discrete(expand=c(0, 0)) + scale_y_continuous(expand=c(0, 0)) + scale_fill_manual(values=col17) + guides(fill=guide_legend(override.aes=list(colour=null))) library(gridextra) png("bar_plots.png", width=10, height=5, units="in", res=100) grid.arrange(p, p2, nrow=1) dev.off()
Comments
Post a Comment