Plot Standard (Manual-Gating) Spectra Extraction Workflow
Source:R/plot_spectra_standard_workflow.R
spectra.standard.workflow.plot.RdBuilds a manuscript-ready, multi-panel figure illustrating a "standard"
single-stained-control workflow of the kind used in vendor software (e.g.
SpectroFlo): an octagon gate on FSC-A vs SSC-A positioned on the dominant
population, selection of the brightest events on the fluorophore's peak
channel as the positive population and the dimmest fraction as an internal
negative, biplots of both fractions (negative in black, positive coloured
by cosine similarity), and a population-
level background subtraction. Intended as a direct comparison against
spectra.automated.steps.plot() for the same fluorophore(s). Uses the same
building blocks as the rest of AutoSpectral (create.biplot()-style
pseudocolour density, spectral.trace()) so panel styling matches the
package's other figures.
Requires plot_spectra_automated_steps.R to be loaded in the same package
namespace (several private helpers are shared).
Usage
spectra.standard.workflow.plot(
control.dir,
control.def.file,
asp,
fluorophores = NULL,
octagon.width.factor = 3,
n.bright.events = 2000L,
negative.quantile = 0.25,
negative.quantile.min = 0.01,
x.min.quantile = 0.005,
singlet.quantiles = c(0.85, 0.975),
gate.color = "darkgoldenrod1",
density.palette = "rainbow",
selection.fill.color = "steelblue",
selection.line.color = "black",
negative.bracket.color = "#377EB8",
positive.bracket.color = "#E41A1C",
negative.point.color = "black",
event.point.size = NULL,
ground.truth.method = c("automated", "legacy", "none"),
truth.n.candidates = 1000L,
truth.n.spectral = 200L,
legacy.gating.system = c("density", "landmarks"),
legacy.af.remove = TRUE,
legacy.universal.negative = TRUE,
legacy.downsample = TRUE,
legacy.scatter.match = TRUE,
legacy.k.neighbors = 3L,
legacy.negative.n = asp$negative.n,
legacy.positive.n = asp$positive.n,
legacy.flow.control = NULL,
legacy.diagnostics.env = NULL,
n.highlight = 200L,
clean.positive.color = "red",
clean.positive.point.size = NULL,
cells.trace.color = "#D95F02",
beads.trace.color = "#377EB8",
af.trace.color = "grey40",
max.points = 50000,
panel.width = 4,
panel.height = 4,
composite.width = NULL,
composite.height = NULL,
output.dir = NULL,
save = TRUE,
file.type = "jpg",
verbose = TRUE
)Arguments
- control.dir
Character. Path to the directory containing the single-stained control FCS files.
- control.def.file
Character. Path to (or filename of) the control definition CSV – for the plotted fluorophore itself, only the
fluorophore/filenamecolumns are used, since this workflow always derives an internal negative from the same file. If the file has acontrol.typecolumn (as used bydefine.flow.control()/check.control.file()), a row withcontrol.type == "beads"sharing a fluorophore name with a "cells" row is treated as a paired bead control: itsfilenameis the positive bead sample, and itsuniversal.negativemust point at the matching unstained bead file. When present, this pair supplies the "(Beads)" trace in panel D instead of the static spectral reference library. - asp
The AutoSpectral parameter list from
get.autospectral.param().- fluorophores
Character vector of fluorophore name(s) to illustrate. Default
NULLillustrates the first fluorophore found.- octagon.width.factor
Numeric, default
3. Controls how large the octagon gate is drawn, as a multiple of the local median-absolute- deviation spread of events around the density peak.- n.bright.events
Integer, default
2000. Number of top-expressing events on the peak channel (within the octagon gate) selected as the "positive" population.- negative.quantile
Numeric in
(0, 1), default0.25. Upper quantile bound (on the peak channel, within octagon-gated events) of the internal "negative" population.- negative.quantile.min
Numeric in
[0, negative.quantile), default0.01. Lower quantile bound of the internal "negative" population – the negative gate spans events between thenegative.quantile.minandnegative.quantilequantiles of the peak channel, excluding the extreme dim tail (typically debris) belownegative.quantile.min.- x.min.quantile
Numeric in
[0, 1), default0.005. Quantile of the peak-channel data used as the x-axis lower limit in panel B. Flow data can have a long, sparse negative tail, so this is set independently ofnegative.quantile.minto keep the histogram readable.- singlet.quantiles
Numeric, default
c(0.85, 0.975). Quantile thresholds used only when cleaning a paired bead control (seecontrol.def.file), matchingget.spectra.automated().- gate.color
Colour of the octagon gate boundary in panel A, and of the gate box drawn around the positive fraction in panel C. Default
"darkgoldenrod1"(matchingdo.gate()'s default).- density.palette
Fill palette for the pseudocolour density in panel A: one of the viridis options (
"plasma","viridis", etc.) or any other value to useasp$density.palette.base.color. Default"rainbow"(matchingcreate.biplot()'s default).- selection.fill.color, selection.line.color
Fill and line colours for the KDE histogram in panel B. Defaults
"steelblue"/"black".- negative.bracket.color, positive.bracket.color
Colours for the negative- and positive-selection brackets in panel B. Defaults
"#377EB8"(blue) /"#E41A1C"(red).- negative.point.color
Colour for the negative-fraction events in panel C, which are plotted as plain points with no colour mapping (matching the "Unstained" convention in
spectra.automated.steps.plot()'s panel D). Default"black". Only the positive-fraction events are coloured by cosine similarity.- event.point.size
Numeric or
NULL(default). Point size for the positive-fraction events in panel C. IfNULL, defaults toasp$figure.gate.point.size * 1.3.- ground.truth.method
Character, one of
"automated"(default),"legacy", or"none". Determines how the "true positive" events highlighted in red in panel A are identified."automated"replicatesget.spectra.automated()'s own candidate + cosine-to-AF-reference filter on this control file."legacy"uses the actual AF-removalgate.population.idxfromremove.af()/clean.controls(), which requires runningdefine.flow.control()andclean.controls()over the whole control set (seelegacy.flow.control/legacy.diagnostics.envto avoid repeating this per fluorophore)."none"reverts to this workflow's own top-n.highlightcosine-similarity selection, which is not an independent ground truth and is kept only for reference.- truth.n.candidates, truth.n.spectral
Integers, defaults
1000and200. Only used whenground.truth.method = "automated"; mirrorn.candidates/n.spectralinget.spectra.automated().- legacy.gating.system, legacy.af.remove, legacy.universal.negative, legacy.downsample, legacy.scatter.match, legacy.k.neighbors, legacy.negative.n, legacy.positive.n
Only used when
ground.truth.method = "legacy"andlegacy.flow.control/legacy.diagnostics.envare not supplied; passed through todefine.flow.control()/clean.controls()exactly as inspectra.legacy.steps.plot().- legacy.flow.control, legacy.diagnostics.env
Optional, default
NULL. Precomputed outputs ofdefine.flow.control()+clean.controls()(the latter called with adiagnostics.env). Supply both together to skip re-running the legacy pipeline when illustrating multiple fluorophores withground.truth.method = "legacy"– e.g. by callingspectra.legacy.steps.plot()first and reusing its internal objects, or running the two functions yourself as shown inspectra.legacy.steps.plot().- n.highlight
Integer, default
200. Only used whenground.truth.method = "none". Number of positive-fraction events (smallest cosine similarity to the negative fraction, i.e. least AF-like) highlighted in red in panel A.- clean.positive.color
Colour for the panel A ground-truth highlight. Default
"red".- clean.positive.point.size
Numeric or
NULL(default). Point size for the panel A highlight. IfNULL, defaults toasp$figure.gate.point.size * 1.5.- cells.trace.color, beads.trace.color, af.trace.color
Colours for the three traces in panel D: the population-level background-subtracted profile ("Cells"), the reference profile ("Beads"), and the negative- fraction trace. Defaults
"#D95F02"/"#377EB8"/"grey40".- max.points
Integer. Maximum events plotted per panel (randomly downsampled beyond this for speed). Default
5e4.- panel.width, panel.height
Numeric. Width/height (inches) used per sub-panel when sizing the saved composite figure. Defaults
4and4.- composite.width, composite.height
Numeric or
NULL(default). Override the overall saved figure dimensions (inches); ifNULL, these are computed frompanel.width/panel.height.- output.dir
Character or
NULL(default). Directory to save the composite figure(s). Defaults to the current working directory.- save
Logical, default
TRUE. Whether to save the composite figure for each fluorophore tooutput.dir.- file.type
Character string, one of
"jpg"(default),"tiff","png", or"pdf".- verbose
Logical, default
TRUE. Print progress messages.
Value
Invisibly, a named list (one entry per fluorophore), each containing:
gate.panelPanel A, the octagon gate on FSC-A vs SSC-A with the ground-truth positive events highlighted.
selection.panelPanel B, the brightest/negative event selection histogram.
cosine.panelPanel C, the negative/positive-fraction cosine-similarity biplots.
subtraction.plotPanel D, the final spectral profile comparison (
spectral.trace()of Cells / Beads / AF).compositeThe assembled four-panel cowplot object saved to
output.dirwhensave = TRUE.peak.channelCharacter. The fluorophore's nominal peak channel, looked up from
fluorophore_database.csvforasp$cytometer.y.channel.peakCharacter. The non-colliding peak AF channel used as the y-axis of panel C.
reference.profileNamed numeric vector (over
spectral.channels) used as the "Beads" trace in panel D, orNULLif neither a paired bead control nor the spectral reference library had data for this fluorophore.