Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding percentage labels to a bar chart in ggplot2

Tags:

r

ggplot2

How can I use geom_text to add percentage labels on top of each bar in ggplot2? I know there are several similar questions which are already answered. But they either use only 1 categorical variable or compute the percentages before plotting.
I have following plot:

ggplot(data = mtcars)+
  geom_bar(aes(x = factor(cyl), 
               y = (..count..)/sum(..count..)*100,
               fill = factor(gear)),
           position = "dodge")  

Now I want to add the percentage labels on the top. If I use y = (..count..)/sum(..count..)*100 in geom_text, it says Error in eval(expr, envir, enclos) : object 'count' not found.

like image 746
umair durrani Avatar asked Oct 25 '16 21:10

umair durrani


People also ask

How do you add percentages in ggplot2?

We can improve the barplot further by labeling the percentage values directly on the bars with percent symbols. To do that, we will use label argument with scales' percent function. And use geom_text() function to add the labels with percentage symbol on bars.

How do I add labels to a bar chart in R?

To add labels on top of each bar in Barplot in R we use the geom_text() function of the ggplot2 package. Parameters: value: value field of which labels have to display.

How do I change y axis to percentage in ggplot2?

Since we need to add percentages in the labels of the Y-axis, the keyword “labels” is used. Now use scales: : percent to convert the y-axis labels into a percentage. This will scale the y-axis data from decimal to percentage. It simply multiplies the value by 100.

How do you add a percentage to a bar chart in Python?

Make a list of frequencies. Create a new figure or activate an existing figure. Make a bar plot using bar() method. Iterate the bar plot and find the height of each patch and use annotate() method to put values in percentages.


1 Answers

It's easiest to calculate the quantities you need beforehand, outside of ggplot, as it's hard to track what ggplot calculates and where those quantities are stored and available.

First, summarize your data:

library(dplyr)
library(ggplot2)

mtcars %>% 
    count(cyl = factor(cyl), gear = factor(gear)) %>% 
    mutate(pct = prop.table(n))
#> # A tibble: 8 x 4
#>   cyl   gear      n    pct
#>   <fct> <fct> <int>  <dbl>
#> 1 4     3         1 0.0312
#> 2 4     4         8 0.25  
#> 3 4     5         2 0.0625
#> 4 6     3         2 0.0625
#> 5 6     4         4 0.125 
#> 6 6     5         1 0.0312
#> 7 8     3        12 0.375 
#> 8 8     5         2 0.0625

Save that if you like, or pipe directly into ggplot:

mtcars %>% 
    count(cyl = factor(cyl), gear = factor(gear)) %>% 
    mutate(pct = prop.table(n)) %>% 
    ggplot(aes(x = cyl, y = pct, fill = gear, label = scales::percent(pct))) + 
    geom_col(position = 'dodge') + 
    geom_text(position = position_dodge(width = .9),    # move to center of bars
              vjust = -0.5,    # nudge above top of bar
              size = 3) + 
    scale_y_continuous(labels = scales::percent)

If you really want to keep it all internal to ggplot, you can use geom_text with stat = 'count' (or stat_count with geom = "text", if you prefer):

ggplot(data = mtcars, aes(x = factor(cyl), 
                          y = prop.table(stat(count)), 
                          fill = factor(gear), 
                          label = scales::percent(prop.table(stat(count))))) +
    geom_bar(position = "dodge") + 
    geom_text(stat = 'count',
              position = position_dodge(.9), 
              vjust = -0.5, 
              size = 3) + 
    scale_y_continuous(labels = scales::percent) + 
    labs(x = 'cyl', y = 'pct', fill = 'gear')

which plots exactly the same thing.

like image 195
alistaire Avatar answered Sep 20 '22 08:09

alistaire