Getting started with geneticUMAP

What geneticUMAP Does

Single-cell RNA sequencing (scRNA-seq) enables the characterization of cellular heterogeneity at single-cell resolution,but its interpretation relies on computational workflows for dimensionality reduction and visualization. These workflows require multiple parameter choices in preprocessing, clustering, and visualization steps. Although general recommendations exist, suitable parameter selection remains dataset-specific, leaving manual configuration susceptible to subjectivity and poor reproducibility when incompletely reported. We address this gap with geneticUMAP, an objective, dataset-specific optimization framework for configuring scRNA-seq visualization. geneticUMAP embeds the complete workflow in a genetic algorithm and optimizes its configuration using the Calinski-Harabasz index to evaluate how well the intrinsic data structure is preserved in the final visualization. We applied geneticUMAP to 18 publicly available scRNA-seq datasets that span different species, tissues, and acquisition protocols. Across all datasets, optimization improved structure-preserving mappings. Additionally, we assess the robustness under parameter perturbations and the biological relevance of the resulting visualizations. Optimized configurations generally produced more robust visualizations than default settings and improved agreement with author-provided cell-type annotations for most datasets. By automatically identifying a suitable configuration, geneticUMAP eliminates the need for manual parameter tuning and enables more objective and robust scRNA-seq data visualizations.

Alongside this R package, geneticUMAP is available as web application.

Installation

Make sure R is installed on your system. Install the package from Bioconductor:

if (!require("BiocManager", quietly = TRUE)) {
    install.packages("BiocManager")
}

BiocManager::install("geneticumap")

Input Data

Provide run_optimization() with a directory containing either a 10X Genomics matrix (matrix.mtx, barcodes.tsv, and features.tsv or genes.tsv) or a 10X HDF5 file (.h5). If the directory contains an HDF5 file, the package loads that file. The package applies fixed quality-control filters to every dataset: cells must have more than 200 and fewer than 2,500 detected features, and mitochondrial content must be below 5% using the ^MT- gene-name pattern.

Run an Optimization

The package includes a small HDF5 dataset* for this reproducible example. The optimization settings below match the lightweight configuration used by the package tests.

library(geneticumap)

data_dir <- system.file("extdata", "testdata", package="geneticumap")
results_dir <- file.path(tempdir(), "geneticumap-vignette-results")
optimization_result <- run_optimization(
    data_dir = data_dir,
    results_dir = results_dir,
    mu = 2,
    lambda = 4,
    max_iterations = 2,
    num_processes = 1
)

The function writes its results to results_dir and returns the optimized parameters as a named vector. The same parameters are saved in a JSON file within results_dir.

optimization_result
#> $scale_factor
#> [1] 10040.8
#> 
#> $nfeatures
#> [1] 500
#> 
#> $dimensionality
#> [1] 18
#> 
#> $resolution
#> [1] 0.58
#> 
#> $umap_neighbors
#> [1] 31
#> 
#> $umap_min_dist
#> [1] 0.31

Result Files

File What it contains
seurat-params.json Selected values for the six pipeline parameters
umap-coordinates.tsv One row per cell, with its barcode and two UMAP coordinates (umap_1, umap_2)
cluster-identities.tsv The Seurat cluster assignment for each cell barcode. These are the clusters used to calculate the CH index
scatter-fitness.png CH fitness across generations
umap-static.png Static UMAP plot for the selected parameter set
umap-static-default-seurat.png Static UMAP plot using the package’s default parameter set, for comparison
umap-interactive.html Interactive UMAP for the selected settings, with cluster labels and hover information for top marker genes

The coordinate and cluster tables can be joined by cell_id. Comparing the two static plots gives a quick visual comparison between the default and selected settings; open the interactive HTML file for cell-level exploration.

References

*The test dataset included in this package is a synthetic dataset. No biological interpretation can be deduced from the results retrieved from it.

Session Information

