Reputation: 125
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.
aes(x = reorder(landuse.ord, percent)
, but that eliminated the stacking and seemed to have maybe summed the percentages for each land use category: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!
Upvotes: 2
Views: 725
Reputation: 24079
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.
Upvotes: 3