【问题标题】:Create multiple donut plots in one plot在一个图中创建多个甜甜圈图
【发布时间】:2021-05-31 17:33:06
【问题描述】:

是否可以在一张图中绘制多个甜甜圈图。 我有一个代码,它绘制了一个甜甜圈图,但是,是否可以通过year(day) 列将它们分开。结果一共会显示4个甜甜圈图?

library(ggplot2)
donut<-structure(list(`year(day)` = c(2018, 2018, 2018, 2018, 2018, 
                               2019, 2019, 2019, 2019, 2019, 2020, 2020, 2020, 2020, 2020, 2021, 
                               2021, 2021, 2021, 2021), kind = c("Audi", "BMW", "Skoda", "Ford", 
                                                                 "MB", "Audi", "BMW", "Skoda", "Ford", "MB", "Audi", "BMW", "Skoda", 
                                                                 "Ford", "MB", "Audi", "BMW", "Skoda", "Ford", "MB"), TOTL = c(82043.56, 
                                                                                                                              22908.66, 135925.42, 50448.36, 762679.18, 83680.1538461538, 35655.2115384615, 
                                                                                                                              95892.4807692308, 57961.5, 726726.423076923, 162654.5, 41344.6153846154, 
                                                                                                                              110685.038461538, 40149.4615384615, 664138.153846154, 355072.729926464, 
                                                                                                                              66555.3261904762, 102378.893809524, 55646.5438095238, 475979.351831226
                                                                 )), row.names = c(NA, -20L), groups = structure(list(`year(day)` = c(2018, 
                                                                                                                                      2019, 2020, 2021), .rows = structure(list(1:5, 6:10, 11:15, 16:20), ptype = integer(0), class = c("vctrs_list_of", 
                                                                                                                                                                                                                                        "vctrs_vctr", "list"))), row.names = c(NA, 4L), class = c("tbl_df", 
                                                                                                                                                                                                                                                                                                  "tbl", "data.frame"), .drop = TRUE), class = c("grouped_df", 
                                                                                                                                                                                                                                                                                                                                                 "tbl_df", "tbl", "data.frame"))


donut$fraction <- donut$NETP / sum(donut$NETP)
donut$ymax <- cumsum(donut$fraction)
donut$ymin <- c(0, head(donut$ymax, n=-1))
donut$labelPosition <- (donut$ymax + donut$ymin)/2
donut$label <- paste0(donut$kind, "\n NETP: ", donut$NETP)

