2-layer barplot in R

£可爱£侵袭症+ 提交于 2019-12-11 11:13:58

问题


I am trying to build a (somewhat) complex barplot in R. The idea is to overlay two charts, whereby the bars in one are wider than in the other one, such that both bars are always visible.

Here's what I have right now:

# GENERATE THE DATA  
Age = c(50, 55, 60, 65, 70)                                     # Age groups  
Male = c(15.4, 24.3, 37.0, 54.6, 71.1)                          # Death rates for males  
Female = c(8.4, 13.6, 19.3, 35.1, 50.0)                         # Death rates for females  
Deathrate = matrix(c(Male,Female), nrow=length(Age), ncol=2, dimnames=list(Age, c("Male","Female")))         

# GENERATE THE DATA  
barplot(Deathrate[,1], col="red")
par(new=TRUE)
barplot(Deathrate[,2], space=1, col="blue")

Now, as you can see, the two plots are shown, but while both middle bars are nicely overlapping and centered, all other bars are not centered. For example, the rightmost blue bar is shown on the edge of the rightmost red bar.

Does anyone have a simple solution to center all bars?

Thanks, Philipp

PS I know that the chart isn't pretty (overlapping legends etc.)....


回答1:


You can use add=TRUE together with apropriate values for width and space.

barplot(Deathrate[,1], col="red")
barplot(Deathrate[,2], width=0.5, space=c(0.9, 1.4, 1.4, 1.4, 1.4), col="blue", add=TRUE)



回答2:


Here is a solution using ggplot2

Death.df <- as.data.frame(Deathrate) # ggplot2 requires a data frame
Death.df$ages <- rownames(Death.df) # add a column with rownames
Death.m <- melt(Death.df, id.vars = "ages") # melt the dataframe to long form

ggplot(Death.m) +
  geom_histogram(aes(x = ages, y = value), stat = "identity", fill = "red", width = 0.4) +
  geom_histogram(aes(x = ages, y = value), stat = "identity", fill = "blue", width = 0.5, position = "dodge") +
  ggtitle("Death Rates of Males and Females\nMales in Red and Females in Blue")




回答3:


 barplot(as.vector(rbind(Male, Female)),col=c('red','blue'), space=rep_len(1:0,length(Male)*2), beside=T, legend.text=c('Male', 'Female'));

P.S. the bars are not centered, but I think they are prettier this way.




回答4:


barplot certainly wasn't optimized for this case. It's not too hard to roll your own plotting function for this type of plot if you want even more control.

cbarplot <- function(x, ..., bcols=c("red","blue"), bwidth=c(.4,.3)) {
    plot(1, type="n", xlim=c(.5,(nrow(x)+.5)), ylim=c(0,max(x)), xaxt="n", ...)
    for(i in 1:ncol(x)) {
        w <- bwidth[i]
        rect(seq_len(nrow(x))-w, 0, seq_len(nrow(x))+w, x[,i], col=bcols[i])
    }
    axis(1, at=1:nrow(x), rownames(x))
}

cbarplot(Deathrate, ylab="Count", xlab="Age")



来源:https://stackoverflow.com/questions/28724396/2-layer-barplot-in-r

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!