R::ggplot2::geom_points: how to swap points with pie charts?

前端 未结 1 1416
悲&欢浪女
悲&欢浪女 2020-12-04 01:18

I would like to plot pie charts in two dimensions to show the composition of each point in terms of their composite \"groups.\"

So far, I\'m using label repel to lab

相关标签:
1条回答
  • 2020-12-04 02:01

    Update:

    If you want pie charts in particular, you're better off with package scatterpie, https://cran.r-project.org/web/packages/scatterpie/vignettes/scatterpie.html. My method below works with non-pie charts as well though.


    I was curious to see if it could be done, and I'm not sure how flexible this solution is, but here's what I came up with. It's worth stepping through this code chunk line by line, stopping before each %>% pipe to see what it's generating as it goes along. This first chunk generates some data: 5 random X and Y values. Then component labels and their values are generated and bound to the Xs and Ys. Then for proof-of-concept I created an additional column that shows the sum of the components for each X-Y pair.

    require(dplyr)
    require(ggplot2)
    
    df <- data_frame(x1 = rnorm(5), y1 = rnorm(5)) %>% 
      group_by(x1, y1) %>%
      do(data_frame(component = LETTERS[1:3], value = runif(3))) %>% 
      mutate(total = sum(value)) %>% 
      group_by(x1, y1, total) 
    
    df
    

     Source: local data frame [15 x 5] Groups: x1, y1, total [5]
    
               x1         y1 component       value     total
            <dbl>      <dbl>     <chr>       <dbl>     <dbl> 
    
    1  -1.0933810  0.4162150         A 0.920992065 2.1406433 
    2  -1.0933810  0.4162150         B 0.914163390 2.1406433 
    3  -1.0933810  0.4162150         C 0.305487891 2.1406433 
    4  -0.9579912  1.4080922         A 0.006967777 0.3149009 
    5  -0.9579912  1.4080922         B 0.128341286 0.3149009 
    6  -0.9579912  1.4080922         C 0.179591852 0.3149009 
    7   0.5617438 -0.8770998         A 0.233895761 1.2324975 
    8   0.5617438 -0.8770998         B 0.942843309 1.2324975 
    9   0.5617438 -0.8770998         C 0.055758395 1.2324975 
    10  0.9970852 -0.4142704         A 0.035965092 1.4261429 
    11  0.9970852 -0.4142704         B 0.454193773 1.4261429 
    12  0.9970852 -0.4142704         C 0.935984062 1.4261429 
    13  1.2253968  0.3557304         A 0.692594728 2.1289173 
    14  1.2253968  0.3557304         B 0.972569822 2.1289173 
    15  1.2253968  0.3557304         C 0.463752786 2.1289173
    

    This chunk takes the first dataframe and for each unique x1-y1-total combination, generates a plain pie chart in a list-column called subplots. Each value in that column is a list of ggplot elements to generate a figure. Then it constructs another column that turns each of those subplots into a custom annotation in a column called subgrobs. These annotations are what can be dropped into a larger figure.

    df.grobs <- df %>% 
      do(subplots = ggplot(., aes(1, value, fill = component)) + 
           geom_col(position = "fill", alpha = 0.75, colour = "white") + 
           coord_polar(theta = "y") + 
           theme_void()+ guides(fill = F)) %>% 
      mutate(subgrobs = list(annotation_custom(ggplotGrob(subplots), 
                          x = x1-total/4, y = y1-total/4, 
                          xmax = x1+total/4, ymax = y1+total/4))) 
    
    df.grobs
    

    Source: local data frame [5 x 5]
    Groups: <by row>
    
    # A tibble: 5 × 5
              x1         y1     total subplots            subgrobs
           <dbl>      <dbl>     <dbl>   <list>              <list>
    1 -1.0933810  0.4162150 2.1406433 <S3: gg> <S3: LayerInstance>
    2 -0.9579912  1.4080922 0.3149009 <S3: gg> <S3: LayerInstance>
    3  0.5617438 -0.8770998 1.2324975 <S3: gg> <S3: LayerInstance>
    4  0.9970852 -0.4142704 1.4261429 <S3: gg> <S3: LayerInstance>
    5  1.2253968  0.3557304 2.1289173 <S3: gg> <S3: LayerInstance>
    

    Here it just takes the 5 unique x1-y1-total combinations and plots them as a regular ggplot, but then also adds in the custom annotations we made, which are sized proportional to total. Then a fake legend is constructed from the original dataframe df using blank geom_cols.

    df.grobs %>%
      {ggplot(data = ., aes(x1, y1)) +
          scale_x_continuous(expand = c(0.25, 0)) +
          scale_y_continuous(expand = c(0.25, 0)) +
          .$subgrobs + 
          geom_text(aes(label = round(total, 2))) + 
          geom_col(data = df,
                   aes(0,0, fill = component), 
                   colour = "white")}
    

    A lot of the numeric constants for adjusting the sizes and x,y scales would need to be changed by eye to fit your dataset.

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