Rather than using the default geom_bar(stat = "count")
, try geom_bar(stat = "identity")
. You might easily calculate the percentage with dplyr
. For example, consider ggplot2::mpg
data,
This dataset contains a subset of the fuel economy data that the EPA makes available on http://fueleconomy.gov. It contains only models which had a new release every year between 1999 and 2008 - this was used as a proxy for the popularity of the car.
-- https://ggplot2.tidyverse.org/reference/mpg.html
ggplot2::mpg %>% select(manufacturer, year)
#> # A tibble: 234 x 2
#> manufacturer year
#> <chr> <int>
#> 1 audi 1999
#> 2 audi 1999
#> 3 audi 2008
#> 4 audi 2008
#> 5 audi 1999
#> 6 audi 1999
#> 7 audi 2008
#> 8 audi 1999
#> 9 audi 1999
#> 10 audi 2008
#> # ... with 224 more rows
manufacturer
: model name
year
: year of manufacture
library(tidyverse)
1. Percentage versus year
You can calculate the percentage of each manufacturer
over year
. In other words, the sum of percentage over year in each manufacturer
might be 1.
Also, you can use scales::percent
instead of labels = function(x) paste0(x*100, "%")
.
mpg %>%
group_by(manufacturer) %>%
mutate(N = n()) %>% # number of each manufacturer
group_by(manufacturer, year) %>% # pair of manu, year
summarise(perc = n() / unique(N)) %>% # n() = number of each pair => n()/N = proportion
ggplot() +
aes(x = manufacturer, y = perc, fill = factor(year)) +
geom_bar(position = "dodge", stat = "identity") + # use y as y axis
scale_y_continuous(labels = scales::percent) +
theme(axis.text.x = element_text(angle = 45, hjust = 1),
axis.title = element_blank()) +
labs(fill = "Year")

Adding each tick(red and blue), you can get 100% each.
2. Percentage over year
On the other hand, you can compute proportion of manufacturer
in each year
so that the sum of each year becomes 1.
mpg %>%
group_by(year) %>%
mutate(N = n()) %>%
group_by(manufacturer, year) %>%
summarise(perc = n() / unique(N)) %>%
ggplot() +
aes(x = manufacturer, y = perc, fill = factor(year)) +
geom_bar(position = "dodge", stat = "identity") +
scale_y_continuous(labels = scales::percent) +
theme(axis.text.x = element_text(angle = 45, hjust = 1),
axis.title = element_blank()) +
labs(fill = "Year")

Adding each colour, you can get 100% each.