1 Introduction

Cell type annotation is a fundamental step in single-cell RNA-seq analysis, for both smaller datasets as well as for atlas-sized efforts (Hemberg et al. 2025). While many automated approaches exist (Traversa and Chiara 2025), manual annotation is still seen as an ubiquitous step to ensure the best identities are assigned (Andrews et al. 2020). After dimensionality reduction and clustering, analysts need to visually inspect groups of cells, correlate them with known marker genes, and ultimately assign meaningful biological labels. This is a process that often times is very labor-intensive, as it typically involves several rounds of back-and-forth between the visualization(s) and the data.

iSEEid extends the iSEE framework (Rue-Albrecht et al. 2018) with a dedicated Sample Identification Center panel. This panel receives a cell selection transmitted from any other panel (e.g. a brush on a ReducedDimensionPlot) and immediately generates ready-to-use R code to assign a cell type label to those cells — including the colData column to write into, the label to assign, and an optional rationale comment for provenance tracking.

The generated command can be copied directly into a script or notebook, making iSEEid a natural companion for interactive annotation workflows.

A place to check out what belongs to the iSEE “core functionality” would be the iSEE organization website (https://isee.github.io/) and the “Extending iSEE” book (https://isee.github.io/iSEE-book/).
This package has been conceived and developed as a corollary to the iSEE workshop delivered in Oxford in 2024, for which we also have put together a resource documenting what is needed to write iSEE extensions (https://isee.github.io/iSEEDemoEuroBioC2024/articles/workshop_isee_extension.html).

2 Installation

iSEEid can be installed from Bioconductor with the following code:

if(!requireNamespace('BiocManager', quietly = TRUE))
  install.packages('BiocManager')

BiocManager::install("iSEEid")

Load the package after installation with

library("iSEEid")

3 Demonstrating the usage of iSEEid

3.1 Setting up example data

We use the Allen Brain Atlas dataset from scRNAseq as a running example, pre-processed with scater.

library("iSEE")
library("iSEEid")
library("scRNAseq")
library("scater")
#> Loading required package: scuttle
#> Loading required package: ggplot2
library("scrapper")
#> 
#> Attaching package: 'scrapper'
#> The following objects are masked from 'package:scater':
#> 
#>     aggregateAcrossCells, normalizeCounts
#> The following objects are masked from 'package:scuttle':
#> 
#>     aggregateAcrossCells, normalizeCounts

sce <- ReprocessedAllenData(assays = "tophat_counts")
sce <- normalizeRnaCounts.se(sce, assay.type = "tophat_counts", size.factors = NULL)
sce <- runPCA(sce, ncomponents = 4)
sce <- runTSNE(sce)

colData(sce)["cell_type"] <- "unassigned"

3.2 Launching the app

A minimal setup pairs a ReducedDimensionPlot with a SampleIdentificationCenter - this is possible in a scripted manner via the initial parameter. The ColumnSelectionSource argument wires these two panels together from the start, so any brush or lasso drawn on the plot can be immediately reflected in the annotation panel.

iSEE(sce, initial = list(
  ReducedDimensionPlot(
    PanelWidth = 6L
  ),
  SampleIdentificationCenter(
    ColumnSelectionSource = "ReducedDimensionPlot1",
    PanelWidth = 6L
  )
))

4 The SampleIdentificationCenter panel

The panel consists of two parts:

  • a Text editor (top) showing either a ready-to-run R command or a plain list of cell IDs, updated live as the upstream selection changes;
  • a Data parameters box (bottom) with controls to customize what the editor produces, whereas the Selection paramters box allows to change the source e.g. for the column selection.
A basic configuration for using iSEEid.

Figure 1: A basic configuration for using iSEEid

Among the essential data parameters, we have:

  • A checkbox, to show the full, executable R command, or alternatively the plain text form of the selected cells. It can have this form, generally:
## This is your SummarizedExperiment object
# se

## In this slot you store your annotation e.g. your cell label
# colData(se)[['cell_type']]

## To rename the selected cells to their new label, you can use the command(s) below

## Rationale: high Cd3e / Cd4 expression
colData(se)[
  c('cell_A',
    'cell_B',
    ...
  ), 'cell_type'] <- 'CD4+ T cells'

When unchecked, the editor switches to a plain list of cell IDs - this can be useful when you just need the names to pass to another tool or paste into a spreadsheet (you still probably should not use Excel for this…).

  • The Annotation rationale: this is a free-text field to record why you are making this assignment — e.g. high Cd3e / Cd4 expression. When non-empty, the text is injected as a ## Rationale: comment immediately above the assignment command, providing lightweight provenance directly inside the generated code.

  • The colData column to be used for annotation: The name of the colData column where labels should be stored. This column must already exist in your object. Defaults to cell_type.

  • The Cell type label, i.e. the label to assign to the selected cells, which becomes the right-hand side of the assignment (when generating the commands). This defaults to new_cell_type, but you can easily replace it with the actual label before copying the command — e.g. CD4+ T cells, Microglia, Monocytes.

5 How to perform annotation within iSEEid

A typical session with iSEEid looks like this:

  1. Open iSEE with a ReducedDimensionPlot linked to a SampleIdentificationCenter.
  2. Brush or lasso a group of cells that cluster together in the reduced dimension plot.
  3. Optionally inspect the selected cells in other linked panels — e.g. a FeatureAssayPlot to check marker gene expression, or a ColumnDataTable to browse their metadata.
  4. In the SampleIdentificationCenter, fill in the colData column, the cell type label, and optionally a rationale.
  5. Copy the generated command from the editor into your analysis script or notebook and run it to write the annotation back into the object.
  6. Rinse and repeat for each cell population of interest.

Because the command is generated fresh on every selection change, you can iterate at will — refine the brush, update the label, copy again — without any risk of accidentally overwriting prior annotations already committed to the object.

An important note: iSEE does not execute these commands for you - nor changes silently the provided object. This is a clear design choice!

6 Customizing the initial state for efficient annotation

All panel slots can be set at construction time, allowing you to pre-fill sensible defaults for your dataset:

iSEE(sce, initial = list(
  ReducedDimensionPlot(
    PanelWidth = 3L,
    Type = "TSNE",
    ColorBy = "Feature name",
    ColorByFeatureSource = "RowDataTable1"
  ),
  SampleIdentificationCenter(
    ColumnSelectionSource = "ReducedDimensionPlot1",
    PanelWidth = 3L,
    ColDataColumn = "labels_from_automated_tool",
    CellTypeLabel = "new_cell_type",
    AnnotationRationale = "refined round: looking explicitly for markers"
  ),
  FeatureAssayPlot(
    PanelWidth = 3L,
    XAxis = "Column data", 
    XAxisColumnData = "Primary.Type",
    YAxisFeatureSource = "RowDataTable1"
  ),
  RowDataTable(
    PanelWidth = 3L,
    Selected = "Foxp2", 
    Search = "Fox"
  )
))
A somewhat more complex example of iSEEid in action, with some extra panels.

Figure 2: A somewhat more complex example of iSEEid in action, with some extra panels

Of course, more complex configurations are also possible - if not even required, in complex datasets. For these cases, we suggest the users to create a panel configuration by hand, directly within iSEE, and export that afterwards with its native functionality.

Session info

sessionInfo()
#> R version 4.6.0 RC (2026-04-17 r89917)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 24.04.4 LTS
#> 
#> Matrix products: default
#> BLAS:   /home/biocbuild/bbs-3.24-bioc/R/lib/libRblas.so 
#> LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.12.0  LAPACK version 3.12.0
#> 
#> locale:
#>  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
#>  [3] LC_TIME=en_GB              LC_COLLATE=C              
#>  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
#>  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
#>  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
#> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
#> 
#> time zone: America/New_York
#> tzcode source: system (glibc)
#> 
#> attached base packages:
#> [1] stats4    stats     graphics  grDevices utils     datasets  methods  
#> [8] base     
#> 
#> other attached packages:
#>  [1] scrapper_1.7.3              scater_1.41.1              
#>  [3] ggplot2_4.0.3               scuttle_1.23.1             
#>  [5] scRNAseq_2.27.0             iSEEid_0.99.1              
#>  [7] iSEE_2.25.0                 SingleCellExperiment_1.35.1
#>  [9] SummarizedExperiment_1.43.0 Biobase_2.73.1             
#> [11] GenomicRanges_1.65.0        Seqinfo_1.3.0              
#> [13] IRanges_2.47.2              S4Vectors_0.51.3           
#> [15] BiocGenerics_0.59.7         generics_0.1.4             
#> [17] MatrixGenerics_1.25.0       matrixStats_1.5.0          
#> [19] BiocStyle_2.41.0           
#> 
#> loaded via a namespace (and not attached):
#>   [1] splines_4.6.0            later_1.4.8              BiocIO_1.23.3           
#>   [4] bitops_1.0-9             filelock_1.0.3           tibble_3.3.1            
#>   [7] XML_3.99-0.23            lifecycle_1.0.5          httr2_1.2.2             
#>  [10] doParallel_1.0.17        lattice_0.22-9           ensembldb_2.37.3        
#>  [13] alabaster.base_1.13.0    magrittr_2.0.5           sass_0.4.10             
#>  [16] rmarkdown_2.31           jquerylib_0.1.4          yaml_2.3.12             
#>  [19] httpuv_1.6.17            otel_0.2.0               DBI_1.3.0               
#>  [22] RColorBrewer_1.1-3       abind_1.4-8              Rtsne_0.17              
#>  [25] AnnotationFilter_1.37.0  RCurl_1.98-1.19          rappdirs_0.3.4          
#>  [28] circlize_0.4.18          ggrepel_0.9.8            irlba_2.3.7             
#>  [31] alabaster.sce_1.13.0     codetools_0.2-20         DelayedArray_0.39.3     
#>  [34] DT_0.34.0                tidyselect_1.2.1         shape_1.4.6.1           
#>  [37] UCSC.utils_1.9.0         farver_2.1.2             viridis_0.6.5           
#>  [40] ScaledMatrix_1.21.0      shinyWidgets_0.9.1       BiocFileCache_3.3.0     
#>  [43] GenomicAlignments_1.49.0 jsonlite_2.0.0           GetoptLong_1.1.1        
#>  [46] BiocNeighbors_2.7.2      iterators_1.0.14         foreach_1.5.2           
#>  [49] tools_4.6.0              Rcpp_1.1.1-1.1           glue_1.8.1              
#>  [52] gridExtra_2.3            SparseArray_1.13.2       BiocBaseUtils_1.15.1    
#>  [55] xfun_0.58                mgcv_1.9-4               GenomeInfoDb_1.49.1     
#>  [58] dplyr_1.2.1              HDF5Array_1.41.0         gypsum_1.9.0            
#>  [61] shinydashboard_0.7.3     withr_3.0.2              BiocManager_1.30.27     
#>  [64] fastmap_1.2.0            rhdf5filters_1.25.0      shinyjs_2.1.1           
#>  [67] digest_0.6.39            rsvd_1.0.5               R6_2.6.1                
#>  [70] mime_0.13                colorspace_2.1-2         listviewer_4.0.0        
#>  [73] dichromat_2.0-0.1        RSQLite_3.53.1           cigarillo_1.3.0         
#>  [76] h5mread_1.5.0            rtracklayer_1.73.0       httr_1.4.8              
#>  [79] htmlwidgets_1.6.4        S4Arrays_1.13.0          pkgconfig_2.0.3         
#>  [82] gtable_0.3.6             blob_1.3.0               ComplexHeatmap_2.29.0   
#>  [85] S7_0.2.2                 XVector_0.53.0           htmltools_0.5.9         
#>  [88] bookdown_0.47            ProtGenerics_1.45.0      rintrojs_0.3.4          
#>  [91] clue_0.3-68              scales_1.4.0             alabaster.matrix_1.13.0 
#>  [94] png_0.1-9                knitr_1.51               rjson_0.2.23            
#>  [97] nlme_3.1-169             curl_7.1.0               shinyAce_0.4.4          
#> [100] cachem_1.1.0             rhdf5_2.57.1             GlobalOptions_0.1.4     
#> [103] BiocVersion_3.24.0       parallel_4.6.0           miniUI_0.1.2            
#> [106] vipor_0.4.7              AnnotationDbi_1.75.0     restfulr_0.0.17         
#> [109] pillar_1.11.1            grid_4.6.0               alabaster.schemas_1.13.0
#> [112] vctrs_0.7.3              promises_1.5.0           BiocSingular_1.29.0     
#> [115] dbplyr_2.5.2             beachmat_2.29.0          xtable_1.8-8            
#> [118] cluster_2.1.8.2          beeswarm_0.4.0           evaluate_1.0.5          
#> [121] GenomicFeatures_1.65.0   cli_3.6.6                compiler_4.6.0          
#> [124] Rsamtools_2.29.0         rlang_1.2.0              crayon_1.5.3            
#> [127] ggbeeswarm_0.7.3         viridisLite_0.4.3        alabaster.se_1.13.0     
#> [130] BiocParallel_1.47.0      Biostrings_2.81.3        lazyeval_0.2.3          
#> [133] colourpicker_1.3.0       Matrix_1.7-5             ExperimentHub_3.3.1     
#> [136] bit64_4.8.2              Rhdf5lib_2.1.0           KEGGREST_1.53.1         
#> [139] shiny_1.13.0             alabaster.ranges_1.13.0  AnnotationHub_4.3.1     
#> [142] igraph_2.3.2             memoise_2.0.1            bslib_0.11.0            
#> [145] bit_4.6.0

Bibliography

Andrews, Tallulah S., Vladimir Yu Kiselev, Davis McCarthy, and Martin Hemberg. 2020. “Tutorial: Guidelines for the Computational Analysis of Single-Cell Rna Sequencing Data.” Nature Protocols 16 (1): 1–9. https://doi.org/10.1038/s41596-020-00409-w.

Hemberg, Martin, Federico Marini, Shila Ghazanfar, Ahmad Al Ajami, Najla Abassi, Benedict Anchang, Bérénice A. Benayoun, et al. 2025. “Insights, Opportunities, and Challenges Provided by Large Cell Atlases.” Genome Biology 26 (1). https://doi.org/10.1186/s13059-025-03771-8.

Rue-Albrecht, K., F. Marini, C. Soneson, and A. T. L. Lun. 2018. “ISEE: Interactive Summarizedexperiment Explorer.” F1000Research 7 (June): 741.

Traversa, Daniele, and Matteo Chiara. 2025. “Mapping Cell Identity from scRNA-Seq: A Primer on Computational Methods.” Computational and Structural Biotechnology Journal 27 (January): 1559–69. https://doi.org/10.1016/j.csbj.2025.03.051.