ggraph/igraph
, the result in below plot isn't correct :
1)The amount of DE is 4.5, but the sub circles are 8.8 and 9 (the correct amount should be "DE cat_a 3.0, DE cat_b 1.5")
How to fix it ? Thanks!
library(ggraph)
library(igraph)
library(tidyverse)
library(viridis)
base <- data.frame(from =c('US','US','UK','UK','DE','DE'),
to = c('cat_a','cat_b','cat_a','cat_b','cat_a','cat_b'),
sales=c(1,3,5,4,3,1.5))
vetic <- base %>% gather(key='type', value ='dim',c(1:2)) %>%
group_by(dim) %>% summarise(sales = sum(sales))
mdf <- graph_from_data_frame(base,directed = TRUE,vertices = vetic)
ggraph(mdf, layout = 'circlepack', weight=sales) +
geom_node_circle(aes(fill = depth)) +
geom_node_text(size=10,aes(label= paste0(name,'\n',sales)))+
theme_void()+scale_fill_distiller(palette = "RdPu")
The problem lies with how you are creating your graph. It seems you want to show the amount of cat_a
and cat_b
within each country, but you are creating the graph as though cat_a
and cat_b
are each a single node. If you want a cat_a
and a cat_b
node inside each country, then you need to specify them as distinct nodes.
For example, we can do:
library(ggraph)
library(igraph)
library(tidyverse)
library(viridis)
base <- data.frame(from =c('US','US','UK','UK','DE','DE'),
to = c('cat_a','cat_b','cat_a','cat_b','cat_a','cat_b'),
sales=c(1,3,5,4,3,1.5))
base_fixed <- base %>% mutate(to = paste(from, to))
Which gives the following data frame:
base_fixed
#> from to sales
#> 1 US US cat_a 1.0
#> 2 US US cat_b 3.0
#> 3 UK UK cat_a 5.0
#> 4 UK UK cat_b 4.0
#> 5 DE DE cat_a 3.0
#> 6 DE DE cat_b 1.5
Similarly, the vertices should have a label and value for each of the resulting 9 nodes (3 country nodes, plus two "cat" nodes within each):
vertices <- base_fixed %>%
group_by(from) %>%
summarize(sales = sum(sales)) %>%
rbind(base_fixed %>% select(-1) %>% rename(from = to))
vertices
#> # A tibble: 9 x 2
#> from sales
#> <chr> <dbl>
#> 1 DE 4.5
#> 2 UK 9
#> 3 US 4
#> 4 US cat_a 1
#> 5 US cat_b 3
#> 6 UK cat_a 5
#> 7 UK cat_b 4
#> 8 DE cat_a 3
#> 9 DE cat_b 1.5
The graph could then be drawn as follows:
graph_from_data_frame(base_fixed, vertices = vertices) %>%
ggraph(layout = 'circlepack', weight = sales) +
geom_node_circle(aes(fill = depth)) +
geom_node_text(size = 5,
aes(label = ifelse(depth == 0, '',
paste0(substr(name, 4, 20), '\n', sales)))) +
geom_node_label(size = 6, aes(label = ifelse(depth == 1, NA,
substr(name, 1, 2)))) +
theme_void() +
scale_fill_distiller(palette = "RdPu", guide = 'none') +
coord_equal()
Created on 2023-05-15 with reprex v2.0.2