utils::sessionInfo()
#> R version 4.6.1 (2026-06-24)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 26.04.1 LTS
#> 
#> Matrix products: default
#> BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 
#> LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.32.so;  LAPACK version 3.12.0
#> 
#> Random number generation:
#>  RNG:     L'Ecuyer-CMRG 
#>  Normal:  Inversion 
#>  Sample:  Rejection 
#>  
#> locale:
#>  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
#>  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
#>  [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: Etc/UTC
#> tzcode source: system (glibc)
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#>  [1] knitr_1.52          Seurat_5.6.0        SeuratObject_5.4.0 
#>  [4] sp_2.2-4            ecr_2.1.1.1         smoof_1.7.0        
#>  [7] checkmate_2.3.4     ParamHelpers_1.14.2 BBmisc_1.13.1      
#> [10] clusterCrit_1.3.0   geneticumap_0.99.6  rmarkdown_2.32     
#> 
#> loaded via a namespace (and not attached):
#>   [1] RColorBrewer_1.1-3     sys_3.4.3              rstudioapi_0.19.0     
#>   [4] jsonlite_2.0.0         magrittr_2.0.5         spatstat.utils_3.2-5  
#>   [7] farver_2.1.2           vctrs_0.7.3            ROCR_1.0-12           
#>  [10] spatstat.explore_3.8-3 htmltools_0.5.9        sass_0.4.10           
#>  [13] sctransform_0.4.3      parallelly_1.48.0      KernSmooth_2.23-27    
#>  [16] bslib_0.12.0           htmlwidgets_1.6.4      ica_1.0-3             
#>  [19] plyr_1.8.9             plotly_4.12.1          zoo_1.9-1             
#>  [22] cachem_1.1.0           buildtools_1.0.0       igraph_2.3.4          
#>  [25] mime_0.13              lifecycle_1.0.5        pkgconfig_2.0.3       
#>  [28] Matrix_1.7-6           R6_2.6.1               fastmap_1.2.0         
#>  [31] fitdistrplus_1.2-6     future_1.80.0          shiny_1.14.0          
#>  [34] digest_0.6.39          patchwork_1.3.2        tensor_1.5.1          
#>  [37] RSpectra_0.16-2        irlba_2.4.1            crosstalk_1.2.2       
#>  [40] textshaping_1.0.5      labeling_0.4.3         progressr_1.1.0       
#>  [43] spatstat.sparse_3.2-0  httr_1.4.9             polyclip_1.10-7       
#>  [46] abind_1.4-8            compiler_4.6.1         withr_3.0.3           
#>  [49] bit64_4.8.6            S7_0.2.2               backports_1.5.1       
#>  [52] fastDummies_1.7.6      MASS_7.3-66            tools_4.6.1           
#>  [55] lmtest_0.9-40          otel_0.2.0             parallelMap_1.5.1     
#>  [58] httpuv_1.6.17          future.apply_1.21.0    goftest_1.2-3         
#>  [61] glue_1.8.1             nlme_3.1-171           promises_1.5.0        
#>  [64] grid_4.6.1             Rtsne_0.17             cluster_2.1.8.3       
#>  [67] reshape2_1.4.5         generics_0.1.4         hdf5r_1.3.16          
#>  [70] gtable_0.3.6           spatstat.data_3.1-9    tidyr_1.3.2           
#>  [73] data.table_1.18.6.1    xml2_1.6.0             spatstat.geom_3.8-3   
#>  [76] RcppAnnoy_0.0.23       ggrepel_0.9.8          RANN_2.6.3            
#>  [79] pillar_1.11.1          stringr_1.6.0          spam_2.11-4           
#>  [82] RcppHNSW_0.7.0         later_1.4.8            splines_4.6.1         
#>  [85] dplyr_1.2.1            lattice_0.23-1         bit_4.6.0             
#>  [88] survival_3.8-12        deldir_2.0-4           tidyselect_1.2.1      
#>  [91] maketools_1.3.2        miniUI_0.1.2           pbapply_1.7-5         
#>  [94] gridExtra_2.3.1        svglite_2.2.2          scattermore_1.2       
#>  [97] xfun_0.62              matrixStats_1.5.0      stringi_1.8.9         
#> [100] lazyeval_0.2.3         yaml_2.3.12            kableExtra_1.4.1      
#> [103] evaluate_1.0.5         codetools_0.2-20       tibble_3.3.1          
#> [106] cli_3.6.6              uwot_0.2.5             xtable_1.8-8          
#> [109] reticulate_1.47.0      systemfonts_1.3.2      jquerylib_0.1.4       
#> [112] Rcpp_1.1.2             globals_0.20.0         spatstat.random_3.5-2 
#> [115] png_0.1-9              spatstat.univar_3.2-0  parallel_4.6.1        
#> [118] ggplot2_4.0.3          dotCall64_1.2          listenv_1.1.0         
#> [121] viridisLite_0.4.3      scales_1.4.0           ggridges_0.5.7        
#> [124] purrr_1.2.2            rlang_1.3.0            cowplot_1.2.0         
#> [127] fastmatch_1.1-8