前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >迄今为止最强大的upset plot R包,没有之一!

迄今为止最强大的upset plot R包,没有之一!

作者头像
医学和生信笔记
发布2022-11-15 09:31:00
4.2K0
发布2022-11-15 09:31:00
举报
文章被收录于专栏:医学和生信笔记

upset plot我们已经介绍了多种画法,包括最流行的UpsetR,还介绍了使用complexHeatmap包画upset plot,以及ggupset包。这些包各有各的特色,基本用法差不多,在一些组合图形方面各有不同,大家可以翻看之前的文章。

今天再介绍一个画upset plot的R包(感觉有点像收集龙珠了),这个包不得了,官方宣传:具有UpsetR的所有优点,且完全支持ggplot2语法!

  • 和其他同类型R包的比较
  • 安装
  • 数据集
  • 基础使用
    • 挑选交集
    • 交集选择模式
    • 展示所有集合
  • 添加图形
  • 调整交集条形图(intersection size)
    • 调整标签外观
    • 增加颜色映射
    • 调整高度比例
    • 隐藏intersection size
    • 展示集合比例
    • 使用ggplot2继续调整

和其他同类型R包的比较

  • UpsetR:画upset plot的强大工具和先锋,但是不支持ggplot语法,且很久没更新了;
  • ggupset:支持ggplot语法,适合画一些简单的图形;
  • ComplexHeatmap:不支持ggplot2,提供超多完整的自定义选项,如果你同时需要画热图,用它!

安装

代码语言:javascript
复制
# 安装一个数据集
install.packages("ggplot2movies")

# 3选1
install.packages('ComplexUpset')

if(!require(devtools)) install.packages("devtools")
devtools::install_github("krassowski/complex-upset")

# conda/mamba安装!
# conda install -c conda-forge r-complexupset

数据集

使用的还是来自IMDB中的电影数据。

代码语言:javascript
复制
library(ggplot2)
library(ComplexUpset)

movies <- as.data.frame(ggplot2movies::movies)
head(movies, 3)
##                    title year length budget rating votes  r1   r2  r3   r4   r5
## 1                      $ 1971    121     NA    6.4   348 4.5  4.5 4.5  4.5 14.5
## 2      $1000 a Touchdown 1939     71     NA    6.0    20 0.0 14.5 4.5 24.5 14.5
## 3 $21 a Day Once a Month 1941      7     NA    8.2     5 0.0  0.0 0.0  0.0  0.0
##     r6   r7   r8   r9  r10 mpaa Action Animation Comedy Drama Documentary
## 1 24.5 24.5 14.5  4.5  4.5           0         0      1     1           0
## 2 14.5 14.5  4.5  4.5 14.5           0         0      1     0           0
## 3 24.5  0.0 44.5 24.5 24.5           0         1      0     0           0
##   Romance Short
## 1       0     0
## 2       0     0
## 3       0     1

第18-24列是电影类型,用0,1矩阵表示的。

代码语言:javascript
复制
genres <- colnames(movies)[18:24]
genres
## [1] "Action"      "Animation"   "Comedy"      "Drama"       "Documentary"
## [6] "Romance"     "Short"

mpaa这一列中的空值变成NA,然后为了方便演示去掉缺失值:

代码语言:javascript
复制
movies[movies$mpaa == "", "mpaa"] <- NA
movies <- na.omit(movies)

基础使用

最少需要提供2个参数,第一个是你的数据集,需要包含使用0,1矩阵表示的数据,第2个是需要展示的子集的名字。

代码语言:javascript
复制
upset(movies,genres,
      name = "genres", # 底部的标签
      width_ratio = 0.1 # 左侧图形的宽度
      )

plot of chunk unnamed-chunk-5

挑选交集

提供了3种方式!

可以挑选交集中的元素个数大于/小于某个值的集合展示,默认不包含没被用到的集合,可以使用keep_empty_group = T包括进来。

神奇的来了,支持拼图!

代码语言:javascript
复制
p1 <- upset(movies, genres, name = "genres",width_ratio = 0.2,
            min_size = 10,
            wrap = T
            ) +
  ggtitle("Without empty groups (Short dropped)")

