rupsetrcomplex-upset

Manual coloring of dots by set color in Complex Upset


I would like to create an UpSet plot using the ComplexUpset package. I would like to manually color the dots in the intersection matrix to match the sets' color.

Here's what I've attempted so far:

movies <- read.csv( system.file("extdata", "movies.csv", package = "UpSetR"), header=T, sep=";" )

ComplexUpset::upset(movies, colnames(movies)[3:5], name='genre', width_ratio=0.1, 
  matrix=(intersection_matrix(geom=geom_point()) +
            scale_color_manual(values = c('Action'='red', 'Adventure'='blue', 'Children'='yellow'))), 
  queries=list(upset_query(set='Action', fill='red'),
               upset_query(set='Adventure', fill='blue'),
               upset_query(set='Children', fill='yellow')))

Output

Adding scale_color_manual only resulted in an extra legend of dots that was plotted which I do not want. I would like the dots, in the intersection matrix itself, for 'Action' to be red, the dots for 'Adventure' to be blue and the dots for 'Children' to be yellow. The segment line connecting the dots should remain black.


Solution

  • The dots don't change color because you are passing fill (not color) to upset_query; you can keep using fill if you like but in that case you need to also change the shape of the dot so that they have area to be filled, which can be done using shape='circle filled' (there are other shapes too!).

    Similarly, the scale_color_manual would not be a perfect choice in plain ggplot2, but given that it is overridden by ComplexUpset it is actually a good idea, but you will need to customize override.aes to make it display as intended.

    library(ComplexUpset)
    library(ggplot2)
    
    upset(
        movies,
        colnames(movies)[3:5],
        name='genre',
        width_ratio=0.1,
        matrix=(
            intersection_matrix(geom=geom_point(shape='circle filled', size=3))
            + scale_color_manual(
                values=c('Action'='red', 'Adventure'='blue', 'Children'='yellow'),
                guide=guide_legend(override.aes=list(shape='circle'))
            )
        ),
        queries=list(
            upset_query(set='Action', fill='red'),
            upset_query(set='Adventure', fill='blue'),
            upset_query(set='Children', fill='yellow')
        )
    )
    

    Solution with circle filled

    Alternatively, you could simply pass color in addition to fill, but I think that the fill option give nicer visuals.