Interactive manual gating for SingleCellExperiment objects in R / Shiny.
Open-source flow cytometry and CyTOF (mass cytometry) gating app for R / Shiny — with FCS import, fluorescence compensation, Boolean population trees, and Gating-ML round-trip, all persisted inside the object.
📖 Documentation & Getting Started
GateLabR is a desktop-style Shiny application for hand-gating flow cytometry
and mass cytometry (CyTOF) data directly on
SingleCellExperiment
objects. It slots into Bioconductor-based analysis pipelines (e.g. CATALYST,
diffcyt) where the events already live in R as an SCE and you want a fast,
reproducible alternative to round-tripping through FlowJo or Cytobank just to
draw a few gates.
Gates are drawn on an interactive D3.js canvas, and gates, populations, scales
and illustration settings are persisted inside the SCE itself via metadata(),
so loading the SCE again restores the entire workspace.
- Draw and edit gates interactively. Polygon and rectangle gates on any pair of channels, with click-and-drag vertex editing, snap-to-grid, undo / redo, and per-gate colour and label.
- Boolean population trees. Build hierarchies of populations from gate references with AND / OR logic; counts and percentages update live.
- Flow and CyTOF modes. Auto-detects the instrument type from channel names. Flow uses per-channel logicle for fluorescence and arcsinh for FSC / SSC scatter, with editable W and cofactor; CyTOF channels use arcsinh (cofactor 5).
- Compensation. When an
.fcscarries an embedded spillover matrix ($SPILLOVER), it can be applied to the raw fluorescence data before gating — toggled on/off from the Scales tab, with a read-only matrix viewer. Scatter and time channels are left untouched. Defaults off; apply it before drawing gates, since it changes the linear space the gates live in. Already-compensated / spectral-unmixed and CyTOF files (no usable matrix) hide the option. - Cytobank-compatible Gating-ML 2.0 import / export. Round-trip gates through Cytobank, FlowJo and other ISAC-compliant tools.
- Workspace persistence. Gates, populations, scales and illustration
settings are saved inside the SCE (
metadata(sce)$gating_workspace) and re-loaded automatically. - FCS export. Export gated populations as FCS files, optionally split by
sample_id. - Sample filter and multi-sample overlay. Filter by any
colDatacolumn and overlay multiple samples with distinct colours. - Statistics tab. Per-population, per-channel summary stats (count, % parent / total, median, mean, geometric mean, SD, CV) exportable to CSV.
- UMAP tab. Overlay any populations on a precomputed UMAP and export as SVG / PDF.
- Cell-division profiler. A CFSE / CellTrace dye-dilution tab: draggable
per-sample division gates on a 1-D histogram (Div0…DivN), a marker-vs-dye
biplot with density contours, and per-cell division calls written back to
colData. - Composition preview. A Proportions tab for quick stacked-bar and boxplot
previews of any
colDatacomposition (e.g. cluster or division proportions by condition), with per-sample averaging and faceting. - Figure export. Strategy and Illustration tabs render publication-style
multi-panel grids; SVG export uses
gridSVGto produce Adobe Illustrator- friendly grouped vector files (rasterised data, vector axes / gates / labels).
GateLabR fills a specific gap: an interactive GUI for gating that lives
natively on a SingleCellExperiment, so it slots into a Bioconductor pipeline
instead of replacing it — while keeping full R access to the same object.
| GateLabR | FlowJo / Cytobank | CytoExploreR / flowGate | |
|---|---|---|---|
| Interface | GUI (Shiny) + full R access | GUI (proprietary) | R, with interactive gating helpers |
| Data object | SingleCellExperiment (Bioconductor-native) |
proprietary workspace | GatingSet (flowWorkspace) |
| Cost / licence | Free, MIT, open source | Commercial | Free, open source |
| Flow and CyTOF | Yes (auto-detected) | Flow-focused | Flow-focused |
| Gates persist in the object | Yes — in metadata(); reload restores everything |
Workspace files | GatingSet on disk |
| Gating-ML round-trip | Yes (Cytobank-compatible) | Yes | Partial |
| Downstream hand-off | Populations → colData for diffcyt / CATALYST / any SCE tool |
Export gated FCS | GatingSet → downstream |
If your data already lives in R as an SCE and you want to draw a few gates without round-tripping through FlowJo or Cytobank — but would rather point and click than write gate coordinates by hand — that's what GateLabR is for.
GateLabR can be used either as an installed R package or straight from a clone.
# install.packages("remotes") # if needed
# Bioconductor dependencies are resolved automatically; if you don't already
# have BiocManager, install it first: install.packages("BiocManager")
remotes::install_github("david-priest/GateLabR")
library(GateLabR)
launchGatingApp() # or launchGatingApp(my_sce)# 1. git clone https://github.com/david-priest/GateLabR.git
# 2. From an R session, install dependencies once (CRAN + Bioconductor):
source("path/to/GateLabR/install_dependencies.R")
# 3. Source the launcher and run (see Quick start):
source("path/to/GateLabR/launch.R")
launchGatingApp()Dependencies (installed automatically by Option A, or by
install_dependencies.R for Option B):
- CRAN:
shiny,DT,jsonlite,base64enc,uuid,sp,gridSVG,png,ggplot2 - Bioconductor:
SingleCellExperiment,SummarizedExperiment,S4Vectors,flowCore,xml2
R ≥ 4.2 and Bioconductor ≥ 3.16 are recommended.
# Installed package: Or from a clone:
library(GateLabR) # source("path/to/GateLabR/launch.R")
# Option A: launch and pass an existing SCE
launchGatingApp(my_sce)
# Option B: launch with no SCE — the app scans the global environment
# and lets you pick from any SingleCellExperiment objects present
launchGatingApp()The app opens in your default browser. The three-column layout is:
| Panel | Content |
|---|---|
| Left | Sample filter, scale controls, FCS / GatingML / workspace import-export, UMAP |
| Centre | Interactive plot (tabs: Gating | Strategy | Illustration | Statistics | Panel) |
| Right | Gates list, population tree, bulk-rename controls |
- Get your events into the app, either way:
- Import
.fcsfiles directly in the app — it builds the SCE and auto-detects flow vs CyTOF (and the per-channel transforms). - Or load an existing
SingleCellExperiment— e.g. from CATALYSTprepData()(CyTOF) or one you've built fromflowCore/ your own pipeline.
- Import
launchGatingApp()(then pick a loaded SCE or Import FCS), orlaunchGatingApp(sce)to start from an object already in your session.- Draw gates on the central plot; the gate list and population tree update live.
- Build populations by referencing gates with AND / OR logic.
- Export results for downstream work — populations as new
colDatacolumns on the SCE (Export Population, e.g. fordiffcyt,CATALYST, or any SCE-aware analysis), or gated events back out as.fcs. - Save the SCE (e.g.
saveRDS(sce, "gated.rds")) — the workspace is embedded inmetadata()and reloaded next time.
GateLabR stores its state inside the SCE itself:
metadata(sce)$gating_workspace
#> $gates — list of gate objects
#> $populations — list of population objects (hierarchy)
#> $gate_order — display order
#> $root_population_id
#> $global_scale_ranges, $cytof_axis_range, $illust_settings, ...You can also export a portable workspace as a standalone .rds (Save Workspace button) and load it into a different SCE — channels are matched by
name, missing ones are skipped with a warning.
- Input: FCS 3.0 / 3.1, Cytobank Gating-ML 2.0 XML, workspace
.rds. - Output: FCS, Gating-ML 2.0 (Cytobank-compatible or standard
re-importable), workspace
.rds, SCE.rds(with embedded workspace), per-population colData columns, CSV statistics, SVG / PDF figures.
If you use GateLabR in published work, please cite the Zenodo archive:
Priest, D. G. (2026). GateLabR: Interactive manual gating for SingleCellExperiment objects. Version 1.0.0. Zenodo. https://doi.org/10.5281/zenodo.20404387
BibTeX:
@software{priest_gatelabr_2026,
author = {Priest, David G.},
title = {GateLabR: Interactive manual gating for SingleCellExperiment objects},
year = {2026},
version = {1.0.0},
doi = {10.5281/zenodo.20404387},
url = {https://github.com/david-priest/GateLabR},
publisher = {Zenodo}
}GitHub's "Cite this repository" button (powered by CITATION.cff)
renders formatted citations in several styles.
MIT — see LICENSE.
GateLabR is developed in the Wing Lab at the Immunology Frontier Research Center (IFReC), Osaka University.
Built on top of the Bioconductor stack
(SingleCellExperiment, SummarizedExperiment, flowCore), the
Shiny web framework, and
D3.js for the interactive plot.
If you run into a bug, or there's a feature you'd find useful, please open an issue or get in touch — I'm happy to take a look and would be glad to implement it.
A note on .fcs import: import has been thoroughly tested on files from a
BD spectral flow cytometer, but not yet on files from other vendors (Beckman
Coulter, Cytek, Sony, Thermo, Miltenyi, …). Channel and instrument detection
is designed to be vendor-agnostic, but if a file imports incorrectly — missing
markers, wrong channels, or a mis-detected flow/CyTOF mode — please let me
know (ideally with the file's channel names) and I'll get it sorted.
A note on compensation: embedded-$SPILLOVER compensation has been
validated on conventional fluorescence data from a BD FACSAria III /
FACSymphony S6, with compensated values matching flowCore::compensate. It has
not yet been exercised on embedded matrices from other vendors' acquisition
software; the matrix is read vendor-agnostically (flowCore::spillover), so if
compensation looks wrong for a given file please send me its channel names and
spillover keyword and I'll take a look.