R Ggplot Ordering Bars Within Groups

R ggplot ordering bars within groups

When you group by Category, the bars are ordered according to the order of appearance of Categories in the dataframe. This works fine for Community 1 and 2 as your rows are already ordered by decreasing Count. But in Community 3, as Category "Singer-Songwriters" is the first occcurring Category in the dataframe, it is put first.

Grouping instead by an Id variable resolves the problem:

top_categories$Id=rep(c(1:5),5)

ggplot(
top_categories,
aes(
x=Community,
y=Count,
group=Id,
label=Category
)
) +
geom_bar(
stat="identity",
color="black",
fill="#9C27B0",
position="dodge"
) +
geom_text(
angle=90,
position=position_dodge(width=0.9),
hjust=-0.05
) +
ggtitle("Number of Products in each Category in Each Community") +
guides(fill=FALSE)

Sample Image

ggplot order bars within group

We can use dplyr and forcats to reorder the blue bar. Due to the structure of your data, we have to convert any variables that are characters to numeric type. Otherwise, we will not be able to reorder the factors:

library(ggplot2)
library(forcats)
library(dplyr)

barplot1 %>%
mutate_if(is.character, as.numeric) %>%
ggplot(aes(fct_reorder(X, Y, .desc = TRUE), Y, fill = Group)) +
geom_col(position = "dodge") +
geom_errorbar(aes(ymin = lb, ymax = ub), width = 0.2, position = position_dodge(.9)) +
scale_fill_manual(values = c("#0073C2B2", "#DC0000B2")) +
labs(title = "Example",
x = "X") +
theme_minimal() +
theme(
plot.title = element_text(size = 14, face = "bold", hjust = 0.5),
axis.text = element_text(size = 12),
axis.title = element_text(size = 14, face = "bold"),
legend.text = element_text(size = 12),
legend.title = element_text(size = 14),
plot.caption = element_text(size = 12)
)

Sample Image

How do I order bars in a grouped bar chart?

Since you already ordered all the rows by the appropriate groups you could add another column that represents the order within the groups and use the group aesthetic argument. That should order them as desired within the number group.

tib.ready <- tib %>% 
mutate(name = fct_reorder(name, prop, sum)) %>%
group_by(number) %>%
mutate(name = fct_reorder(name, prop, sum)) %>%
ungroup() %>%
mutate(number = fct_reorder(factor(number), prop, sum))

ggplot(tib.ready, aes(x = number, y = prop, fill = name, group = rank, label = name)) +
geom_col(position = "dodge")

edit: Updated to just use the rank variable

Ordering grouped bars using ggplot

you can try

ggplot(df, aes(x=reorder(CountryCode, sumofpct, max), y=sumofpct, fill=factor(timepoint, levels = c("last", "first")))) +
geom_col(position = "dodge") + # recommended over geom_bar
geom_text(aes(label=sumofpct), hjust=1, color='black',size=5, position=position_dodge(width=0.9)) +
scale_fill_manual("timepoint", values = c("violetred3",'steelblue'), guide = guide_legend(reverse = TRUE))+
coord_flip()

Sample Image

Instead of reorder you can use forcats::fct_reorder2(CountryCode, timepoint=="first", -sumofpct)

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)

barplot figure

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(...))

How to reorder the groups in a grouped bar-chart

We need to convert the 'Groups' to factor with levels specified in that order

df_bars$Groups <- factor(df_bars$Groups, levels = c('B', 'C', 'A'))

Then using the ggplot code in the OP's post

Sample Image

ggplot2 bar-chart order by values of one group

Process the data outside the call to ggplot to determine the factor order for the grouping variable you are interested in (labels). Then apply this factor to the labels variable in ggplot.

library(ggplot2)
library(dplyr)

sel_order <-
data %>%
filter(variable == "selected") %>%
arrange(desc(value)) %>%
mutate(labels = factor(labels))

data %>%
mutate(labels = factor(labels, levels = sel_order$labels, ordered = TRUE)) %>%
ggplot(aes(x = labels, y = value, fill = variable), group = labels) +
geom_bar(stat="identity", width=.5, position = "dodge") +
theme(axis.text.x = element_text(angle = 90, hjust = 1))

Created on 2020-05-26 by the reprex package (v0.3.0)

R - Issues with group order/ ggplot dodge barchart

To reorder the subsegment, assign factor to it and specify the orders in levels.

To reorder the bars within dodged bar chart, use reorder to order the dodged bars with descending size of values.

library(tidyverse)

ggplot(df, aes(factor(subsegment, levels = c("Sub3", "Sub1", "Sub2")),
values,
fill = reorder(company, desc(values)))) +
geom_bar(position="dodge", stat="identity", alpha=0.5) +
labs(x = "subsegment", fill = "company")

reorder_dodged_bar



Related Topics



Leave a reply



Submit