rggplot2ggtern

How to plot a ternary graphic with different size point in ggtern?


I would like to make a ggtern graph that I could change the size of every point. My data has some patients which have only 1 of the 3 possible compositions. As a result, in a vertex, I have more than 1 patient information overlapped, and I don't want to jitter.

What I have so far:

library(compositions)
library(ggtern)
ds <- structure(list(`GC+` = c(1, 0, 9, 21, 2, 0, 0, 0, 4, 0, 0, 24, 
                               0, 0, 1, 0, 0, 3, 3, 0, 5, 0, 0, 3, 0, 0, 0, 2, 11, 0, 0, 18, 
                               13, 0, 6, 8, 0, 1, 0, 1, 23, 0, 1, 4, 5), `PC+` = c(5, 2, 8, 
                                                                                   0, 6, 0, 0, 0, 10, 0, 0, 20, 0, 0, 2, 0, 0, 3, 3, 0, 0, 0, 10, 
                                                                                   2, 0, 0, 0, 0, 10, 1, 0, 4, 8, 0, 1, 16, 1, 2, 0, 0, 18, 0, 0, 
                                                                                   0, 1), `OT+` = c(0, 2, 7, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 
                                                                                                    0, 2, 5, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 12, 0, 0, 6, 3, 1, 0, 
                                                                                                    6, 0, 0, 0, 0, 3, 0, 0, 3, 0), size = c(1, 1, 1, 4, 1, 0, 0, 
                                                                                                                                            0, 1, 0, 3, 1, 0, 0, 1, 0, 3, 1, 1, 0, 4, 0, 1, 1, 0, 0, 0, 1, 
                                                                                                                                            1, 2, 0, 1, 1, 3, 1, 1, 2, 1, 0, 4, 1, 0, 4, 1, 1)), row.names = c(NA, 
                                                                                                                                                                                                               45L), class = "data.frame")
d.tern <- as.data.frame(acomp(ds))
size <- apply(d.tern, 2, function(x) {
  sum(x==1)
})
ds$size <- ifelse(d.tern$`GC+` == 1, 4,
                  ifelse(d.tern$`PC+` == 1, 2,
                         ifelse(d.tern$`OT+` == 1, 3, 1)))
ds$size[is.na(ds$size)] <- 0
ggtern(data = ds, aes(`GC+`, `PC+`, `OT+`)) + 
  geom_mask() +
  geom_point(fill="red", shape=21, size = 3) + 
  theme_bw() +
  theme_showarrows() +
  theme_clockwise() +
  labs(x = "GC+", y = "PC+", z = "OT+",
       title = "Composição dos Linfonodos Positivos")

I would like to pass size from ds to geom_point. But it doesn't work.

enter image description here


Solution

  • So here is a way how to count the samples per unique value:

    tab <- as.data.frame(table(ds[,1:3]))
    
    # Keep only observed samples
    tab <- tab[tab$Freq > 0,]
    
    # Fix colnames to contain plus
    colnames(tab) <- gsub("\\.", "+", colnames(tab))
    
    # For reasons I don't understand the columns were converted to factors
    # so we'll fix them again as numeric
    tab[, 1:3] <- lapply(tab[, 1:3], as.numeric)
    

    And then the plotting would be as follows:

    ggtern(data = tab, aes(`GC+`, `PC+`, `OT+`)) + 
      geom_mask() +
      geom_point(aes(size = Freq), fill="red", shape=21) +
      scale_size_continuous(range = c(3, 5), breaks = sort(unique(tab$Freq))) +
      theme_bw() +
      theme_showarrows() +
      theme_clockwise() +
      labs(x = "GC+", y = "PC+", z = "OT+",
           title = "Composição dos Linfonodos Positivos")
    

    enter image description here

    You can play around with the scale_size_continuous() function untill you have sizes that satisfy you.