将饼图插入条形图

问题描述 投票:0回答:1

假设我有以下用

library(plotly)
制作的条形图(右侧的空格是故意的):

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

d <- tibble(cat = LETTERS[1:3],
            val = c(25, 10, 30),
            total = 40)

(bars <- d %>%
  mutate(remaining = total - val) %>%
  pivot_longer(cols = c(val, remaining)) %>% 
  plot_ly(x = ~ value, y =  ~ cat, 
          type = "bar", 
          orientation = 'h', color = ~ name, 
          colors = c("#440154FF", "#FDE725FF")) %>%
  layout(xaxis = list(title = NA, range= c(0, 60)),
         yaxis = list(title = NA),
         showlegend = FALSE,
         barmode = "stack"))

我现在想在

x == 50
和相应的 y 位置插入以下饼图:

pies <- d %>%
  rowwise() %>%
  group_map(~ plot_ly(.x) %>% 
              add_pie(values = ~ c(val, total - val),
                      marker = list(colors = c("#440154FF", "#FDE725FF"))))

预期结果如下所示(通过手动将饼图粘贴到条形图中完成):

理想情况下,xa 轴的跨度会一直到 40,并且饼图下方没有可见的轴。


P.S:我发现在这个 reprex 中,颜色也很混乱,我该如何调整饼图中的颜色,使它们与条形图中的颜色相匹配?

r plotly
1个回答
0
投票

如果您准备使用一点数学知识,则可以在 tidyverse 中执行此操作,无需任何额外的软件包:

make_pie <- function(x, y, size, groups, n, rownum, aspect = 1) {
  angles <- c(0, 2*pi * cumsum(n)/sum(n))
  do.call("rbind", Map(function(a1, a2, g) {
    xvals <- c(0, sin(seq(a1, a2, len = 30)) * size, 0) * aspect + x
    yvals <- c(0, cos(seq(a1, a2, len = 30)) * size, 0) + y
    data.frame(x = xvals, y = yvals, group = g, rownum = rownum)
  }, head(angles, -1), tail(angles, -1), groups))
}

pies <- d %>%
  mutate(r = row_number(), y = as.numeric(factor(cat))) %>%
  rowwise() %>%
  group_map(~ with(.x, make_pie(50, y, 0.4, aspect = 15,
                                c("val", "neg"), c(val, total - val), r))) %>%
  bind_rows() 

d %>%
  mutate(neg = total - val) %>%
  select(-total) %>%
  pivot_longer(-1) %>%
  ggplot(aes(value, cat, fill = name)) +
  geom_col() +
  geom_polygon(aes(x = x, y = y, fill = group), data = pies) +
  scale_fill_manual(values = c("#FDE725FF", "#440154FF"), guide = 'none') +
  theme_minimal()

© www.soinside.com 2019 - 2024. All rights reserved.