ggplot Donut chart

后端 未结 2 1467
臣服心动
臣服心动 2020-12-07 23:24

Hi I really have googled this a lot without any joy. Would be happy to get a reference to a website if it exists. I\'m struggling to understand the Hadley documentation on p

相关标签:
2条回答
  • 2020-12-07 23:59

    I don't have a full answer to your question, but I can offer some code that may help get you started making ring plots using ggplot2.

    library(ggplot2)
    
    # Create test data.
    dat = data.frame(count=c(10, 60, 30), category=c("A", "B", "C"))
    
    # Add addition columns, needed for drawing with geom_rect.
    dat$fraction = dat$count / sum(dat$count)
    dat = dat[order(dat$fraction), ]
    dat$ymax = cumsum(dat$fraction)
    dat$ymin = c(0, head(dat$ymax, n=-1))
    
    p1 = ggplot(dat, aes(fill=category, ymax=ymax, ymin=ymin, xmax=4, xmin=3)) +
         geom_rect() +
         coord_polar(theta="y") +
         xlim(c(0, 4)) +
         labs(title="Basic ring plot")
    
    p2 = ggplot(dat, aes(fill=category, ymax=ymax, ymin=ymin, xmax=4, xmin=3)) +
         geom_rect(colour="grey30") +
         coord_polar(theta="y") +
         xlim(c(0, 4)) +
         theme_bw() +
         theme(panel.grid=element_blank()) +
         theme(axis.text=element_blank()) +
         theme(axis.ticks=element_blank()) +
         labs(title="Customized ring plot")
    
    
    library(gridExtra)
    png("ring_plots_1.png", height=4, width=8, units="in", res=120)
    grid.arrange(p1, p2, nrow=1)
    dev.off()
    

    enter image description here

    Thoughts:

    1. You may get more useful answers if you post some well-structured sample data. You have mentioned using some columns from the iris dataset (a good start), but I am unable to see how to use that data to make a ring plot. For example, the ring plot you have linked to shows proportions of several categories, but neither iris[, 2:4] nor iris[, 1] are categorical.
    2. You want to "Add a second layer circle on top": Do you mean to superimpose the second ring directly on top of the first? Or do you want the second ring to be inside or outside of the first? You could add a second internal ring with something like geom_rect(data=dat2, xmax=3, xmin=2, aes(ymax=ymax, ymin=ymin))
    3. If your data.frame has a column named period, you can use facet_wrap(~ period) for facetting.
    4. To use ggplot2 most easily, you will want your data in 'long-form'; melt() from the reshape2 package may be useful for converting the data.
    5. Make some barplots for comparison, even if you decide not to use them. For example, try: ggplot(dat, aes(x=category, y=count, fill=category)) + geom_bar(stat="identity")
    0 讨论(0)
  • 2020-12-08 00:20

    Just trying to solve question 2 with the same approach from bdemarest's answer. Also using his code as a scaffold. I added some tests to make it more complete but feel free to remove them.

    library(broom)
    library(tidyverse)
    # Create test data.
    dat = data.frame(count=c(10,60,20,50),
                     ring=c("A", "A","B","B"),
                     category=c("C","D","C","D"))
    
    # compute pvalue
    cs.pvalue <- dat %>% spread(value = count,key=category) %>%
      ungroup() %>% select(-ring) %>% 
      chisq.test() %>% tidy()
    cs.pvalue <- dat %>% spread(value = count,key=category) %>% 
      select(-ring) %>%
      fisher.test() %>% tidy() %>% full_join(cs.pvalue)
    
    # compute fractions
    #dat = dat[order(dat$count), ]
    dat %<>% group_by(ring) %>% mutate(fraction = count / sum(count),
                                          ymax = cumsum(fraction),
                                          ymin = c(0,ymax[1:length(ymax)-1]))
    
    
    # Add x limits
    baseNum <- 4
    #numCat <- length(unique(dat$ring))
    dat$xmax <- as.numeric(dat$ring) + baseNum
    dat$xmin = dat$xmax -1
    
    
    # plot
    p2 = ggplot(dat, aes(fill=category,
                         alpha = ring,
                         ymax=ymax, 
                         ymin=ymin, 
                         xmax=xmax, 
                         xmin=xmin)) +
      geom_rect(colour="grey30") +
      coord_polar(theta="y") +
      geom_text(inherit.aes = F,
                x=c(-1,1),
                y=0,
                data = cs.pvalue,aes(label = paste(method,
                                                   "\n",
                                                   format(p.value,
                                                          scientific = T,
                                                          digits = 2))))+
      xlim(c(0, 6)) +
      theme_bw() +
      theme(panel.grid=element_blank()) +
      theme(axis.text=element_blank()) +
      theme(axis.ticks=element_blank(),
            panel.border = element_blank()) +
      labs(title="Customized ring plot") + 
      scale_fill_brewer(palette = "Set1") +
      scale_alpha_discrete(range = c(0.5,0.9))
    
    p2
    

    And the result:

    Imgur

    0 讨论(0)
提交回复
热议问题