Search code examples
rmatrixggplot2diagram

Kite Diagram in R


I am trying to re-create a kite diagram showing the distribution of the most abundant macroalgal species.

My data is below:

Here: dput(p2[1:3, 1:5])

structure(c(25.04240506, 24.95759494, 24.04113924, 25.0164557, 
24.9835443, 24.04905063, 25.00379747, 24.99620253, 24.03955696, 
25.01677215, 24.98322785, 24.01740506, 25.00474684, 24.99525316, 
24.03955696), .Dim = c(3L, 5L), .Dimnames = list(c("Sphacelaria tribuloides(O)", 
"Amphiroa rigida (R)", "Stypocaulon scoparium (O)"), c("A1", 
"A2", "A3", "B1", "B2")))

Current output:

[![This is what my plot looks like][1]][1]

Goal:

[![This is what my kite diagram should look like][2]][2]

I am truly not sure what I am doing wrong and or how to go about fixing it.

Thank you very much for your help and guidance in advance. I greatly appreciate it.


Solution

  • NB: I change values of your example, in order to get more variations as all your values were all between 24 or 25 which explain why you get almost horizontal bar in your kite Diagram. I did:

    df[1:3,1:5] <- sample(5:25, 15, replace = TRUE)
    
                               A1 A2 A3 B1 B2
    Sphacelaria tribuloides(O)  9 18 20  5 17
    Amphiroa rigida (R)         6 18 24 18 18
    Stypocaulon scoparium (O)  16 18 16 19  8
    

    To get a kite diagram, you can simply use kiteChart function from plotrix diagram.

    library(plotrix)
    kiteChart(df)
    

    enter image description here

    I did not find a way to rotate y labels as it seems that yaxt = "n" and las = 1 don't work on this function. So, I try to find a way using ggplot2.

    A possible way is to first shape your dataframe and convert y and x axis in an numerical format by attributing the level of their factor format. You also need to normalise the "value" column:

    library(dplyr)
    library(tidyr)
    DF <- as.data.frame(df) %>% mutate(species = rownames(df)) %>%
      pivot_longer(-species, names_to = "X_var", values_to = "values") %>%
      mutate(species = factor(species, levels = unique(species))) %>%
      mutate(X_var = factor(X_var, levels = unique(X_var))) %>%
      mutate(NewY = as.numeric(species)*2) %>%
      mutate(normval = values / max(values))  %>%
      mutate(NewX = as.numeric(X_var))  
    
    # A tibble: 15 x 6
       species                    X_var values  NewY normval  NewX
       <fct>                      <fct>  <dbl> <dbl>   <dbl> <dbl>
     1 Sphacelaria tribuloides(O) A1         9     2   0.375     1
     2 Sphacelaria tribuloides(O) A2        18     2   0.75      2
     3 Sphacelaria tribuloides(O) A3        20     2   0.833     3
     4 Sphacelaria tribuloides(O) B1         5     2   0.208     4
     5 Sphacelaria tribuloides(O) B2        17     2   0.708     5
     6 Amphiroa rigida (R)        A1         6     4   0.25      1
     7 Amphiroa rigida (R)        A2        18     4   0.75      2
     8 Amphiroa rigida (R)        A3        24     4   1         3
     9 Amphiroa rigida (R)        B1        18     4   0.75      4
    10 Amphiroa rigida (R)        B2        18     4   0.75      5
    11 Stypocaulon scoparium (O)  A1        16     6   0.667     1
    12 Stypocaulon scoparium (O)  A2        18     6   0.75      2
    13 Stypocaulon scoparium (O)  A3        16     6   0.667     3
    14 Stypocaulon scoparium (O)  B1        19     6   0.792     4
    15 Stypocaulon scoparium (O)  B2         8     6   0.333     5
    

    Now, you can use geom_ribbon to get your kite diagram:

    library(ggplot2)
    ggplot(DF, aes(x = NewX, fill = species))+
      geom_ribbon(aes(ymin = NewY-normval, ymax = NewY+normval))+
      scale_y_continuous(breaks = unique(DF$NewY), labels = levels(DF$species))+
      scale_x_continuous(breaks = unique(DF$NewX), labels = levels(DF$X_var), name = "")
    

    enter image description here Is it what you are looking for ?