Nest donut chart with plotly or highcharts in R

Viewed 44
library(webr)
data <- as.data.frame(Titanic)  

pd = data %>% 
  group_by(Class, Survived) %>% 
  summarise(n = sum(Freq))

PieDonut(pd,  aes(Class, Survived, count = n),
         labelposition = 0,
         r0 = 0.5,
         r1 = 0.95,
         title = "Titanic: Survial by Class")

This donut fig was made With webr package, is it possible to polt such an interactive fig with plotly or highchart.

enter image description here

1 Answers

1. The plotly way

The input data format for plotly's sunburst option is confusing (i.e. a bit of a pain); the relevant example in the documentation is Sunburst with Repeated Labels.

The key is to

  1. transform the data in the following way by adding marginal sums (both total and group-level, see my in-line comments), and
  2. add a unique ids column.
library(tidyverse)
df <- bind_rows(
    # Full total
    pd %>% summarise(labels = "Total", n = sum(n)),
    # "Class"-level totals
    pd %>% 
        group_by(labels = Class) %>% 
        summarise(
            n = sum(n), 
            parents = "Total",
            .groups = "drop"),
    # Individual Class+Survived-level numbers
    pd %>% 
        rename(parents = Class, labels = Survived) %>%
        mutate(parents = paste("Total", parents, sep = " - "))) %>%
    # Add unique ids column
    mutate(ids = if_else(
        is.na(parents), labels, paste(parents, labels, sep = " - ")))
## A tibble: 13 × 4
#   labels     n parents      ids               
#   <chr>  <dbl> <chr>        <chr>             
# 1 Total   2201 NA           Total             
# 2 1st      325 Total        Total - 1st       
# 3 2nd      285 Total        Total - 2nd       
# 4 3rd      706 Total        Total - 3rd       
# 5 Crew     885 Total        Total - Crew      
# 6 No       122 Total - 1st  Total - 1st - No  
# 7 Yes      203 Total - 1st  Total - 1st - Yes 
# 8 No       167 Total - 2nd  Total - 2nd - No  
# 9 Yes      118 Total - 2nd  Total - 2nd - Yes 
#10 No       528 Total - 3rd  Total - 3rd - No  
#11 Yes      178 Total - 3rd  Total - 3rd - Yes 
#12 No       673 Total - Crew Total - Crew - No 
#13 Yes      212 Total - Crew Total - Crew - Yes

Then

library(plotly)
plot_ly(
    data = df,
    ids = ~ids,
    labels = ~labels,
    parents = ~parents,
    values = ~n,
    type = "sunburst",
    branchvalues = "total")

enter image description here


2. The highcharter way

highcharter provides the convenience function data_to_hierarchical() to reformat input data for a sunburst visualisation:

library(tidyverse)
library(highcharter)
pd %>% 
    data_to_hierarchical(c(Class, Survived), n) %>%
    hchart(type = "sunburst")

enter image description here

Related