How to control ordering of stacked bar chart using identity on ggplot2
I've struggled with the same issue before. It appears that ggplot stacks the bars based on their appearance in the dataframe. So the solution to your problem is to sort your data by the fill factor in the reverse order you want it to appear in the legend: bottom item on top of the dataframe, and top item on bottom:
ggplot(ts[order(ts$y, decreasing = T),],
aes(z, x, fill=factor(y, levels=c("blue","white" )))) +
geom_bar(stat = "identity")
Edit: More illustration
Using sample data, I created three plots with different orderings of the dataframe, I thought that more fill-variables would make things a bit clearer.
set.seed(123)
library(gridExtra)
df <- data.frame(x=rep(c(1,2),each=5),
fill_var=rep(LETTERS[1:5], 2),
y=1)
#original order
p1 <- ggplot(df, aes(x=x,y=y,fill=fill_var))+
geom_bar(stat="identity") + labs(title="Original dataframe")
#random order
p2 <- ggplot(df[sample(1:10),],aes(x=x,y=y,fill=fill_var))+
geom_bar(stat="identity") + labs(title="Random order")
#legend checks out, sequence wird
#reverse order
p3 <- ggplot(df[order(df$fill_var,decreasing=T),],
aes(x=x,y=y,fill=fill_var))+
geom_bar(stat="identity") + labs(title="Reverse sort by fill")
plots <- list(p1,p2,p3)
do.call(grid.arrange,plots)
Change the order of stacked fill columns in ggplot2
The structure of the input data is character:
str(mpg$drv)
> chr [1:234] "f" "f" "f" "f" "f" "f" "f" "4" "4" "4" "4" "4" "4" "4" "4" "4" "4" "4" "r" "r" "r" "r" "r" "r" "r" "r" "r" "r" "4" "4" "4" "4" "f" "f" "f" "f" "f" "f" "f" "f" "f" "f" "f" ...
ggplot will automatically convert character strings to a factor. You can see the default ordering as follows, and this conversion ranks them alphabetically:
levels(as.factor(mpg$drv))
> "4" "f" "r"
To reorder the barplot without changing the original data, you can just refactor the variable within plot itself:
ggplot(mpg, aes(fl, fill = factor(drv, levels=c("4", "r", "f")))) +
geom_bar(position="stack") +
labs(fill = "Drive")
Comparing the results:
Change order in y-direction of stacked bar chart in ggplot2 as indicated by sequence
geom_col
and geom_bar
are not the appropriate ggplot2
functions when you want the fill or color to vary along with the sequence as the fill and or color are grouped in one bar. geom_rect
is able to seperate two layer of fill or color within a bar/rectangle.
p1 <- ggplot(tib1)+
geom_rect(data = tib1,
aes(x = NULL, NULL,
xmin = drill-0.45, xmax = drill+0.45,
fill = soiltype,
ymin = -bottom_of_layer, ymax = -top_of_layer))+
scale_fill_manual(values = colpalette)+
facet_wrap(vars(location))+
xlab("drill")+
ylab("depth (cm)")+
ggtitle("how to plot the bars in the 'preferred order'? ",
subtitle = "the order of loc2 and drill == 4 should be: loam-sand-gravel-clay")+
theme_minimal()
# Optional:
# Adding in text the column called "order"
p1 + geom_text(aes(x = drill,
y = (bottom_of_layer + top_of_layer)/-2,
label = order))
This is also possible with discrete x-axis values:
how do I use geom_rect with discrete axis values
Stacked barchart, independent fill order for each stack
If you use separate geom_bar
s, you can make the orders different.
dats %>%
ggplot(aes(x = id, y = value, fill = reorder(filling,-ordering))) +
geom_bar(stat = "identity", position = "stack", data = dats %>% filter(id == 1)) +
geom_bar(stat = "identity", position = "stack", data = dats %>% filter(id == 2)) +
geom_bar(stat = "identity", position = "stack", data = dats %>% filter(id == 3)) +
guides(fill=guide_legend("ordering"))
More generally:
bars <- map(unique(dats$id)
, ~geom_bar(stat = "identity", position = "stack"
, data = dats %>% filter(id == .x)))
dats %>%
ggplot(aes(x = id, y = value, fill = reorder(filling,-ordering))) +
bars +
guides(fill=guide_legend("ordering"))
Reorder Bars of a Stacked Barchart in R
One option would be to reorder
your Identity
column by a helper Value
"column" where you set the values for non-High
categories to zero and use FUN=sum
:
data1$Identity <- reorder(data1$Identity, ifelse(!data1$FavorableLevel %in% "High", 0, data1$Value), FUN = sum)
library(ggplot2)
ggplot(
data1,
aes(
fill = factor(FavorableLevel, levels = c("Low", "Medium", "High")),
y = Value,
x = Identity,
)
) +
geom_bar(position = "fill", stat = "identity")
Related Topics
Count Unique Combinations of Values
How to Run a R Language(.R) File Using Batch File
Vary the Color Gradient on a Scatter Plot Created with Ggplot2
R Ggplot Ordering Bars in "Barplot-Like " Plot
Connect R and Vertica Using Rodbc
Why Does As.Matrix Add Extra Spaces When Converting Numeric to Character
Large Integers in Data.Table. Grouping Results Different in 1.9.2 Compared to 1.8.10
Remove Unused Categorical Values Boxplot - R
R - Replace Specific Value Contents with Na
Control Speed of a Gganimation
Importing Data into R (Rdata) from Github
How to Remove Columns from a Data.Frame by Data Type
Remove Duplicates Column Combinations from a Dataframe in R
Rstudio Calls Source() When Saving Script
Why Does Subsetting a Column from a Data Frame VS. a Tibble Give Different Results