pie chart with ggplot2 with specific order and percentage annotations

25,452

Solution 1

You have to change levels of Make by share or volume (provided data is already sorted):

dfc$Make <- factor(dfc$Make, levels = rev(as.character(dfc$Make)))

And play with theme arguments:

ggplot(dfc[1:10, ], aes("", share, fill = Make)) +
    geom_bar(width = 1, size = 1, color = "white", stat = "identity") +
    coord_polar("y") +
    geom_text(aes(label = paste0(round(share), "%")), 
              position = position_stack(vjust = 0.5)) +
    labs(x = NULL, y = NULL, fill = NULL, 
         title = "market share") +
    guides(fill = guide_legend(reverse = TRUE)) +
    scale_fill_manual(values = c("#ffd700", "#bcbcbc", "#ffa500", "#254290")) +
    theme_classic() +
    theme(axis.line = element_blank(),
          axis.text = element_blank(),
          axis.ticks = element_blank(),
          plot.title = element_text(hjust = 0.5, color = "#666666"))

enter image description here

Solution 2

You can try:

df %>%
  group_by(Make) %>%
  summarise(volume = sum(Cnt)) %>%
  mutate(share=volume/sum(volume)) %>%
  ggplot(aes(x="", y= share, fill=reorder(Make, volume))) +
   geom_col() +
   geom_text(aes(label = scales::percent(round(share,3))), position = position_stack(vjust = 0.5))+
   coord_polar(theta = "y") + 
   theme_void()

enter image description here

add guides(fill = guide_legend(reverse = TRUE)) for a reversed legend

Share:
25,452
user3206440
Author by

user3206440

Updated on December 19, 2020

Comments

  • user3206440
    user3206440 over 3 years

    I have a data frame like below

    +--------+-----------+-----+
    |  make  |   model   | cnt |
    +--------+-----------+-----+
    | toyota |  camry    |  10 |
    | toyota |  corolla  |   4 |
    | honda  |  city     |   8 |
    | honda  |  accord   |  13 |
    | jeep   |  compass  |   3 |
    | jeep   |  wrangler |   5 |
    | jeep   |  renegade |   1 |
    | accura |  x1       |   2 |
    | accura |  x3       |   1 |
    +--------+-----------+-----+
    

    I need to create a pie ( yes really) of the percentage share for each make.

    I do the following as of now.

    library(ggplot2)
    library(dplyr)
    
    df <- data.frame(Make=c('toyota','toyota','honda','honda','jeep','jeep','jeep','accura','accura'),
                     Model=c('camry','corolla','city','accord','compass', 'wrangler','renegade','x1', 'x3'),
                     Cnt=c(10, 4, 8, 13, 3, 5, 1, 2, 1))
    dfc <- df %>%
      group_by(Make) %>%
      summarise(volume = sum(Cnt)) %>%
      mutate(share=volume/sum(volume)*100.0) %>%
      arrange(desc(volume))
    
    bp <- ggplot(dfc[c(1:10),], aes(x="", y= share, fill=Make)) +
      geom_bar(width = 1, stat = "identity")
    pie <- bp + coord_polar("y")
    pie
    

    This gives me the following pie chart which is pretty neat.

    enter image description here

    However I need to enhance this with the following things - like in the image below.

    1. add percentage labels
    2. order the pies in desc order of share
    3. remove lables like 0/100, 25
    4. add a title

    enter image description here

  • user3206440
    user3206440 over 6 years
    The order of the pies need to be in the same order of share % - so Honda shall come first in the pie.
  • Microscone
    Microscone over 4 years
    Very nice! How would you increase the size of the percentage labels?
  • pogibas
    pogibas over 4 years
    @Microscone change size within geom_text. For example: geom_text(size = 10, ...)