Search code examples
rchartsplotly

How to hide outside lables in plotly donut chart


I am working on a Flexdashboard with runtime Shiny where I'm plotting a Donut chart. The slices depend on a certain variable and sometimes are too small for the percentage to be shown inside, in which case the labels are displayed outside the chart like in the image below.

Donut Chart Image

is there a way to keep the labels/percentages with big enough slices and get rid of the ones that are on the outside due to smaller slices? the way it looks in the image above is just too messy and I want to be able to see the percentage data without having to hover over it.

this the data and code

library(plotly)
library(tidyr)
library(dplyr)

InT <- data.frame(Category = c(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,AA,AB),
`Category Value` = c(172928,1106269,222102,0,1054448,682990,1975937,779346,12398,0,1450944,368130,2493154,4347455,1865752,1443840,692972,61891,6443758,1539659,1659183,2711385,856182,1992250,3722195,2762090,257023,1204422))

plot_ly(InT, labels = ~Category, values = ~`Category Value`) %>%
  add_pie(hole = 0.6) %>%
  layout(title = "",  showlegend = F, 
         xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = TRUE),
         yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = TRUE))

Solution

    1. Another option is to lump together the Categories with "small" count using fct_lump_min() from forcats package.
    2. Another practical tip: Instead of InT <- data.frame use InT <- as_data_frame or tibble if you want to use Category Value as name. Because data.frame and as.data.frame changes names to . separated ones. In case it is intended to use Category.Value (which is good) then you have to adapt your further code.
    3. Another hint: If you want to use data.frame then pass a list of vectors and add check.names = FALSE then the variable name will keep as Category Value. Here are some options:
    InT <- tibble(
      Category = c(LETTERS, "AA", "AB"),
      `Category Value` = c(172928, 1106269, 222102, 0, 1054448, 682990, 1975937, 779346, 12398, 0, 1450944, 368130, 2493154, 4347455, 1865752, 1443840, 692972, 61891, 6443758, 1539659, 1659183, 2711385, 856182, 1992250, 3722195, 2762090, 257023, 1204422)
    )
    InT
    
    InT <- as_data_frame(list(
      Category = c(LETTERS, "AA", "AB"),
      `Category Value` = c(172928, 1106269, 222102, 0, 1054448, 682990, 1975937, 779346, 12398, 0, 1450944, 368130, 2493154, 4347455, 1865752, 1443840, 692972, 61891, 6443758, 1539659, 1659183, 2711385, 856182, 1992250, 3722195, 2762090, 257023, 1204422)
    ))
    InT
    
    InT <- data.frame(list(
      Category = c(LETTERS, "AA", "AB"),
      `Category Value` = c(172928, 1106269, 222102, 0, 1054448, 682990, 1975937, 779346, 12398, 0, 1450944, 368130, 2493154, 4347455, 1865752, 1443840, 692972, 61891, 6443758, 1539659, 1659183, 2711385, 856182, 1992250, 3722195, 2762090, 257023, 1204422)
    ), check.names = FALSE)
    InT
    

    The lumpted plot:

    library(plotly)
    library(dplyr)
    library(forcats)
    
    InT %>%
      mutate(Category = fct_lump_min(Category, min = 400000, w = `Category Value`)) %>% 
      summarise(`Category Value` = sum(`Category Value`), .by=Category) %>% 
      plot_ly(labels = ~Category, values = ~`Category Value`) %>%
      add_pie(hole = 0.6) %>%
      layout(title = "", showlegend = F, 
             xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = TRUE),
             yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = TRUE))
    

    enter image description here