ggplot(donut, aes(ymax=ymax, ymin=ymin, xmax=7, xmin=4, fill=kind)) +
  geom_rect() +
  geom_text( x=10, aes(y=labelPosition, label=label, color=kind), size=4.5, fontface="bold") + # x here controls label position (inner / outer)
  #scale_fill_brewer(palette=5) +
  #scale_color_brewer(palette=5) +
  coord_polar(theta="y") +
  xlim(c(-3, 10)) +
  theme_void()

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    这可以通过刻面来实现。要完成这项工作,您必须计算每个方面的 yminymax

    library(dplyr)
    library(ggplot2)
    
    donut1 <- donut %>%
      group_by(`year(day)`) %>%
      mutate(
        fraction = TOTL / sum(TOTL),
        ymax = cumsum(fraction),
        ymin = lag(ymax, default = 0),
        labelPosition = (ymax + ymin) / 2,
        label = paste0(kind, "\n TOTL: ", TOTL)
      )
    
    ggplot(donut1, aes(ymax = ymax, ymin = ymin, xmax = 7, xmin = 4, fill = kind)) +
      geom_rect() +
      geom_text(x = 10, aes(y = labelPosition, label = label, color = kind), size = 2.5, fontface = "bold") +
      coord_polar(theta = "y") +
      xlim(c(-3, 10)) +
      facet_wrap(~`year(day)`) +
      theme_void() 
    

    编辑如果您想为每个方面添加注释,我建议您通过geom_text 这样做:

    donut1_annotate <- donut1 %>% 
      group_by(`year(day)`) %>%
      summarise(totalsum = sum(TOTL))
    
    ggplot(donut1) +
      geom_rect(aes(ymax = ymax, ymin = ymin, xmax = 7, xmin = 4, fill = kind)) +
      geom_text(x = 10, aes(y = labelPosition, label = label, color = kind), size = 2.5, fontface = "bold") +
      geom_text(data = donut1_annotate, aes(label = paste("Total: ",totalsum)), x = -2, y = 0, fontface = "bold") +
      coord_polar(theta = "y") +
      xlim(c(-3, 10)) +
      facet_wrap(~`year(day)`) +
      theme_void()
    

    【讨论】:

    • 谢谢它正在工作,但你知道为什么如果我在mutate() 中添加行totalsum = sum(TOTL),然后在theme_void() + 之后添加annotate(geom = 'text', x = -2, y = 0, label = paste("Total: ",totalsum), fontface="bold") 我有一个错误: object 'totalsum' not found。据我了解,totalsum 在数据框中,但在ggplot() 中不可见。为什么会这样?
    • 如果您想使用 data.frame 中的值,您必须执行 donut1$totalsum。但是,annotate 最适合添加单个注释。因此我建议使用geom_text。查看我的编辑。
    【解决方案2】:

    我在您的数据框中找不到列 NETP,所以我改为绘制 TOTL。

    donut$fraction <- donut$TOTL / sum(donut$TOTL)
    donut$ymax <- cumsum(donut$fraction)
    donut$ymin <- c(0, head(donut$ymax, n=-1))
    donut$labelPosition <- (donut$ymax + donut$ymin)/2
    donut$label <- paste0(donut$kind, "\n NETP: ", donut$TOTL)
    
    p2018 <- ggplot(donut[donut$`year(day)` == 2018,], 
                    aes(ymax=ymax, ymin=ymin, xmax=7, xmin=4, fill=kind)) +
        geom_rect() +
        geom_text( x=10, aes(y=labelPosition, label=label, color=kind), 
                   size=4.5, fontface="bold")+
        coord_polar(theta="y") +
        xlim(c(-3, 10)) +
        theme_void()
    
    p2019 <- ggplot(donut[donut$`year(day)` == 2019,], 
                    aes(ymax=ymax, ymin=ymin, xmax=7, xmin=4, fill=kind)) +
        geom_rect() +
        geom_text( x=10, aes(y=labelPosition, label=label, color=kind), 
                   size=4.5, fontface="bold")+
        coord_polar(theta="y") +
        xlim(c(-3, 10)) +
        theme_void()
    
    p2020 <- ggplot(donut[donut$`year(day)` == 2020,], 
                    aes(ymax=ymax, ymin=ymin, xmax=7, xmin=4, fill=kind)) +
        geom_rect() +
        geom_text( x=10, aes(y=labelPosition, label=label, color=kind), 
                   size=4.5, fontface="bold")+
        coord_polar(theta="y") +
        xlim(c(-3, 10)) +
        theme_void()
    
    p2021 <- ggplot(donut[donut$`year(day)` == 2021,], 
                    aes(ymax=ymax, ymin=ymin, xmax=7, xmin=4, fill=kind)) +
        geom_rect() +
        geom_text( x=10, aes(y=labelPosition, label=label, color=kind), 
                   size=4.5, fontface="bold")+
        coord_polar(theta="y") +
        xlim(c(-3, 10)) +
        theme_void()
    
    g1 <- ggplotGrob(p2018)
    g2 <- ggplotGrob(p2019)
    g3 <- ggplotGrob(p2020)
    g4 <- ggplotGrob(p2021)
    
    grob1 <- gridExtra::arrangeGrob(grobs = list(g1, g2,g3,g4), nrow = 2)
    plot1 <- gridExtra::grid.arrange(grob1)
    

    干杯

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-25
      • 1970-01-01
      • 2021-09-08
      • 1970-01-01
      • 2016-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多