latest news


VisCello; for visualization of single cell data.

access info ...


Sample data provenance from 1,347 RNAseq samples.

access info ...


ORNASEQ: Ontology for RNA sequencing.

access info ...


Maintained by Qin Zhu GPL-2.0-only License

Using VisCello for Single Cell Data Visualization

We developed VisCello to distribute single cell analyses and provide interactive visualizations. VisCello hosts dimensionality reductions (e.g. UMAPs), cell annotations, and marker gene tables for the different subsets of the data described in this manuscript. Users can visualize gene expression on UMAP or PCA plots, on a lineage tree diagram, or as box/violin plots grouped by cell type or lineage. The plots are interactive, allowing users to zoom in on subsets of cells, define new cell annotation groups, and run differential expression analysis and GO/KEGG enrichment with these newly defined groups. Program state can be downloaded and shared, facilitating collaboration.


      • You can install VisCello with code below:
      install.packages("devtools") # install devtools::install_github("qinzhu/VisCello") # load library(VisCello) # launch with example data cello()

    Example Datasets Preprocessed for VisCello

      • Here's an example app with data from Paul et al.(2015). It shows basic features offered by VisCello..
      • Here's another app based on VisCello for interactive exploration of C. elegans embryogenesis data: Also available as R package for download at
        • You can download an example dataset for VisCello from
        • git clone
            then in R:
              library(VisCello) cello("~/Downloads/Celegans.L2.Cello") # Change path if necessary
              • To put in your own dataset into VisCello for visualization, follow guidance below.

            General Data Requirement

              • VisCello requires two main data object - an ExpressionSet object and a Cello object (or list of Cello objects), plus one configuration file. All 3 files must be put inside the same data folder. Each data folder represent one particular study.
                • ExpressionSet object - The ExpressionSet object is a general class from Bioconductor.
                • Cello object - The Cello object is an S4 class specifically designed for visualizing subsets of the single cell data - by storing dimension reduction results of (subsets of) cells that are present in the global ExpressionSet, and any local meta information about the cells, such as clustering results.
                • Lastly, a simple configuration file needs to be editted by user to let VisCello know general information about this study.
              • An example can be downloaded here . This vignette will describe the preprocessing step fsubset_GSE72857_log2norm.txt: Log2 normalized expression matrix, same dimension as raw matrix. You can also input any other type of normalized data as long as it matches the dimension of raw data.or inputing data into VisCello.
              • library(PIVOT) pivot()

            Prepare ExpressionSet object

              • The data-raw folder contains an example dataset and associated meta information from Paul et al. (2015). The files in the folder are:
                • subset_GSE72857.txt Raw gene expression matrix, with column as cells and rows as genes, rownames must be unique.
                • subset_GSE72857_log2norm.txt Log2 normalized expression matrix, same dimension as raw matrix. You can also input any other type of normalized data as long as it matches the dimension of raw data.
                • subset_GSE72857_pmeta.txt Meta data for the cells.
              • Load the data into R and convert them into ExpressionSet using the following code: library(Matrix) library(Biobase) raw_df <- read.table("data-raw/GSE72857_raw.txt") norm_df <- read.table("data-raw/GSE72857_log2norm.txt") pmeta <- read.table("data-raw/GSE72857_pmeta.txt") fmeta <- read.table("data-raw/GSE72857_fmeta.txt") # Feature meta MUST have rownames the same as the rownames of expression matrix - this can be gene name or gene id (but must not have duplicates). rownames(fmeta) <- fmeta$id eset <- new("ExpressionSet", assayData = assayDataNew("environment", exprs=Matrix(as.matrix(raw_df), sparse = T), norm_exprs = Matrix(as.matrix(norm_df), sparse = T)), phenoData = new("AnnotatedDataFrame", data = pmeta), featureData = new("AnnotatedDataFrame", data =fmeta))
                • A few additional work needs to be done here: some columns in pmeta, such as cell state should be treated as factors rather than numeric values.
                    factor_cols <- c("Mouse_ID", "cluster", "State") for(c in factor_cols) { pData(eset)[[c]] <- factor(pData(eset)[[c]]) } saveRDS(eset, "your_data_folder/eset.rds")
                  • Now the expression data and meta information required by VisCello is in place.

                [Alternative] Convert common objects to ExpressionSet

                  • Seurat object fmeta <- data.frame(symbol = rownames(seurat@data)) # Seurat does not seem to store feature meta data as of version 3.0 rownames(fmeta) <- fmeta$symbol eset <- new("ExpressionSet", assayData = assayDataNew("environment", exprs=Matrix(as.matrix(, sparse = T), norm_exprs = Matrix(as.matrix(seurat@data), sparse = T)), phenoData = new("AnnotatedDataFrame", data =, featureData = new("AnnotatedDataFrame", data = fmeta))
                  • Monocle object
                    fmeta <- fData(cds) fmeta[[1]] <- fmeta$gene_short_name # Make first column gene name eset <- new("ExpressionSet", assayData = assayDataNew("environment", exprs=Matrix(as.matrix(exprs(cds)), sparse = T), norm_exprs = Matrix(log2(Matrix::t(Matrix::t(FM)/sizeFactors(cds))+1), sparse = T)), # Note this is equivalent to 'log' normalization method in monocle, you can use other normalization function phenoData = new("AnnotatedDataFrame", data = pData(cds)), featureData = new("AnnotatedDataFrame", data = fmeta))
                  • SingleCellExperiment/SummarizedExperiment object
                    fmeta <- rowData(sce) # if rowData empty, you need to make a new fmeta with rownames of matrix: fmeta <- data.frame(symbol = rownames(sce)); rownames(fmeta) <- fmeta[[1]] fmeta[[1]] <- fmeta$symbol # Make sure first column is gene name eset <- new("ExpressionSet", assayData = assayDataNew("environment", exprs=Matrix(sce@assays$data$counts, sparse = T), # Change 'counts' to raw count matrix norm_exprs = Matrix(sce@assays$data$norm_counts, sparse = T)), # Change 'norm_counts' to raw count matrix phenoData = new("AnnotatedDataFrame", data = colData(sce)), featureData = new("AnnotatedDataFrame", data = fmeta))

                Prepare Cello Object

                  • Cello object allows embedding of multiple dimension reduction results for different subsets of cells. This allows "zoom-in" analysis on subset of cells as well as differential expression analysis on locally defined clusters. The basic structure of Cello is as follows:
                    • name Name of the cell subset
                    • idx : The index of the cell subset in global expression set.
                    • proj : Named list of projections such as PCA, t-SNE and UMAP.
                    • pmeta : (Optional) local meta data containing the meta data that's specific to this local cell subset. For example, in global meta data, only one "Cluster" column is allowed. But what if you have different clustering results for different cell subsets? You can store this subset-dependent result inside the local pmeta slot of cello.
                    • notes : (Optional) information about the cell subset to display to the user
                  • Create Cello for VisCello, note at least one dimension reduction result must be computed and put in cello@proj: library(irlba) library(VisCello) # Creating a cello for all the cells cello <- new("Cello", name = "Global dataset", idx = 1:ncol(eset)) # Index is basically the column index, here all cells are included # Code for computing dimension reduction, not all of them is necessary, and you can input your own dimension reduction result into the cello@proj list. # It is also recommended that you first filter your matrix to remove low expression genes and cells, and input a matrix with variably expressed genes cello <- compute_pca_cello(eset, cello, num_dim = 50) # Compute PCA cello <- compute_tsne_cello(eset, cello, use_dim = 30, n_component = 2, perplexity = 30) # Compute t-SNE cello <- compute_umap_cello(eset, cello, use_dim = 30, n_component = 2) # Compute UMAP, need reticulate and UMAP (python package) to be installed cello <- compute_umap_cello(eset, cello, use_dim = 30, n_component = 3) # 3D UMAP
                  • If you already computed your dimension reduction result and wants to make a cello for it, use following R code: cello <- new("Cello", name = "My cell subset", idx = cell_index) # cell_index is which cells from ExpressionSet are used for the dimension reduction my_tsne_proj <- read.table("path_to_tsne_projection") my_umap_proj <- read.table("path_to_umap_projection") # You can put in as many dimension reduction result as you want cello@proj <- list("My t-SNE [2D]" = my_tsne_proj, "My UMAP [3D]" = my_umap_proj) # Put a 2D or 3D in the name to tell VisCello if you want to visualize this as a 2D plot or as a 3D rotatable plot, if 2D there must be 2 columns for each dimension, if 3D there must be 3 columns.
                  • Create a list to store Cello objects and save to data location. clist <- list() clist[["Global dataset"]] <- cello saveRDS(clist, "inst/app/data/clist.rds")
                  • You can create multiple Cello hosting visualization information of different subsets of the cells. Say people want to zoom in onto GMP for further analysis: zoom_type <- "GMP" cur_idx <- which(eset$cell_type == zoom_type) cello <- new("Cello", name = zoom_type, idx = cur_idx) # Refilter gene by variation if necessary cello <- compute_pca_cello(eset[,cur_idx], cello, num_dim = 50) # Compute PCA cello <- compute_tsne_cello(eset[,cur_idx], cello, use_dim = 15, n_component = 2, perplexity = 30) # Compute t-SNE cello <- compute_umap_cello(eset[,cur_idx], cello, use_dim = 15, n_component = 2) # Compute UMAP cello <- compute_umap_cello(eset[,cur_idx], cello, use_dim = 15, n_component = 3) # 3D UMAP clist[[zoom_type]] <- cello saveRDS(clist, "your_data_folder/clist.rds")
                  • Now all the data required to run cello has been preprocessed.

                Prepare Configure File and Launch

                  • Download example configure file here
                    • study_name Appear as title for the app.
                    • study_description : Appear as footer for the app.
                    • organism : support mouse, human and c. elegans.
                    • feature_name_column : important! What's the column name of fData(eset) that corresponds to gene symbol, must be specified.
                    • feature_id_column : What's the column name of fData(eset) that corresponds to gene id, set same as feature_name_column if you don't have gene id.
                  • After updating this file, put it together with previously saved eset.rds and clist.rds
                  • Now VisCello is ready to go! To launch Viscello, in R:
                  • library(VisCello) cello(data_path = "your_data_folder")

                Host VisCello on a Server

                  • To host VisCello on a server, you need to use either a ShinyServer ( or use the service (
                    • STEP 1: Install VisCello from github
                    install_github("qinzhu/VisCello") # STEP 1
                    • STEP 2 [IMPORTANT]: Git clone VisCello from github, replace inst/app/data/eset.rds, inst/app/data/clist.rds, inst/app/data/config.yml with your own data.
                    • ALSO, change first line in inst/app/global.R from viscello_DEPLOY = F to viscello_DEPLOY = T.
                    • STEP 3: Set the repositories to bioconductor in R, and then only deploy the inst/app/ folder that contains your own data.
                    options(repos = BiocManager::repositories()) rsconnect::deployApp("inst/app/", account = "cello", appName = "base") # change account to your own account, change app name to your own app name.
                  • Please cite VisCello properly if you use VisCello to host your dataset.

                Cite VisCello

                  • Q. Zhu, J. I. Murray, K. Tan, J. Kim, qinzhu/VisCello: VisCello v1.0.0 (2019;
                  • For specific analysis, please check the citation listed in the module.


                  • Paul, Franziska, Ya'ara Arkin, Amir Giladi, Diego Adhemar Jaitin, Ephraim Kenigsberg, Hadas Keren-Shaul, Deborah Winter, et al. 2015. “Transcriptional Heterogeneity and Lineage Commitment in Myeloid Progenitors.” Cell 163 (7). Elsevier: 1633-77.
                  • Cao, Junyue, et al. Comprehensive single-cell transcriptional profiling of a multicellular organism. Science 357.6352 (2017): 661-667.