p2 <- upset(movies, genres, name = "genres",width_ratio = 0.2,
            min_size = 10, # 最少10个
            max_size = 100, # 最多100个
            wrap = T,
            keep_empty_group = T
            ) +
  ggtitle("With empty groups")

p1 + p2

plot of chunk unnamed-chunk-6

或者使用min_degree/max_degree参数选择有特定交集个数的集合进行展示:

代码语言:javascript
复制
upset(movies, genres, width_ratio = 0.1,
      min_degree = 3
      )

plot of chunk unnamed-chunk-7

或者直接使用n_intersections参数指定要展示多少交集:

代码语言:javascript
复制
upset(movies, genres, width_ratio = 0.1,
      n_intersections = 15
      )

plot of chunk unnamed-chunk-8

交集选择模式

有4种交集选择模式,这4种模式很重要,在后面添加各种图形、映射不同颜色时非常有用,我觉得这部分是这个包的核心,有点难理解,需要结合给出的图形。

  • exclusive_intersection region: 选定集合的交集,但要去掉选定集合以外的集合中的元素,(简称: distinct), 默认是这一种;
  • inclusive_intersection region: 选定集合的交集 (简称: intersect);
  • exclusive_union region: 选定集合的并集,但要去掉选定集合以外的集合中的元素;
  • inclusive_union region: 选定集合的并集,(简称: union)

下面是一张图,使用3个集合,展示这4种模式:

上面这张图可以使用complexUpset画出来,只需要提供不同的交集选择模式即可,这也体现了这个包的牛逼之处,不仅可以画upset plot,也可以画传统的韦恩图:

代码语言:javascript
复制
# 先构造一个数据集用于演示
abc_data = create_upset_abc_example()
head(abc_data) # 数据集长这样
##      A     B     C
## 1 TRUE FALSE FALSE
## 2 TRUE FALSE FALSE
## 3 TRUE FALSE FALSE
## 4 TRUE FALSE FALSE
## 5 TRUE FALSE FALSE
## 6 TRUE FALSE FALSE
代码语言:javascript
复制
# 定义一个画韦恩图的函数
abc_venn = (
    ggplot(arrange_venn(abc_data)) # 这个函数可以计算韦恩图的坐标!
    + coord_fixed()
    + theme_void()
    + scale_color_venn_mix(abc_data)
)

# 画不同的交集类型
simple_venn = (
    abc_venn
    + geom_venn_region(data=abc_data, alpha=0.3)
    + geom_point(aes(x=x, y=y), size=0.75, alpha=0.3)
    + geom_venn_circle(abc_data)
    + geom_venn_label_set(abc_data, aes(label=region), outwards_adjust=2.55)
)
highlight = function(regions) scale_fill_venn_mix(
    abc_data, guide='none', highlight=regions, inactive_color='NA'
)

# 拼图
(
    (
        simple_venn + highlight(c('A-B')) + labs(title='Exclusive intersection of A and B')
        | simple_venn + highlight(c('A-B', 'A-B-C')) + labs(title='Inclusive intersection of A and B')
    ) /
    (
        simple_venn + highlight(c('A-B', 'A', 'B')) + labs(title='Exclusive union of A and B')
        | simple_venn + highlight(c('A-B', 'A-B-C', 'A', 'B', 'A-C', 'B-C')) + labs(title='Inclusive union of A and B')
    )
)

plot of chunk unnamed-chunk-10

上面是4个图形展示4种模式,也可以在同一张图中展示4种模式:

代码语言:javascript
复制
abc_venn = (
    ggplot(arrange_venn(abc_data))
    + coord_fixed()
    + theme_void()
    + scale_color_venn_mix(abc_data)
)

(
    abc_venn
    + geom_venn_region(data=abc_data, alpha=0.05)
    + geom_point(aes(x=x, y=y, color=region), size=1)
    + geom_venn_circle(abc_data)
    + geom_venn_label_set(abc_data, aes(label=region))
    + geom_venn_label_region(
        abc_data, aes(label=size),
        outwards_adjust=1.75,
        position=position_nudge(y=0.2)
    )
    + scale_fill_venn_mix(abc_data, guide='none')
)

plot of chunk unnamed-chunk-11

