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)
ggplot2: How to reorder stacked bar charts by proportions of fill variable
Hopefully this makes up for lack of concision with clarity:
df %>%
left_join( # Add res_share for each neighborhood
df %>%
group_by(neighborhood) %>%
mutate(share = count / sum(count)) %>%
ungroup() %>%
filter(type == "residential_unit") %>%
select(neighborhood, res_share = share)
) %>%
mutate(neighborhood = fct_reorder(neighborhood, res_share)) %>%
ggplot(aes(neighborhood, count, fill = type)) +
geom_col(position = "fill") +
scale_y_continuous(labels = scales::percent) +
coord_flip() +
theme_light()
How can I change the order of the stacked bar plot in R?
Just convert d1$Gendered
into a factor and specify the levels in the order you want them.
d1$Gender <- factor(d1$Gender, levels = c("M", "F"))
Then, run the code to create your plot.
Ordering the 'fill' of a stacked bar chart ggplot2
Try one of this options. You can use reorder()
with fill
:
library(ggplot2)
library(dplyr)
#Code 1
Comete_Line %>% ggplot(aes(x = Line,
y = The_Number_Of_Evaders,
fill = reorder(The_Results_Of_Using_The_Line,-The_Number_Of_Evaders))) +
geom_bar(stat = "identity", width = 0.5)+
labs(fill='Var')
Output:
Or this:
#Code 2
Comete_Line %>% ggplot(aes(x = Line,
y = The_Number_Of_Evaders,
fill = reorder(The_Results_Of_Using_The_Line,The_Number_Of_Evaders))) +
geom_bar(stat = "identity", width = 0.5)+
labs(fill='Var')
Output:
Set the order of a stacked bar chart by the value of one of the variables
You already have plotOrder
, but you need to apply it to reorder x
rather than fill
...
stackedBarPlot <-
ggplot(data) +
aes(x = reorder(ValueName,-plotOrder),
y = Percent,
fill = Response) +
geom_bar(position = "fill", stat = "identity") +
coord_flip()
Order Bars in ggplot2 bar graph
The key with ordering is to set the levels of the factor in the order you want. An ordered factor is not required; the extra information in an ordered factor isn't necessary and if these data are being used in any statistical model, the wrong parametrisation might result — polynomial contrasts aren't right for nominal data such as this.
## set the levels in order we want
theTable <- within(theTable,
Position <- factor(Position,
levels=names(sort(table(Position),
decreasing=TRUE))))
## plot
ggplot(theTable,aes(x=Position))+geom_bar(binwidth=1)
In the most general sense, we simply need to set the factor levels to be in the desired order. If left unspecified, the levels of a factor will be sorted alphabetically. You can also specify the level order within the call to factor as above, and other ways are possible as well.
theTable$Position <- factor(theTable$Position, levels = c(...))
Order the stacked barplot by proportion or percent in R
Add the proportion c by group like this, when generating p
:
... %>%
group_by(Name) %>%
mutate(prop_c = sum(value[variable=="c"], na.rm=T)/sum(value, na.rm=T))
Then plot, using reorder
:
ggplot() +
geom_col(data= p,aes(x = reorder(Name,prop_c, decreasing=T),y = value,fill = variable),position = "fill") +
geom_text(data = long_totals, aes(y = 100,x = Name,label = Total),size = 7,position = position_fill(vjust = 1.02)) +
scale_y_continuous(labels = scales::percent_format())
Related Topics
How Does One Reorder Columns in a Data Frame
Group by Multiple Columns in Dplyr, Using String Vector Input
Select Equivalent Rows [A-B & B-A]
Method to Extract Stat_Smooth Line Fit
Overlay Normal Curve to Histogram in R
How to Use an Image as a Point in Ggplot
How to Remove All Whitespace from a String
Incomplete Final Line' Warning When Trying to Read a .Csv File into R
How to Use Grep()/Gsub() to Find Exact Match
Why Do R Objects Not Print in a Function or a "For" Loop
How to Convert a Table to a Data Frame
Returning Multiple Objects in an R Function
Workflow For Statistical Analysis and Report Writing
How to Create an R Function Programmatically
How Can One Work Fully Generically in Data.Table in R With Column Names in Variables
How to Omit Na Values While Pasting Numerous Column Values Together