Seurat Weekly NO.08 || Seurat 交互系统

数据可视化是数据分析中关键的一步,相比于静态绘图,交互(界面)图可以给我们更多的调节空间。单细胞数据分析中往往需要用不同的参数来可视化细胞图谱或者基因表达特征,所以Seurat中有相关的交互绘图功能。而随着单细胞技术的普及,很多更开始接触编程或者没有接触过编程的朋友也开始有了分析单细胞数据需求,于是有了SeuratV3Wizard这样的完全交互的Seurat平台。在Seurat V4 版本中,也官方地提出了其交互平台(Shiny app):azimuth并且内置了PBMC的参考数据集,可以在线分析和注释。本期Seurat weekly 就和大家探索一下Seurat 的交互系统。

在Seurat中交互的参数一般是interactive,我们需要找到哪些函数有这个参数。思考:如何查一个R包中哪些函数有某一参数?

先载入R包和数据,并执行简单的降维。

library(Seurat)
packageVersion('Seurat')
[1] ‘3.2.2’
library(SeuratData)
library(tidyverse)
head(stxBrain.SeuratData::anterior1@meta.data)
                   orig.ident nCount_Spatial nFeature_Spatial slice   region
AAACAAGTATCTCCCA-1  anterior1          13069             4242     1 anterior
AAACACCAATAACTGC-1  anterior1          37448             7860     1 anterior
AAACAGAGCGACTCCT-1  anterior1          28475             6332     1 anterior
AAACAGCTTTCAGAAG-1  anterior1          39718             7957     1 anterior
AAACAGGGTCTATATT-1  anterior1          33392             7791     1 anterior
AAACATGGTGAGAGGA-1  anterior1          20955             6291     1 anterior
# Loading required package: shiny


stxBrain.SeuratData::anterior1 %>% NormalizeData() %>% FindVariableFeatures() %>% ScaleData() %>% RunPCA() -> anterior1

我们发现有这个参数的函数有:

  • FeaturePlot
  • IFeaturePlot
  • SpatialDimPlot
  • SpatialFeaturePlot
  • ISpatialFeaturePlot
  • ISpatialDimPlot

我们看到它们是配对的,演示几个先:

FeaturePlot(anterior1,feature= "Cd4",interactive = T)
Listening on http://127.0.0.1:6388

那我们肯定想知道它是如何实现的了,我们选择用debug的方式来查看原函数:

debug(FeaturePlot)
FeaturePlot(anterior1,feature= "Cd4",interactive = T)

函数太长,我们只看其中和交互有关的地方。

 ui <- miniPage(miniButtonBlock(miniTitleBarButton(inputId = "done", 
    label = "Done", primary = TRUE)), miniContentPanel(fillRow(sidebarPanel(selectInput(inputId = "assay", 
    label = "Assay", choices = assays.use, selected = assay, 
    selectize = FALSE, width = "100%"), selectInput(inputId = "feature", 
    label = feature.label, choices = features, selected = feature, 
    selectize = FALSE, width = "100%"), selectInput(inputId = "reduction", 
    label = "Dimensional reduction", choices = Reductions(object = object), 
    selected = reduction, selectize = FALSE, width = "100%"), 
    selectInput(inputId = "xdim", label = "X dimension", 
      choices = dims.reduc, selected = as.character(x = dims[1]), 
      selectize = FALSE, width = "100%"), selectInput(inputId = "ydim", 
      label = "Y dimension", choices = dims.reduc, selected = as.character(x = dims[2]), 
      selectize = FALSE, width = "100%"), selectInput(inputId = "palette", 
      label = "Color scheme", choices = names(x = FeaturePalettes), 
      selected = "Seurat", selectize = FALSE, width = "100%"), 
    width = "100%"), plotOutput(outputId = "plot", height = "100%"), 
    flex = c(1, 4))))
  dims <- paste0(Key(object = object[[reduction]]), dims)
  plot.data <- FetchData(object = object, vars = c(dims, feature), 
    slot = slot)
  server <- function(input, output, session) {
    plot.env <- reactiveValues(data = plot.data, dims = paste0(Key(object = object[[reduction]]), 
      dims), feature = feature, palette = "Seurat")
    observeEvent(eventExpr = input$done, handlerExpr = stopApp(returnValue = plot.env$plot))
    observe(x = {
      assay <- input$assay
      feature.use <- input$feature
      features.assay <- sort(x = rownames(x = GetAssayData(object = object, 
        slot = slot, assay = assay)))
      feature.use <- ifelse(test = feature.use %in% features.assay, 
        yes = feature.use, no = features.assay[1])
      reduc <- input$reduction
      dims.reduc <- gsub(pattern = Key(object = object[[reduc]]), 
        replacement = "", x = colnames(x = object[[reduc]]))
      dims <- c(input$xdim, input$ydim)
      for (i in seq_along(along.with = dims)) {
        if (!dims[i] %in% dims.reduc) {
          dims[i] <- dims.reduc[i]
        }
      }
      updateSelectInput(session = session, inputId = "xdim", 
        label = "X dimension", choices = dims.reduc, 
        selected = as.character(x = dims[1]))
      updateSelectInput(session = session, inputId = "ydim", 
        label = "Y dimension", choices = dims.reduc, 
        selected = as.character(x = dims[2]))
      updateSelectInput(session = session, inputId = "feature", 
        label = feature.label, choices = features.assay, 
        selected = feature.use)
    })

可以看出是用miniUI来实现的。miniUI提供了一个UI小部件,用于在R命令行中集成交互式应用程序。开发比较小的,或作为辅助功能的Shiny,miniUI是比较实用的,而且还支持多种展示形式,如下:

除了内置的交互形式之外,也有热心的Seurat开发了在线版的Seurat: SeuratV3Wizard,它旨在为研究人员提供一个直观的界面,让他们可以轻松地交互上传、分析、可视化和探索单细胞RNA-seq数据,而无需事先掌握R方面的编程知识。

地址:http://nasqar.abudhabi.nyu.edu/SeuratV3Wizard/

可以完成SeuratV3基本功能的线上分析,上传数据就可以直接点点点分析了,很方便:

更上一层楼的是Seurat V4 的azimuth ,不仅可以完成在线的基本分析还可以多PBMC做基于WNN的细胞类型注释,同时在效率上也得到了提升,可以一次性在线分析更多的细胞(小于100,000 cells , 基本满足一般的研究型图谱数据分析的要求了)。风格很Seurat,有详细的教程和贴心的FAQ。

地址: https://satijalab.org/azimuth/

教程区:

除了直接在线分析也可以在自己的R中安装azimuth 包,以方便本地使用。

if (!requireNamespace('remotes', quietly = TRUE) {
  install.packages('remotes')
}
remotes::install_github('satijalab/azimuth', ref = 'master')

Azimuth::AzimuthApp()

其实有了Seurat之后用Shiny包装它并不是复杂,如Azimuth的源码,shiny完成的是对Seurat包的调用程序。

界面版和命令行版针对的是不同条件的选择,看自己的实验室的编程条件和人员背景来选择。但是做单细胞数据分析迟早都要会R语言。

https://hiplot.com.cn/advance/shinyseurat
http://nasqar.abudhabi.nyu.edu/SeuratV3Wizard/
https://satijalab.org/azimuth/
https://github.com/satijalab/azimuth
https://rdrr.io/cran/miniUI/

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容