上面这种传统传统韦恩图不会画也不要紧,只要记住4种交集选择模型即可,毕竟韦恩图我们有更好的实现方式,不需要用complexUpset

只要记住了4种交集选择模式,就可以使用upset plot的方式来呈现了:

代码语言:javascript
复制
# 定义一个函数,可以根据4种交集选择模式画出相应的图形
abc_upset = function(mode) upset(
    abc_data, c('A', 'B', 'C'), mode=mode, set_sizes=FALSE,
    encode_sets=FALSE,
    queries=list(upset_query(intersect=c('A', 'B'), color='orange')),
    base_annotations=list(
      'Size'=( # 可以看到这里使用了ggplot2语法!
        intersection_size(
          mode=mode,
          mapping=aes(fill=exclusive_intersection),
          size=0,
          text=list(check_overlap=TRUE)
          ) + 
        scale_fill_venn_mix(
          data=abc_data,
          guide='none',
          colors=c('A'='red', 'B'='blue', 'C'='green3')
          )
        )
      )
    )

# 使用了类似patchwork的拼图方式
(
    (abc_upset('exclusive_intersection') | abc_upset('inclusive_intersection'))
    /
    (abc_upset('exclusive_union') | abc_upset('inclusive_union'))
)

plot of chunk unnamed-chunk-12

展示所有集合

展示所有集合对数据集很大时非常耗费内存!只有在模式不是exclusive intersection时才有意义。

代码语言:javascript
复制
upset(
    movies, genres,
    width_ratio=0.1,
    min_size=10,
    mode='inclusive_union',
    base_annotations=list('Size'=(intersection_size(counts=FALSE, mode='inclusive_union'))),
    intersections='all', # 展示所有集合
    max_degree=3
)

plot of chunk unnamed-chunk-13

添加图形

使用annotations参数添加其他图形。

代码语言:javascript
复制
set.seed(123)

upset(movies,genres,min_size = 10,width_ratio = 0.1,
      
      # 添加图形,提供了3种方法
      annotations = list(
        # 方法1:使用list,这里我们使用length 这一列数据
        "Length" = list(
          aes=aes(x=intersection, y=length),
          geom=geom_boxplot(na.rm = T)
        ),
        
        # 方法2:使用ggplot2,这里我们使用 rating 这一列数据
        "Rating" = (
          ggplot(mapping = aes(y = rating)) + # 默认x=intersection,省略了
            geom_violin(alpha=0.5,na.rm = T)+
            geom_jitter(aes(color=log10(votes)),na.rm = T)
        ),
        
        # 方法3:使用内置的 upset_annotate() 函数
        "Budget" = upset_annotate("budget",geom_boxplot(na.rm = T))
        
        
      )
      )

plot of chunk unnamed-chunk-14

对于分类变量,我们可以使用百分比堆积条形图展示不同的比例:

代码语言:javascript
复制
upset(
    movies,
    genres,
    annotations = list(
        'MPAA Rating'=(
            ggplot(mapping=aes(fill=mpaa))
            + geom_bar(stat='count', position='fill')
            + scale_y_continuous(labels=scales::percent_format())
            + scale_fill_manual(values=c(
                'R'='#E41A1C', 'PG'='#377EB8',
                'PG-13'='#4DAF4A', 'NC-17'='#FF7F00'
            ))
            + ylab('MPAA Rating')
        )
    ),
    width_ratio=0.1
)

image-20220516204455055

可以分别设置不同的交集模式:

代码语言:javascript
复制
set.seed(0)
upset(
    movies,
    genres,
    mode='inclusive_intersection',
    annotations = list(
        # 这里如果不指定就会使用上面设置好的模式)
        'Length (inclusive intersection)'=(
            ggplot(mapping=aes(y=length))
            + geom_jitter(alpha=0.2, na.rm=TRUE)
        ),
        'Length (exclusive intersection)'=(
            ggplot(mapping=aes(y=length))
            + geom_jitter(alpha=0.2, na.rm=TRUE)
            + upset_mode('exclusive_intersection')
        ),
        'Length (inclusive union)'=(
            ggplot(mapping=aes(y=length))
            + geom_jitter(alpha=0.2, na.rm=TRUE)
            + upset_mode('inclusive_union')
        )
    ),
    min_size=10,
    width_ratio=0.1
)

