Search code examples
rggplot2data-visualizationpie-chart

How to center Pie chart and nested pie for a subsection?


I am trying to plot a nested pie chart. However, I do not get a full pie chart. Top and bottom side of the pie is missing.

enter image description here

For example, I am only interested in expanding "Agriculture" in the nested pie. I have calculated size in % for each

I am interested in pie chart look likes below

enter image description here

Here is my working script.

library(ggplot2)
library(plotrix)

df <- structure(list(parent = c("Energy", "Industry", "Transport", "Buildings ", "Agriculture", "Agriculture", "Agriculture", "Agriculture", "Agriculture", "Agriculture", "Agriculture", "Forestry and Land Use " ), node = c("Energy", "Industry", "Transport", "Buildings ", "Enteric Fermentation", "Manure Left on Pasture", "Synthetic Fertilizers", "Paddy Rice", "Manure Management ", "Burning of savannahs", "Other", "Forestry and Land Use "), size = c(35, 21, 14, 6, 4.8, 1.92, 1.56, 1.2, 0.84, 0.6, 1.08, 12)), row.names = c(NA, -12L), class = c("data.table", "data.frame"))  

# aggregate data for the df pie chart
df_data <-
  aggregate(df$size,
            by = list(df = df$parent),
            FUN = sum)

# order sub_data data by df so it will line up with df pie chart
sub_data <- df[order(df$node), ]

df_colors <- c('#85EA72', '#3B3B3F', '#71ACE9', '#747AE6', '#F69852','#F69992')

# adjust these as desired (currently colors all subdatas the same as df)
sub_data_colors <-
  c('#85EA72', '#3B3B3F', '#71ACE9', '#747AE6', '#F69852','#F69992', '#85EA88', '#3B3B4F', '#71ACC9', '#747EE6', '#F69899','#F68882')

# format labels to display subdata and % market size
sub_data_labels <- paste(sub_data$sub_data, ": ", sub_data$size, "%", sep = "")

# coordinates for the center of the chart
center_x <- 0.5
center_y <- 0.5

plot.new()

# draw sub_data pie chart first
sub_data_chart <-
  floating.pie(
    xpos = center_x,
    ypos = center_y,
    x = sub_data$size,
    radius = 0.35,
    border = "white",
    col = sub_data_colors
  )

# add labels for sub_data pie chart
pie.labels(
  x = center_x,
  y = center_y,
  angles = sub_data_chart,
  labels = sub_data_labels,
  radius = 0.38,
  bg = NULL,
  cex = 0.8,
  font = 2,
  col = "gray40"
)

# overlay df pie chart
df_chart <-
  floating.pie(
    xpos = center_x,
    ypos = center_y,
    x = df_data$x,
    radius = 0.25,
    border = "white",
    col = df_colors
  )

# add labels for df pie chart
pie.labels(
  x = center_x,
  y = center_y,
  angles = df_chart,
  labels = df_data$df,
  radius = 0.125,
  bg = NULL,
  cex = 0.8,
  font = 2,
  col = "white"
)

Could someone assist me to figure out the error? Thank you.


Solution

  • Regarding the missing edges, just increase your "Plots" Tab to the needed size.

    Regarding the splitted subsection, my solution is basically to set all other sections to a white color so you wouldn't see them on a white background.

    library(ggplot2)
    library(plotrix)
    library(data.table)
    
    
    df <- structure(list(parent = c("Energy", "Industry", "Transport", "Buildings ",
                                    "Agriculture", "Agriculture", "Agriculture", 
                                    "Agriculture", "Agriculture", "Agriculture",
                                    "Agriculture", "Forestry and Land Use " ), 
                         node = c("Energy", "Industry", "Transport", "Buildings ",
                                  "Enteric Fermentation", "Manure Left on Pasture",
                                  "Synthetic Fertilizers", "Paddy Rice",
                                  "Manure Management ", "Burning of savannahs", 
                                  "Other", "Forestry and Land Use "), 
                         size = c(35, 21, 14, 6, 4.8, 1.92, 1.56,
                                  1.2, 0.84, 0.6, 1.08, 12)),
                    row.names = c(NA, -12L), 
                    class = c("data.table", "data.frame"))  
    
    # aggregate data for the df pie chart
    df_data <-
      aggregate(df$size,
                by = list(df = df$parent),
                FUN = sum)
    
    # order sub_data data by df so it will line up with df pie chart
    sub_data <- df[order(df$node), ]
    
    df_colors <- c('#85EA72', '#3B3B3F', '#71ACE9', '#747AE6', '#F69852','#F69992')
    
    # adjust these as desired (currently colors all subdatas the same as df)
    sub_data_colors <-
      c('#85EA72', '#3B3B3F', '#71ACE9', '#747AE6', '#F69852','#F69992', '#85EA88',
        '#3B3B4F', '#71ACC9', '#747EE6', '#F69899','#F68882')
    
    # format labels to display subdata and % market size
    sub_data_labels <- paste(sub_data$sub_data, ": ", sub_data$size, "%", sep = "")
    # coordinates for the center of the chart
    center_x <- 0.5
    center_y <- 0.5
    
    # colors should always match with the group
    sub_data$color <- sub_data_colors
    
    # set all other groups to white. Hence, they are not shown in the plot
    sub_data[parent != "Agriculture", color := "#ffffff"]
    
    # correct order is important
    data.table::setorder(sub_data, -parent)
    
    # Enlarge the "Plots" tab to the needed size
    plot.new()
    
    
    # draw sub_data pie chart first
    sub_data_chart <-
      floating.pie(
        xpos = center_x,
        ypos = center_y,
        x = sub_data$size,
        radius = 0.35,
        border = "white",
        col = sub_data$color
      )
    
    # add labels for sub_data pie chart
    pie.labels(
      x = center_x,
      y = center_y,
      angles = sub_data_chart,
      labels = sub_data_labels,
      radius = 0.38,
      bg = NULL,
      cex = 0.8,
      font = 2,
      col = "gray40"
    )
    
    data.table::setorder(df_data, -df)
    
    # overlay df pie chart
    df_chart <-
      floating.pie(
        xpos = center_x,
        ypos = center_y,
        x = df_data$x,
        radius = 0.25,
        border = "white",
        col = df_colors
      )
    
    # add labels for df pie chart
    pie.labels(
      x = center_x,
      y = center_y,
      angles = df_chart,
      labels = df_data$df,
      radius = 0.125,
      bg = NULL,
      cex = 0.8,
      font = 2,
      col = "white"
    )
    

    enter image description here