Ordering stacked bar charts using ggplot

infoart.ca
2 min readJan 28, 2024

--

Photo by Eaters Collective on Unsplash

In data visualization, stacked bar charts are a useful way to represent categorical data with multiple subcategories. However, the default ordering of the bars might not always be optimal for conveying the desired message. In this post, we will explore how to order stacked bar charts using the popular ggplot2 package in R.

Let’s fabricate a fake dataset first:

data <- data.frame(
country = c("Country A", "Country B", "Country C", "Country D", "Country E"),
Agriculture = c(82.2, 78.4, 73.2, 60.3, 57.8),
Education = c(1.63, 3.29, 3.65, 6.56, 8.94),
Healthcare = c(11.0, 10.7, 15.2, 15.1, 16.0),
IT = c(5.18, 7.61, 7.91, 18.00, 17.30)
)

> data
country Agriculture Education Healthcare IT
1 Country A 82.2 1.63 11.0 5.18
2 Country B 78.4 3.29 10.7 7.61
3 Country C 73.2 3.65 15.2 7.91
4 Country D 60.3 6.56 15.1 18.00
5 Country E 57.8 8.94 16.0 17.30

Our goal is to visualize and compare the percent distribution of employment by sector.

To do so, the data will take a quick reshaping:

data = data %>%
mutate(country = factor(country,
levels = country[order(IT, decreasing = F)])) %>%
pivot_longer(cols = -country, names_to = "Frequency", values_to = "Percentage")


# A tibble: 20 × 3
country Frequency Percentage
<fct> <chr> <dbl>
1 Country A Agriculture 82.2
2 Country A Education 1.63
3 Country A Healthcare 11
4 Country A IT 5.18
5 Country B Agriculture 78.4
6 Country B Education 3.29
7 Country B Healthcare 10.7
8 Country B IT 7.61
9 Country C Agriculture 73.2
10 Country C Education 3.65
11 Country C Healthcare 15.2
12 Country C IT 7.91
13 Country D Agriculture 60.3
14 Country D Education 6.56
15 Country D Healthcare 15.1
16 Country D IT 18
17 Country E Agriculture 57.8
18 Country E Education 8.94
19 Country E Healthcare 16
20 Country E IT 17.3

to generate the desired plot:

data %>%
mutate(country = factor(country,
levels = country[order(IT, decreasing = F)])) %>%
pivot_longer(cols = -country, names_to = "Frequency", values_to = "Percentage") %>%
ggplot(aes(x = country, y = Percentage, fill = Frequency)) +
geom_bar(stat = "identity") + theme_minimal()+
coord_flip()

--

--

infoart.ca
infoart.ca

Written by infoart.ca

Center for Social Capital & Environmental Research | Posts by Bishwajit Ghose, BI consultant and lecturer at the University of Ottawa

No responses yet