Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
911 views
in Technique[技术] by (71.8m points)

ggplot2 - Reorder stacks in horizontal stacked barplot (R)

I'm trying to make a horizontal stacked barplot using ggplot. Below are the actual values for three out of 300 sites in my data frame. Here's where I've gotten to so far, using info pulled from these previous questions which I admit I may not have fully understood.

df <- data.frame(id=c("AR001","AR001","AR001","AR001","AR002","AR002","AR002","AR003","AR003","AR003","AR003","AR003"), 
             landuse=c("agriculture","developed","forest","water","agriculture","developed","forest","agriculture","developed","forest","water","wetlands"), 
             percent=c(38.77,1.76,59.43,0.03,69.95,0.42,29.63,65.4,3.73,15.92,1.35,13.61))
df

      id     landuse percent 
1  AR001 agriculture   38.77 
2  AR001   developed    1.76 
3  AR001      forest   59.43 
4  AR001       water    0.03 
5  AR002 agriculture   69.95 
6  AR002   developed    0.42 
7  AR002      forest   29.63 
8  AR003 agriculture   65.40 
9  AR003   developed    3.73 
10 AR003      forest   15.92 
11 AR003       water    1.35 
12 AR003    wetlands   13.61 

str(df)

'data.frame':   12 obs. of  3 variables:
 $ id     : Factor w/ 3 levels "AR001","AR002",..: 1 1 1 1 2 2 2 3 3 3 ...
 $ landuse: Factor w/ 5 levels "agriculture",..: 1 2 3 4 1 2 3 1 2 3 ...
 $ percent: num  38.77 1.76 59.43 0.03 69.95 ...

df <- transform(df, 
                landuse.ord  = factor(
                  landuse,
                  levels=c("agriculture","forest","wetlands","water","developed"),
                  ordered =TRUE))

cols <- c(agriculture="maroon",forest="forestgreen", 
      wetlands="gold", water="dodgerblue", developed="darkorchid") 

ggplot(df,aes(x = id, y = percent, fill = landuse.ord, order=landuse.ord)) + 
    geom_bar(position = "stack",stat = "identity", width=1) + 
    coord_flip() +
    scale_fill_manual(values = cols) 

which produces this graph.

initial ggplot result

  1. What I would like to do is to reorder the bars so that they are in descending order by value for the agriculture category - in this example AR002 would be at the top, followed by AR003 then AR001. I tried changing the contents of aes to aes(x = reorder(landuse.ord, percent), but that eliminated the stacking and seemed to have maybe summed the percentages for each land use category:

second ggplot result

  1. I would like to have the stacks in order, from left to right: agriculture, forest, wetlands, water, developed. I tried doing that with the transform part of the code, which put it in the correct order in the legend, but not in the plot itself?

Thanks in advance... I have made a ton of progress based on answers to other peoples' questions, but seem to now be stuck at this point!

Update: here is the finished graph for all 326 sites! finished graph

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Ok based on your comments, I believe this is your solution. Place these lines after cols<-...:

  #create df to sort by argiculture's percentage
ag<-filter(df, landuse=="agriculture")
  #use the df to sort and order df$id's levels
df$id<-factor(df$id, levels=ag$id[order(ag$percent)], ordered = TRUE)
  #sort df, based on ordered ids and ordered landuse
df<-df[order(df$id, df$landuse.ord),]

ggplot(df,aes(x = id, y = percent, fill = landuse.ord, order=landuse.ord)) + 
    geom_bar(position = "stack",stat = "identity", width=1) + 
    coord_flip() +
    scale_fill_manual(values = cols) 

The comments should clarify each of the lines purposes. This will reorder your original data frame, if that is a problem I would create a copy and then operate on the new copy.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...