image-20220516204524064

调整交集条形图(intersection size)

图形上面的条形图(intersection size)可以被精确调整,比如颜色/标签/字体等。

调整标签外观

代码语言:javascript
复制
upset(movies,genres,min_size=10,width_ratio = 0.1,
      
      # 调整intersection size
      base_annotations = list(
        "intersection size"=intersection_size(counts = F) # 不显示个数
      )
      )

plot of chunk unnamed-chunk-17

代码语言:javascript
复制
upset(movies,genres,min_size=10,width_ratio = 0.1,
      base_annotations = list(
        "intersection size"=intersection_size(
          # 调整标签颜色和方向
          text = list(vjust=-0.1,
                      hjust=-0.1,
                      angle=45),
          text_colors = c(on_background = "brown",
                          on_bar = "yellow"
                          )
          )
        
        # 右上角添加汇总数字
        + annotate(
            geom='text', x=Inf, y=Inf,
            label=paste('Total:', nrow(movies)),
            vjust=1, hjust=1
            )
        
        # y轴标题
        + ylab('Intersection size')
        )
      )

plot of chunk unnamed-chunk-18

增加颜色映射

代码语言:javascript
复制
upset(movies,genres,width_ratio = 0.1,min_size=10,
      
      base_annotations = list(
        "intersection size" = intersection_size(
          counts = F,
          mapping = aes(fill=mpaa)
        )
      )
      )

plot of chunk unnamed-chunk-19

支持自定义颜色!

代码语言:javascript
复制
library(ggsci)

upset(movies,genres, min_size=10,width_ratio = 0.1,
      base_annotations = list(
        "intersection" = intersection_size(
          counts = F,
          mapping = aes(fill=mpaa)
        ) 
        + scale_fill_lancet() # 使用ggsci包的lancet配色
      )
      )

plot of chunk unnamed-chunk-20

如果要使用单一颜色,则要使用以下方法:

代码语言:javascript
复制
upset(movies,genres, min_size=10,width_ratio = 0.1,
      base_annotations = list(
        "intersection" = intersection_size(
          counts = F,
          mapping = aes(fill="bars_color")
        ) 
        + scale_fill_manual(values = c("bars_color"="skyblue"),guide="none")
      )
      )

plot of chunk unnamed-chunk-21

调整高度比例

使用height_ratio调整上面条形(intersection size)和下面矩阵(intersection matrix)的比例。

代码语言:javascript
复制
upset(
    movies,
    genres,
    height_ratio=1, # 1:1
    width_ratio=0.1
)

plot of chunk unnamed-chunk-22

隐藏intersection size

代码语言:javascript
复制
upset(
    movies,
    genres,
    base_annotations=list(), # 提供一个空列表
    min_size=10,
    width_ratio=0.1
)

plot of chunk unnamed-chunk-23

展示集合比例

代码语言:javascript
复制
upset(
    movies, genres, name='genre', width_ratio=0.1, min_size=10,
    base_annotations=list(
        'Intersection size'=intersection_size(),
        'Intersection ratio'=intersection_ratio() # 展示占比
    )
)

plot of chunk unnamed-chunk-24

使用ggplot2继续调整

代码语言:javascript
复制
upset(
    movies, genres, width_ratio=0.1,
    base_annotations = list(
        'Intersection size'=(
            intersection_size()
            + ylim(c(0, 700))
            + theme(plot.background=element_rect(fill='#E5D3B3'))
            + ylab('# observations in intersection')
        )
    ),
    min_size=10
)

plot of chunk unnamed-chunk-25

后面会继续介绍这个目前为止最为强大的upset plot R 包!

以上就是今天的内容,希望对你有帮助哦!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 医学和生信笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 和其他同类型R包的比较
  • 安装
  • 数据集
  • 基础使用
    • 挑选交集
      • 交集选择模式
        • 展示所有集合
        • 添加图形
        • 调整交集条形图(intersection size)
          • 调整标签外观
            • 增加颜色映射
              • 调整高度比例
                • 隐藏intersection size
                  • 展示集合比例
                    • 使用ggplot2继续调整
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档