#' cyto_plot_1d
#'
#' Visualise 1-D flow cytometry density distributions.
#'
#' @param x object of class \code{\link[flowCore:flowFrame-class]{flowFrame}} or
#' \code{\link[flowCore:flowSet-class]{flowSet}}.
#' @param ... additional method-specific arguments for cyto_plot_1d.
#'
#' @seealso \code{\link{cyto_plot_1d,flowFrame-method}}
#' @seealso \code{\link{cyto_plot_1d,flowSet-method}}
#'
#' @author Dillon Hammill, \email{Dillon.Hammill@anu.edu.au}
#'
#' @noRd
setGeneric(
name = ".cyto_plot_1d",
def = function(x, ...) {
standardGeneric(".cyto_plot_1d")
}
)
#' cyto_plot_1d - flowFrame Method
#'
#' Visualise 1-D flow cytometry density distributions for a flowFrame.
#'
#' @param x object of class \code{\link[flowCore:flowFrame-class]{flowFrame}}.
#' @param channel name of the channel or marker to be used to construct the
#' plot.
#' @param axes_trans object of class
#' \code{\link[flowCore:transformList-class]{transformList}} or
#' \code{\link[flowWorkspace]{transformerList}} generated by
#' \code{\link[flowCore:logicleTransform]{estimateLogicle}} which was used to
#' transform the fluorescent channels of the supplied flowFrame. This
#' transformation object will be used internally to ensure that the axes
#' labels of the plot are appropriately transformed. The transformation object
#' will NOT be applied to the flowFrame internally and should be applied to
#' the flowFrame prior to plotting.
#' @param overlay a \code{flowFrame}, \code{flowSet} or list of
#' \code{flowFrames} to be overlaid onto the plot.
#' @param gate gate object(s) to be added to plot. For \code{cyto_plot_1d} only
#' gate objects of class
#' \code{\link[flowCore:rectangleGate-class]{rectangleGate}} in either 1 or 2
#' dimensions are supported. Mulitple gates can be supplied either as a
#' \code{list} or \code{\link[flowCore:filters-class]{filters}} object.
#' @param limits indicates whether the axes limits should be based on the
#' \code{"data"} or \code{"machine"}, set to "machine" by default to show
#' complete axes ranges. This argument will only alter the upper axis limits,
#' to modify the lower limits use \code{xlim} and \code{ylim}.
#' @param popup logical indicating whether the plot should be constructed in a
#' pop-up window, set to FALSE by default. \code{popup} will open OS-specific
#' graphic device prior to plotting. Mac users will need to install
#' \href{https://www.xquartz.org/}{XQuartz} for this functionality.
#' @param xlim lower and upper limits of x axis (e.g. c(0,5)).
#' @param ylim lower and upper limits of y axis (e.g. c(0,5)).
#' @param title title to use for the plot, set to the name of the sample by
#' default. Title can be removed by setting this argument to \code{NA}.
#' @param xlab x axis label.
#' @param ylab y axis label.
#' @param density_modal logical indicating whether density should be normalised
#' to mode and presented as a percentage. Set to \code{TRUE} by default.
#' @param density_smooth smoothing parameter passed to
#' \code{\link[stats:density]{density}} to adjust kernel density.
#' @param density_stack numeric [0,1] indicating the degree of offset for
#' overlaid populations, set to 0.5 by default.
#' @param density_fill colour(s) used to fill polygons.
#' @param density_fill_alpha numeric [0,1] used to control fill transparency,
#' set to 1 by default to remove transparency.
#' @param density_line_type line type(s) to use for border(s), set to solid
#' lines by default.
#' @param density_line_width line width for border.
#' @param density_line_col colour(s) for border line, set to "black" by default.
#' @param axes_text_font numeric indicating the font to use for axes, set to 1
#' for plain font by default. See \code{\link[graphics:par]{?par}} font for
#' details.
#' @param axes_text_size character expansion for axis text.
#' @param axes_text_col colour of axis text.
#' @param axes_label_text_font numeric indicating the font to use for title, set
#' to 1 for plain font by default. See \code{\link[graphics:par]{?par}} font
#' for details.
#' @param axes_label_text_size character expansion for axis labels.
#' @param axes_label_text_col colour of axis labels.
#' @param title_text_font numeric indicating the font to use for title, set to 2
#' for bold font by default. See \code{\link[graphics:par]{?par}} font for
#' details.
#' @param title_text_size character expansion for plot title.
#' @param title_text_col colour for plot title.
#' @param legend can be either \code{"line"} or \code{"fill"} to indicate
#' whether a legend should be constructed based on the density \code{"line"}
#' or \code{"fill"}, set to FALSE by default to remove the legend.
#' @param legend_text vector of labels to use for the legend.
#' @param legend_text_font numeric indicating the font to use for labels, set to
#' 1 for plain font by default. See \code{\link[graphics:par]{?par}} font for
#' details.
#' @param legend_text_size character expansion for legend text, set to 1 by
#' default.
#' @param legend_text_col colour of text used in legend, set to \code{"black"}
#' by default.
#' @param legend_line_col vector of line colours to use for legend.
#' @param legend_box_fill vector of fill colours to use for legend.
#' @param gate_line_type integer [0,6] which controls the line type, set to
#' \code{1} to draw solid lines by default.
#' @param gate_line_width numeric to adjust line thickness of gates, set to
#' \code{2.5} by default.
#' @param gate_line_col indicates the colour of the gate to be constructed, set
#' to \code{"red"} by default.
#' @param label logical indicating whether gated populations should be labelled.
#' If the names of the populations are supplied as the text.labels argument,
#' the population name and frequency will be included in the labels, otherwise
#' only the population frequencies will be included in the labels.
#' @param label_text vector of population names to use in labels. Set to NA to
#' exclude population names.
#' @param label_stat indicates the type of statistic to include in the label,
#' can be \code{"percent"}, \code{"count"}, \code{"mean"}, \code{"median"},
#' \code{"mode"} or \code{"geo mean"}, set to \code{"percent"} for gated data
#' or \code{NA} to exclude statistics for un-gated data.
#' @param label_text_font numeric indicating the font to use for labels, set to
#' 2 for bold font by default. See \code{\link[graphics:par]{?par}} font for
#' details.
#' @param label_text_size character expansion for label text, set to 0.8 by
#' default.
#' @param label_text_col colour of text used in labels, set to \code{"black"} by
#' default.
#' @param label_box_x x co-ordinate to manually adjust the position of the label
#' on the plot.
#' @param label_box_y y co-ordinate(s) to manually adjust the position of the
#' label(s) on the plot.
#' @param label_box_alpha numeric controlling backgropund fill transparency of
#' label boxes, set to 0.6 by default to introduce some transparency.
#' @param border_line_type line type to use for plot border, set to 1 by default
#' for a sold border.
#' @param border_line_width line width for plot border, set to 1 by default.
#' @param border_line_col line colour for plot border, set to "black" by
#' default.
#' @param ... additional arguments passed to \code{\link[graphics:plot]{plot}}.
#'
#' @examples
#' \dontrun{
#' library(CytoRSuiteData)
#' fs <- Activation
#'
#' cyto_plot_1d(fs[[1]],
#' channel = "FSC-A",
#' overlay = fs[[2]],
#' density_fill = c("red", "blue")
#' )
#' }
#'
#' @importFrom flowCore exprs parameters
#' @importFrom flowWorkspace pData
#' @importFrom graphics plot axis title abline polygon legend par box
#' @importFrom grDevices adjustcolor
#' @importFrom stats density
#'
#' @author Dillon Hammill (Dillon.Hammill@anu.edu.au)
#'
#' @noRd
setMethod(.cyto_plot_1d,
signature = "flowFrame",
definition = function(x,
channel = NULL,
axes_trans = NULL,
overlay = NULL,
gate = NA,
limits = "machine",
popup = FALSE,
xlim = NULL,
ylim = NULL,
title,
xlab = NA,
ylab = NA,
density_modal = TRUE,
density_smooth = 1.5,
density_stack = 0.5,
density_fill,
density_fill_alpha = 1,
density_line_type = 1,
density_line_width = 1,
density_line_col = "black",
axes_text_font = 1,
axes_text_size = 1,
axes_text_col = "black",
axes_label_text_font = 1,
axes_label_text_size = 1.1,
axes_label_text_col = "black",
title_text_font = 2,
title_text_size = 1.1,
title_text_col = "black",
legend = FALSE,
legend_text,
legend_text_font = 1,
legend_text_size = 1,
legend_text_col = "black",
legend_line_col = NA,
legend_box_fill = NA,
gate_line_type = 1,
gate_line_width = 2.5,
gate_line_col = "red",
label = TRUE,
label_text = NA,
label_stat = "percent",
label_text_font = 2,
label_text_size = 1,
label_text_col = "black",
label_box_x = NA,
label_box_y = NA,
label_box_alpha = 0.6,
border_line_type = 1,
border_line_width = 1,
border_line_col = "black", ...) {
# Prevent scientific notation on axes
options(scipen = 999)
# Assign x to fr
fr <- x
# Return channel name if marker supplied
channel <- cyto_channel_check(fr,
channels = channel,
plot = TRUE
)
# Get transformList object
if (!is.null(axes_trans)) {
axes_trans <- cyto_trans_check(axes_trans,
inverse = FALSE
)
}
# Get X Axis Breaks and Labels from trans if supplied
xtext <- .cyto_axes_text(
x = fr,
channels = channel,
trans = axes_trans
)[[1]]
# Check overlay return list of fowFrames
if (!is.null(overlay)) {
overlay <- .cyto_overlay_check(
x = fr,
overlay = overlay
)
# title missing - no title for plots with overlay
if (missing(title)) {
title <- NA
}
if (!density_modal) {
message("Overlays must be normalised to mode.")
density_modal <- TRUE
}
}
# number of overlays
ovn <- length(overlay)
# number of layers
lyrs <- ovn + 1
# group_by fr with overlay if supplied - named list of fr & overlay
if (!is.null(overlay)) {
frs <- c(list(fr), overlay)
names(frs) <- unlist(
lapply(frs, function(fr) {
fr@description$GUID
})
)
} else {
frs <- list(fr)
names(frs) <- fr@description$GUID
}
# Extract information
fr.data <- pData(parameters(fr))
fr.channels <- BiocGenerics::colnames(fr)
# Extract data from frs and calculate kernel density
frs.dens <- .cyto_density(
x = frs,
channel = channel,
adjust = density_smooth,
modal = density_modal,
density_stack = density_stack
)
# Y axis labels
if (ovn == 0) {
ytext <- TRUE
} else if (ovn != 0) {
if (density_stack == 0) {
ytext <- TRUE
} else {
ytext <- FALSE
}
}
# Get y axis values for horizontal lines
if (density_stack == 0) {
ofst <- 0
} else {
ofst <- seq(
0,
ovn * density_stack * 100,
density_stack * 100
)
}
# Title missing - set to sample name
if (missing(title)) {
title <- fr@description$GUID
}
# Y Axis Title
if (is.na(ylab)) {
if (density_modal) {
ylab <- "Density Normalised to Mode (%)"
} else {
ylab <- "Density"
}
}
# X Axis Title
if (is.na(xlab)) {
if (!is.na(fr.data$desc[which(fr.channels == channel)])) {
xlab <- paste(fr.data$desc[which(fr.channels == channel)],
channel,
sep = " "
)
} else if (is.na(fr.data$desc[which(fr.channels == channel)])) {
xlab <- paste(channel, sep = " ")
}
}
# Y Axis Limits
if (is.null(ylim)) {
if (is.null(overlay)) {
if (!density_modal) {
ylim <- range(frs.dens[[1]]$y)
} else if (density_modal) {
ylim <- c(0, 100)
}
} else if (!is.null(overlay)) {
# No offset with overlay y limits c(0,100)
if (density_stack == 0) {
ylim <- c(0, 100)
} else if (density_stack != 0) {
# Overlays with offset
ylim <- c(0, (100 + ovn * density_stack * 100))
}
}
}
# X Axis limits
if (is.null(xlim)) {
xlim <- suppressWarnings(.cyto_plot_limits(
x = fr,
channels = channel,
overlay = overlay,
limits = limits
)[[1]])
}
# Overlay colours
cols <- colorRampPalette(c(
"grey",
"bisque4",
"brown1",
"red",
"darkred",
"chocolate",
"orange",
"yellow",
"yellowgreen",
"green",
"aquamarine",
"cyan",
"cornflowerblue",
"blue",
"blueviolet",
"purple",
"magenta",
"deeppink"
))
# Density fill
if (missing(density_fill)) {
density_fill <- NA
}
# Get density_fill for each layer
if (all(is.na(density_fill))) {
density_fill <- cols(length(frs.dens))
} else if (length(density_fill) < length(frs.dens)) {
density_fill <- c(
density_fill,
cols((length(frs.dens) - length(density_fill)))
)
} else if (length(density_fill) > length(frs.dens)) {
density_fill <- density_fill[length(frs.dens)]
}
# Legend text
if (missing(legend_text)) {
legend_text <- names(frs)
}
# Supported gates
typ <- c("rectangleGate", "filters")
if (class(gate) %in% typ) {
gates <- length(gate)
} else if (inherits(gate, "list")) {
if (all(unlist(lapply(gate, "class")) %in% typ)) {
gates <- length(gate)
} else if (all(unlist(lapply(gate, "class")) == "list")) {
gates <- length(gate[[1]])
}
} else if (!.valid_gates(gate, channel)) {
gates <- 0
}
# Get named list of arguments
args <- as.list(environment())
# Split arguments
args <- .arg_split(
x = args[-c(match(
c(
"x",
"fr",
"channel",
"axes_trans",
"overlay",
"gate",
"xlim",
"ylim",
"popup",
"limits",
"gate",
"typ",
"cols",
"ofst",
"ytext",
"xtext",
"frs.dens",
"fr.channels",
"fr.data",
"frs",
"lyrs",
"ovn"
),
names(args)
))],
channels = channel,
n = lyrs,
plots = 1,
layers = lyrs,
gates = gates
)
# Unlist arguments for single plot
args <- lapply(args, function(x) x[[1]])
# Pop-up
if (popup == TRUE) {
.cyto_plot_window()
}
# Plot margins
.cyto_plot_margins(
x = fr,
overlay = overlay,
legend = args[["legend"]],
legend_text = args[["legend_text"]],
title = args[["title"]]
)
# Set up empty plot
if (is.null(xtext) & ytext == FALSE) {
graphics::plot(1,
type = "n",
yaxt = "n",
xlim = xlim,
ylim = ylim,
axes = TRUE,
font.axis = args[["axes_text_font"]],
cex.axis = args[["axes_text_size"]],
col.axis = args[["axes_text_col"]],
ann = FALSE,
bty = "n", ...
)
box(
which = "plot",
lty = args[["border_line_type"]],
lwd = args[["border_line_width"]],
col = args[["border_line_col"]]
)
abline(
h = ofst,
col = args[["density_line_col"]],
lwd = args[["density_line_width"]],
lty = args[["density_line_type"]]
)
if (!is.na(args[["title"]])) {
title(
main = args[["title"]],
cex.main = args[["title_text_size"]],
col.main = args[["title_text_col"]],
font.main = args[["title_text_font"]]
)
}
title(
xlab = args[["xlab"]],
font.lab = args[["axes_label_text_font"]],
col.lab = args[["axes_label_text_col"]],
cex.lab = args[["axes_label_text_size"]]
)
title(
ylab = args[["ylab"]],
mgp = c(2, 0, 0),
font.lab = args[["axes_label_text_font"]],
col.lab = args[["axes_label_text_col"]],
cex.lab = args[["axes_label_text_size"]]
)
} else if (is.null(xtext) & ytext == TRUE) {
graphics::plot(1,
type = "n",
xlim = xlim,
ylim = ylim,
axes = TRUE,
font.axis = args[["axes_text_font"]],
cex.axis = args[["axes_text_size"]],
col.axis = args[["axes_text_col"]],
ann = FALSE,
las = 1,
bty = "n", ...
)
box(
which = "plot",
lty = args[["border_line_type"]],
lwd = args[["border_line_width"]],
col = args[["border_line_col"]]
)
abline(
h = ofst,
col = args[["density_line_col"]],
lwd = args[["density_line_width"]],
lty = args[["density_line_type"]]
)
if (!is.na(args[["title"]])) {
title(
main = args[["title"]],
cex.main = args[["title_text_size"]],
col.main = args[["title_text_col"]],
font.main = args[["title_text_font"]]
)
}
title(
xlab = args[["xlab"]],
font.lab = args[["axes_label_text_font"]],
col.lab = args[["axes_label_text_col"]],
cex.lab = args[["axes_label_text_size"]]
)
title(
ylab = args[["ylab"]],
mgp = c(3, 0, 0),
font.lab = args[["axes_label_text_font"]],
col.lab = args[["axes_label_text_col"]],
cex.lab = args[["axes_label_text_size"]]
)
} else if (!is.null(xtext) & ytext == FALSE) {
graphics::plot(1,
type = "n",
yaxt = "n",
xaxt = "n",
xlim = xlim,
ylim = ylim,
axes = TRUE,
cex.axis = args[["axes_text_size"]],
col.axis = args[["axes_text_col"]],
ann = FALSE,
bty = "n", ...
)
axis(1,
at = xtext$at,
labels = xtext$label,
font = args[["axes_text_font"]],
cex.axis = args[["axes_text_size"]],
col.axis = args[["axes_text_col"]]
)
box(
which = "plot",
lty = args[["border_line_type"]],
lwd = args[["border_line_width"]],
col = args[["border_line_col"]]
)
abline(
h = ofst,
col = args[["density_line_col"]],
lwd = args[["density_line_width"]],
lty = args[["density_line_type"]]
)
if (!is.na(args[["title"]])) {
title(
main = args[["title"]],
cex.main = args[["title_text_size"]],
col.main = args[["title_text_col"]],
font.main = args[["title_text_font"]]
)
}
title(
xlab = args[["xlab"]],
font.lab = args[["axes_label_text_font"]],
col.lab = args[["axes_label_text_col"]],
cex.lab = args[["axes_label_text_size"]]
)
title(
ylab = args[["ylab"]],
mgp = c(2, 0, 0),
font.lab = args[["axes_label_text_font"]],
col.lab = args[["axes_label_text_col"]],
cex.lab = args[["axes_label_text_size"]]
)
} else if (!is.null(xtext) & ytext == TRUE) {
graphics::plot(1,
type = "n",
xaxt = "n",
xlim = xlim,
ylim = ylim,
axes = TRUE,
xlab = xlab,
ylab = ylab,
cex.axis = args[["axes_text_size"]],
col.axis = args[["axes_text_col"]],
ann = FALSE,
las = 1,
bty = "n", ...
)
axis(1,
at = xtext$at,
labels = xtext$label,
font = args[["axes_text_font"]],
cex.axis = args[["axes_text_size"]],
col.axis = args[["axes_text_col"]]
)
box(
which = "plot",
lty = args[["border_line_type"]],
lwd = args[["border_line_width"]],
col = args[["border_line_col"]]
)
abline(
h = ofst,
col = args[["density_line_col"]],
lwd = args[["density_line_width"]],
lty = args[["density_line_type"]]
)
if (!is.na(args[["title"]])) {
title(
main = args[["title"]],
cex.main = args[["title_text_size"]],
col.main = args[["title_text_col"]],
font.main = args[["title_text_font"]]
)
}
title(
xlab = args[["xlab"]],
font.lab = args[["axes_label_text_font"]],
col.lab = args[["axes_label_text_col"]],
cex.lab = args[["axes_label_text_size"]]
)
title(
ylab = args[["ylab"]],
mgp = c(3, 0, 0),
font.lab = args[["axes_label_text_font"]],
col.lab = args[["axes_label_text_col"]],
cex.lab = args[["axes_label_text_size"]]
)
}
# Add density distributions - reverse plot order and colours
if (!is.null(overlay) & args[["density_stack"]] == 0) {
mapply(
function(fr.dens,
density_fill,
density_line_col,
density_line_width,
density_line_type,
density_fill_alpha) {
polygon(fr.dens,
col = adjustcolor(density_fill, density_fill_alpha),
border = density_line_col,
lwd = density_line_width,
lty = density_line_type
)
}, frs.dens,
args[["density_fill"]],
args[["density_line_col"]],
args[["density_line_width"]],
args[["density_line_type"]],
args[["density_fill_alpha"]]
)
} else {
mapply(
function(fr.dens,
density_fill,
density_line_col,
density_line_width,
density_line_type,
density_fill_alpha) {
polygon(fr.dens,
col = adjustcolor(density_fill, density_fill_alpha),
border = density_line_col,
lwd = density_line_width,
lty = density_line_type
)
}, rev(frs.dens),
rev(args[["density_fill"]]),
rev(args[["density_line_col"]]),
rev(args[["density_line_width"]]),
rev(args[["density_line_type"]]),
rev(args[["density_fill_alpha"]])
)
}
# Add legend
if (!is.null(overlay) & args[["legend"]]) {
# Legend TRUE default to fill
if (args[["legend"]]) {
args[["legend"]] <- "fill"
}
# Legend position x
legend.x <- par("usr")[2] + 0.025 * par("usr")[2]
# Legend position y
legend.y <- mean(par("usr")[c(3, 4)])
legend.y <- legend.y + (((par("usr")[4]) / 21) * 0.5 * length(frs.dens))
# Legend labels
legend_text <- rev(args[["legend_text"]])
# Line legend
if (args[["legend"]] == "line") {
# No line colours supplied - use density_line_col
if (all(is.na(args[["legend_line_col"]]))) {
args[["legend_line_col"]] <- args[["density_line_col"]]
}
legend(
x = legend.x,
y = legend.y,
legend = legend_text,
col = rev(args[["legend_line_col"]]),
lty = rev(args[["density_line_type"]]),
lwd = rev(args[["density_line_width"]]),
xpd = TRUE,
bty = "n",
x.intersp = 0.5,
cex = args[["legend_text_size"]],
text.col = rev(args[["legend_text_col"]]),
text.font = rev(args[["legend_text_font"]])
)
# Fill legend
} else if (args[["legend"]] == "fill") {
# No fill colours supplied - use density_line_col
if (all(is.na(args[["legend_box_fill"]]))) {
args[["legend_box_fill"]] <- args[["density_fill"]]
}
# Alpha adjust legend_fill
if (!all(args[["density_fill_alpha"]] == 1)) {
args[["legend_box_fill"]] <- mapply(
function(legend_box_fill,
density_fill_alpha) {
adjustcolor(legend_box_fill, density_fill_alpha)
}, args[["legend_box_fill"]],
args[["density_fill_alpha"]]
)
}
legend(
x = legend.x,
y = legend.y,
legend = legend_text,
fill = rev(args[["legend_box_fill"]]),
xpd = TRUE,
bty = "n",
x.intersp = 0.5,
cex = args[["legend_text_size"]],
text.col = rev(args[["legend_text_col"]]),
text.font = rev(args[["legend_text_font"]])
)
}
}
# Valid gates supplied?
valid_gates <- .valid_gates(gate, channel)
# Gates - no overlay
if (is.null(overlay)) {
if (valid_gates) {
gate <- cyto_plot_gate(gate,
channels = channel,
gate_line_col = args[["gate_line_col"]],
gate_line_width = args[["gate_line_width"]],
gate_line_type = args[["gate_line_type"]]
)
}
# Labels
if (valid_gates & args[["label"]]) {
# Population names missing - show percantage only
suppressMessages(cyto_plot_label(
x = fr,
channels = channel,
gates = gate,
trans = axes_trans,
text = args[["label_text"]],
stat = args[["label_stat"]],
text_size = args[["label_text_size"]],
text_font = args[["label_text_font"]],
text_col = args[["label_text_col"]],
box_alpha = args[["label_box_alpha"]]
))
}
} else if (!is.null(overlay) & args[["density_stack"]] != 0 & valid_gates) {
.cyto_overlay_gate(
x = fr,
channel = channel,
trans = axes_trans,
overlay = overlay,
gates = gate,
density_stack = args[["density_stack"]],
label_text = args[["label_text"]],
label_stat = args[["label_stat"]],
label_text_size = args[["label_text_size"]],
label_text_font = args[["label_text_font"]],
label_text_col = args[["label_text_col"]],
label_box_x = args[["label_box_x"]],
label_box_y = args[["label_box_y"]],
label_box_alpha = args[["label_box_alpha"]],
gate_line_col = args[["gate_line_col"]],
gate_line_width = args[["gate_line_width"]],
gate_line_type = args[["gate_line_type"]]
)
} else if (!is.null(overlay) & args[["density_stack"]] == 0 & valid_gates) {
message("Gating overlays without stacking is not supported.")
}
# No gates - labels
if (!valid_gates & !all(is.na(args[["label_text"]])) & args[["label"]]) {
if (is.null(overlay)) {
# label # limited to # layers - arg_split
mapply(
function(label_text,
label_stat,
label_text_size,
label_text_font,
label_text_col,
label_box_x,
label_box_y,
label_box_alpha) {
if (label_stat == "percent") {
label_stat <- NA
}
suppressMessages(cyto_plot_label(
x = fr,
channels = channel,
gates = gate, trans = axes_trans,
text = label_text,
stat = label_stat,
text_x = label_box_x,
text_y = label_box_y,
text_size = label_text_size,
text_font = label_text_font,
text_col = label_text_col,
box_alpha = label_box_alpha
))
}, args[["label_text"]],
args[["label_stat"]],
args[["label_text_size"]],
args[["label_text_font"]],
args[["label_text_col"]],
args[["label_box_x"]],
args[["label_box_y"]],
args[["label_box_alpha"]]
)
} else if (!is.null(overlay)) {
fr.lst <- c(list(fr), overlay)
# Number of labels must equal number of layers
if (length(args[["label_text"]]) != length(fr.lst)) {
message("cyto_plot expects one label per layer.")
if (all(is.na(args[["label_box_y"]]))) {
args[["label_box_y"]] <- unlist(
lapply(seq_along(fr.lst), function(x) {
stk <- args[["density_stack"]]
(0.5 * stk * 100) + ((x - 1) * stk * 100)
})
)
}
mapply(
function(fr,
label_text,
label_stat,
label_text_size,
label_text_font,
label_text_col,
label_box_x,
label_box_y,
label_box_alpha) {
if (label_stat == "percent") {
label_stat <- NA
}
suppressMessages(cyto_plot_label(
x = fr,
channels = channel,
gates = gate,
trans = axes_trans,
text = label_text,
stat = label_stat,
text_x = label_box_x,
text_y = label_box_y,
text_size = label_text_size,
text_font = label_text_font,
text_col = label_text_col,
box_alpha = label_box_alpha
))
}, fr.lst, args[["label_text"]],
args[["label_stat"]],
args[["label_text_size"]],
args[["label_text_font"]],
args[["label_text_col"]],
args[["label_box_x"]],
args[["label_box_y"]],
args[["label_box_alpha"]]
)
}
}
}
# Return options to default
options(scipen = 0)
# Return plot margins to default
par(mar = c(5, 4, 4, 2) + 0.1)
}
)
#' cyto_plot_1d - flowSet Method
#'
#' Visualise 1-D flow cytometry density distributions for a flowSet.
#'
#' @param x object of class \code{\link[flowCore:flowSet-class]{flowSet}}.
#' @param channel name of the channel or marker to be used to construct the
#' plot.
#' @param axes_trans object of class
#' \code{\link[flowCore:transformList-class]{transformList}} or
#' \code{\link[flowWorkspace]{transformerList}} generated by
#' \code{\link[flowCore:logicleTransform]{estimateLogicle}} which was used to
#' transform the fluorescent channels of the supplied flowFrame. This
#' transformation object will be used internally to ensure axes labels of the
#' plot are appropriately transformed. The transformation object will NOT be
#' applied to the flowFrame internally and should be applied to the flowFrame
#' prior to plotting.
#' @param group_by a vector of pData variables to sort and merge samples into
#' groups, set to FALSE by default to prevent merging. To merge all samples
#' set this argument to "all".
#' @param overlay a \code{flowFrame}, \code{flowSet}, \code{list of flowFrames},
#' \code{list of flowSets} or \code{list of flowFrame lists} containing
#' populations to be overlaid onto the plot(s).
#' @param gate gate object(s) to be added to plot. For \code{cyto_plot_1d} only
#' gate objects of class
#' \code{\link[flowCore:rectangleGate-class]{rectangleGate}} in either 1 or 2
#' dimensions are supported. Mulitple gates can be supplied either as a
#' \code{list} or \code{\link[flowCore:filters-class]{filters}} object. Gates
#' can also be supplied on a per sample basis as a list of length samples,
#' with each element being a list of length gates containing the gates per
#' sample.
#' @param limits indicates whether the axes limits should be based on the
#' \code{"data"} or \code{"machine"}, set to "machine" by default to show
#' complete axes ranges. This argument will only alter the upper axis limits,
#' to modify the lower limits use \code{xlim} and \code{ylim}.
#' @param popup logical indicating whether the plot should be constructed in a
#' pop-up window, set to FALSE by default. \code{popup} will open OS-specific
#' graphic device prior to plotting. Mac users will need to install
#' \href{https://www.xquartz.org/}{XQuartz} for this functionality.
#' @param layout a vector of the length 2 indicating the dimensions of the grid
#' for plotting \code{c(#rows, #columns)}.
#' @param xlim lower and upper limits of x axis (e.g. c(0,5)).
#' @param ylim lower and upper limits of y axis (e.g. c(0,5)).
#' @param title vector of titles to use for each plot, set to name of the sample
#' by default.
#' @param xlab x axis label.
#' @param ylab y axis label.
#' @param density_modal logical indicating whether density should be normalised
#' to mode and presented as a percentage. Set to \code{TRUE} by default.
#' @param density_smooth smoothing parameter passed to
#' \code{\link[stats:density]{density}} to adjust kernel density.
#' @param density_stack numeric [0,1] indicating the degree of offset for
#' overlaid populations, set to 0.5 by default.
#' @param density_layers numeric indicating the number of samples to stack each
#' plot, set to all samples by default.
#' @param density_fill colour(s) used to fill polygons.
#' @param density_fill_alpha numeric [0,1] used to control fill transparency,
#' set to 1 by default to remove transparency.
#' @param density_line_type line type(s) to use for border(s), set to solid
#' lines by default.
#' @param density_line_width line width for border.
#' @param density_line_col colour(s) for border line, set to "black" by default.
#' @param axes_text_font numeric indicating the font to use for axes, set to 1
#' for plain font by default. See \code{\link[graphics:par]{?par}} font for
#' details.
#' @param axes_text_size character expansion for axis text.
#' @param axes_text_col colour of axis text.
#' @param axes_label_text_font numeric indicating the font to use for title, set
#' to 1 for plain font by default. See \code{\link[graphics:par]{?par}} font
#' for details.
#' @param axes_label_text_size character expansion for axis labels.
#' @param axes_label_text_col colour of axis labels.
#' @param title_text_font numeric indicating the font to use for title, set to 2
#' for bold font by default. See \code{\link[graphics:par]{?par}} font for
#' details.
#' @param title_text_size character expansion for plot title.
#' @param title_text_col colour for plot title.
#' @param legend can be either \code{"line"} or \code{"fill"} to indicate
#' whether a legend should be constructed based on the density \code{"line"}
#' or \code{"fill"}, set to FALSE by default to remove the legend.
#' @param legend_text vector of labels to use for the legend.
#' @param legend_text_font numeric indicating the font to use for labels, set to
#' 1 for plain font by default. See \code{\link[graphics:par]{?par}} font for
#' details.
#' @param legend_text_size character expansion for legend text, set to 1 by
#' default.
#' @param legend_text_col colour of text used in legend, set to \code{"black"}
#' by default.
#' @param legend_line_col vector of line colours to use for legend.
#' @param legend_box_fill vector of fill colours to use for legend.
#' @param gate_line_type integer [0,6] which controls the line type, set to
#' \code{1} to draw solid lines by default.
#' @param gate_line_width numeric to adjust line thickness of gates, set to
#' \code{2.5} by default.
#' @param gate_line_col indicates the colour of the gate to be constructed, set
#' to \code{"red"} by default.
#' @param label logical indicating whether gated populations should be labelled.
#' If the names of the populations are supplied as the text.labels argument,
#' the population name and frequency will be included in the labels, otherwise
#' only the population frequencies will be included in the labels.
#' @param label_text vector of population names to use in labels. Set to NA to
#' exclude population names.
#' @param label_stat indicates the type of statistic to include in the label,
#' can be \code{"percent"}, \code{"count"}, \code{"mean"}, \code{"median"},
#' \code{"mode"} or \code{"geo mean"}, set to \code{"percent"} for gated data
#' or \code{NA} to exclude statistics for un-gated data.
#' @param label_text_font numeric indicating the font to use for labels, set to
#' 2 for bold font by default. See \code{\link[graphics:par]{?par}} font for
#' details.
#' @param label_text_size character expansion for label text, set to 0.8 by
#' default.
#' @param label_text_col colour of text used in labels, set to \code{"black"} by
#' default.
#' @param label_box_x x co-ordinate to manually adjust the position of the label
#' on the plot.
#' @param label_box_y y co-ordinate(s) to manually adjust the position of the
#' label(s) on the plot.
#' @param label_box_alpha numeric controlling backgropund fill transparency of
#' label boxes, set to 0.6 by default to introduce some transparency.
#' @param border_line_type line type to use for plot border, set to 1 by default
#' for a sold border.
#' @param border_line_width line width for plot border, set to 1 by default.
#' @param border_line_col line colour for plot border, set to "black" by
#' default.
#' @param ... additional arguments passed to \code{\link[graphics:plot]{plot}}.
#'
#' @examples
#' \dontrun{
#' library(CytoRSuiteData)
#' fs <- Activation
#'
#' cyto_plot_1d(fs, channel = "FSC-A", legend = TRUE)
#' }
#'
#' @seealso \code{\link{cyto_plot_1d,flowFrame-method}}
#' @seealso \code{\link{cyto_plot,flowSet-method}}
#'
#' @importFrom flowCore exprs parameters fsApply
#' @importFrom flowWorkspace pData sampleNames
#' @importFrom graphics plot axis title abline polygon legend
#' @importFrom grDevices n2mfrow
#' @importFrom graphics par
#' @importFrom methods as
#'
#' @author Dillon Hammill (Dillon.Hammill@anu.edu.au)
#'
#' @noRd
setMethod(.cyto_plot_1d,
signature = "flowSet",
definition = function(x,
channel,
axes_trans = NULL,
group_by = FALSE,
overlay = NULL,
gate = NA,
limits = "machine",
popup = FALSE,
layout = NULL,
xlim = NULL,
ylim = NULL,
title,
xlab = NA,
ylab = NA,
density_modal = TRUE,
density_smooth = 1.5,
density_stack = 0,
density_layers = length(x),
density_fill = NA,
density_fill_alpha = 1,
density_line_type = 1,
density_line_width = 1,
density_line_col = "black",
axes_text_font = 1,
axes_text_size = 1,
axes_text_col = "black",
axes_label_text_font = 1,
axes_label_text_size = 1.1,
axes_label_text_col = "black",
title_text_font = 2,
title_text_size = 1.1,
title_text_col = "black",
legend = FALSE,
legend_text,
legend_text_font = 1,
legend_text_size = 1,
legend_text_col = "black",
legend_line_col = NA,
legend_box_fill = NA,
gate_line_type = 1,
gate_line_width = 2.5,
gate_line_col = "red",
label = TRUE,
label_text = NA,
label_stat = "percent",
label_text_font = 2,
label_text_size = 1,
label_text_col = "black",
label_box_x = NA,
label_box_y = NA,
label_box_alpha = 0.6,
border_line_type = 1,
border_line_width = 1,
border_line_col = "black", ...) {
# Prevent scientific notation
options(scipen = 999)
# Assign x to fs
fs <- x
# Refresh layout after plotting?
if (is.null(layout[1])) {
refresh <- TRUE
} else {
if (layout[1] == FALSE) {
refresh <- FALSE
} else {
refresh <- TRUE
}
}
# Return name of channel if marker supplied
channel <- cyto_channel_check(
x = fs,
channels = channel,
plot = TRUE
)
# Get transformList object
if (!is.null(axes_trans)) {
axes_trans <- cyto_trans_check(axes_trans,
inverse = FALSE
)
}
# Get X Axis Breaks and Labels from trans if supplied
xtext <- .cyto_axes_text(
x = as(fs, "flowFrame"),
channels = channel,
trans = axes_trans
)[[1]]
# Axes limits
if (is.null(xlim)) {
xlim <- suppressWarnings(.cyto_plot_limits(
x = fs,
channels = channel,
overlay = overlay,
limits = limits
)[[1]])
}
# group_by
if (group_by[1] != FALSE) {
# group_by set to TRUE
if (group_by[1] == TRUE) {
group_by <- "all"
}
# Return list of group_by flowFrames
fr.lst <- .cyto_merge(x = fs, group_by = group_by)
# No overlay
if (is.null(overlay)) {
# No stacking - each in separate panels
if (all(density_stack == 0)) {
# title
if (missing(title)) {
if (group_by[1] == "all") {
title <- "Combined Events"
} else {
title <- names(fr.lst)
}
}
# Legend text
if (missing(legend_text)) {
legend_text <- names(fr.lst)
}
# Gates
if (.valid_gates(gate, channel)) {
gate <- .cyto_gate_check(gate, length(fr.lst))
}
# Stacking - one panel
} else {
# title
if (missing(title)) {
title <- paste(group_by, sep = "-")
}
# Split fr.lst by density_layers
sp <- rep(seq_len(length(fr.lst)),
each = density_layers,
length.out = length(fr.lst)
)
# Legend text
if (missing(legend_text)) {
legend_text <- lapply(
unique(sp),
function(x) {
names(fr.lst[sp == x])
}
)
}
# Gates
if (.valid_gates(gate, channel)) {
gate <- .cyto_gate_check(gate, 1)
}
}
# Overlay - separate panels with overlay
} else if (!is.null(overlay)) {
# Check overlay
overlay <- .cyto_overlay_check(
x = fs,
overlay = overlay
)
# list of flowFrame lists to overlay (1 per group)
overlay <- .cyto_overlay_merge(
x = fs,
overlay = overlay,
group_by = group_by
)
# Layout
layout <- .cyto_plot_layout(
x = fr.lst,
layout = layout
)
# title
if (missing(title)) {
title <- names(fr.lst)
}
# Legend text
if (missing(legend_text)) {
legend_text <- paste0("layer", 1:(length(overlay) + 1))
}
# Gates
if (.valid_gates(gate, channel)) {
gate <- .cyto_gate_check(gate, length(fr.lst))
}
}
} else if (group_by[1] == FALSE) {
# Number of samples
smp <- length(fs)
# Convert fs to list of flowFrames
fr.lst <- lapply(seq_len(length(fs)), function(x) fs[[x]])
names(fr.lst) <- sampleNames(fs)
# No overlay
if (is.null(overlay)) {
# Legend text
if (missing(legend_text)) {
legend_text <- names(fr.lst)
}
# No stacking - separate panels
if (all(density_stack == 0)) {
# Titles
if (missing(title)) {
title <- sampleNames(fs)
}
# Gates
if (.valid_gates(gate, channel)) {
gate <- .cyto_gate_check(gate, length(fr.lst))
}
# Stacking - one panel
} else {
# Split fr.lst by density_layers
sp <- rep(seq_len(length(fr.lst)),
each = density_layers,
length.out = length(fr.lst)
)
# Title
if (missing(title)) {
title <- NA
}
# Gates
if (.valid_gates(gate, channel)) {
gate <- .cyto_gate_check(gate, 1)
}
}
# Overlay - separate panels with overlay
} else if (!is.null(overlay)) {
# Check overlay
overlay <- .cyto_overlay_check(
x = fs,
overlay = overlay
)
# Legend text
if (missing(legend_text)) {
legend_text <- paste0("layer", seq_len(length(overlay[[1]]) + 1))
}
# Titles
if (missing(title)) {
title <- names(fr.lst)
}
# Gates
if (.valid_gates(gate, channel)) {
gate <- .cyto_gate_check(
gate,
length(fr.lst)
)
}
# Layout
layout <- .cyto_plot_layout(
x = fr.lst,
layout = layout
)
}
}
# Pop-up
if (popup) {
.cyto_plot_window()
}
# Plot layout
if (is.null(layout)) {
layout <- .cyto_plot_layout(
x = fr.lst,
layout = layout,
density_stack = density_stack,
density_layers = density_layers
)
# Set plot space
par(mfrow = layout)
} else if (all(!layout)) {
layout <- par("mfrow")
} else {
par(mfrow = layout)
}
# Plot space
np <- layout[1] * layout[2]
# Legend text - fs merged in flowFrame lists
if (missing(legend_text)) {
legend_text <- names(fr.lst)
}
# Number of gates
typ <- c("rectangleGate", "filters")
if (class(gate) %in% typ) {
gates <- length(gate)
} else if (inherits(gate, "list")) {
if (all(unlist(lapply(gate, "class")) %in% typ)) {
gates <- length(gate)
} else if (all(unlist(lapply(gate, "class")) == "list")) {
gates <- length(gate[[1]])
}
} else if (!.valid_gates(gate, channel)) {
gates <- 0
}
# Split arguments & plot
if (is.null(overlay)) {
# No stacking - separate panels
if (all(density_stack == 0)) {
# Get named list of arguments
args <- as.list(environment())
# Split arguments
args <- .arg_split(
x = args[-c(match(
c(
"x",
"fs",
"channel",
"axes_trans",
"overlay",
"gate",
"xlim",
"ylim",
"popup",
"limits",
"layout",
"group_by",
"gates",
"typ"
),
names(args)
))],
channels = channel,
n = length(fr.lst),
plots = length(fr.lst),
layers = 1,
gates = gates
)
# Call to cyto_plot_1d
cnt <- 0
mapply(
function(fr,
gate,
xlab,
ylab,
title,
title_text_font,
title_text_size,
title_text_col,
density_fill,
density_fill_alpha,
density_line_type,
density_line_width,
density_line_col,
axes_text_font,
axes_text_size,
axes_text_col,
axes_label_text_font,
axes_label_text_size,
axes_label_text_col,
legend,
legend_text,
legend_text_font,
legend_text_size,
legend_text_col,
legend_line_col,
legend_box_fill,
gate_line_type,
gate_line_width,
gate_line_col,
label,
label_text,
label_stat,
label_text_font,
label_text_size,
label_text_col,
label_box_x,
label_box_y,
label_box_alpha,
border_line_type,
border_line_width,
border_line_col, ...) {
cnt <<- cnt + 1
.cyto_plot_1d(
x = fr,
channel = channel,
axes_trans = axes_trans,
overlay = NULL,
gate = gate,
density_stack = 0,
xlim = xlim,
xlab = xlab,
ylab = ylab,
title = title,
title_text_font = title_text_font,
title_text_size = title_text_size,
title_text_col = title_text_col,
density_fill = density_fill,
density_fill_alpha = density_fill_alpha,
density_line_type = density_line_type,
density_line_width = density_line_width,
density_line_col = density_line_col,
axes_text_font = axes_text_font,
axes_text_size = axes_text_size,
axes_text_col = axes_text_col,
axes_label_text_font = axes_label_text_font,
axes_label_text_size = axes_label_text_size,
axes_label_text_col = axes_label_text_col,
legend = legend,
legend_text = legend_text,
legend_text_font = legend_text_font,
legend_text_size = legend_text_size,
legend_text_col = legend_text_col,
legend_line_col = legend_line_col,
legend_box_fill = legend_box_fill,
gate_line_type = gate_line_type,
gate_line_width = gate_line_width,
gate_line_col = gate_line_col,
label = label,
label_text = label_text,
label_stat = label_stat,
label_text_font = label_text_font,
label_text_size = label_text_size,
label_text_col = label_text_col,
label_box_x = label_box_x,
label_box_y = label_box_y,
label_box_alpha = label_box_alpha,
border_line_type = border_line_type,
border_line_width = border_line_width,
border_line_col = border_line_col, ...
)
if (popup == TRUE & cnt %% np == 0 & length(fr.lst) > cnt) {
.cyto_plot_window()
par(mfrow = layout)
}
}, fr.lst,
gate,
args[["xlab"]],
args[["ylab"]],
args[["title"]],
args[["title_text_font"]],
args[["title_text_size"]],
args[["title_text_col"]],
args[["density_fill"]],
args[["density_fill_alpha"]],
args[["density_line_type"]],
args[["density_line_width"]],
args[["density_line_col"]],
args[["axes_text_font"]],
args[["axes_text_size"]],
args[["axes_text_col"]],
args[["axes_label_text_font"]],
args[["axes_label_text_size"]],
args[["axes_label_text_col"]],
args[["legend"]],
args[["legend_text"]],
args[["legend_text_font"]],
args[["legend_text_size"]],
args[["legend_text_col"]],
args[["legend_line_col"]],
args[["legend_box_fill"]],
args[["gate_line_type"]],
args[["gate_line_width"]],
args[["gate_line_col"]],
args[["label"]],
args[["label_text"]],
args[["label_stat"]],
args[["label_text_font"]],
args[["label_text_size"]],
args[["label_text_col"]],
args[["label_box_x"]],
args[["label_box_y"]],
args[["label_box_alpha"]],
args[["border_line_type"]],
args[["border_line_width"]],
args[["border_line_col"]], ...
)
# Stacking - One panel
} else {
# Get named list of arguments
args <- as.list(environment())
# Split arguments
args <- .arg_split(
x = args[-c(match(
c(
"x",
"fs",
"channel",
"axes_trans",
"overlay",
"gate",
"xlim",
"ylim",
"popup",
"limits",
"layout",
"group_by",
"gates",
"typ"
),
names(args)
))],
channels = channel,
n = length(fr.lst),
plots = ceiling(length(fr.lst) / density_layers),
layers = density_layers,
gates = gates
)
# Call to cyto_plot
mapply(
function(y,
gate,
xlab,
ylab,
title,
title_text_font,
title_text_size,
title_text_col,
density_stack,
density_fill,
density_fill_alpha,
density_line_type,
density_line_width,
density_line_col,
axes_text_font,
axes_text_size,
axes_text_col,
axes_label_text_font,
axes_label_text_size,
axes_label_text_col,
legend,
legend_text,
legend_text_font,
legend_text_size,
legend_text_col,
legend_line_col,
legend_box_fill,
gate_line_type,
gate_line_width,
gate_line_col,
label,
label_text,
label_stat,
label_text_font,
label_text_size,
label_text_col,
label_box_x,
label_box_y,
label_box_alpha,
border_line_type,
border_line_width,
border_line_col, ...) {
.cyto_plot_1d(
x = fr.lst[sp == y][[1]],
channel = channel,
axes_trans = axes_trans,
overlay = fr.lst[sp == y][2:length(fr.lst[sp == y])],
gate = gate,
density_stack = density_stack,
xlim = xlim,
xlab = xlab,
ylab = ylab,
title = title,
title_text_font = title_text_font,
title_text_size = title_text_size,
title_text_col = title_text_col,
density_fill = density_fill,
density_fill_alpha = density_fill_alpha,
density_line_type = density_line_type,
density_line_width = density_line_width,
density_line_col = density_line_col,
axes_text_font = axes_text_font,
axes_text_size = axes_text_size,
axes_text_col = axes_text_col,
axes_label_text_font = axes_label_text_font,
axes_label_text_size = axes_label_text_size,
axes_label_text_col = axes_label_text_col,
legend = legend,
legend_text = legend_text,
legend_text_font = legend_text_font,
legend_text_size = legend_text_size,
legend_text_col = legend_text_col,
legend_line_col = legend_line_col,
legend_box_fill = legend_box_fill,
gate_line_type = gate_line_type,
gate_line_width = gate_line_width,
gate_line_col = gate_line_col,
label = label,
label_text = label_text,
label_stat = label_stat,
label_text_font = label_text_font,
label_text_size = label_text_size,
label_text_col = label_text_col,
label_box_x = label_box_x,
label_box_y = label_box_y,
label_box_alpha = label_box_alpha,
border_line_type = border_line_type,
border_line_width = border_line_width,
border_line_col = border_line_col, ...
)
}, unique(sp),
list(gate[[1]]),
args[["xlab"]],
args[["ylab"]],
args[["title"]],
args[["title_text_font"]],
args[["title_text_size"]],
args[["title_text_col"]],
args[["density_stack"]],
args[["density_fill"]],
args[["density_fill_alpha"]],
args[["density_line_type"]],
args[["density_line_width"]],
args[["density_line_col"]],
args[["axes_text_font"]],
args[["axes_text_size"]],
args[["axes_text_col"]],
args[["axes_label_text_font"]],
args[["axes_label_text_size"]],
args[["axes_label_text_col"]],
args[["legend"]],
args[["legend_text"]],
args[["legend_text_font"]],
args[["legend_text_size"]],
args[["legend_text_col"]],
args[["legend_line_col"]],
args[["legend_box_fill"]],
args[["gate_line_type"]],
args[["gate_line_width"]],
args[["gate_line_col"]],
args[["label"]],
args[["label_text"]],
args[["label_stat"]],
args[["label_text_font"]],
args[["label_text_size"]],
args[["label_text_col"]],
args[["label_box_x"]],
args[["label_box_y"]],
args[["label_box_alpha"]],
args[["border_line_type"]],
args[["border_line_width"]],
args[["border_line_col"]], ...
)
}
# Overlay - separate panels
} else if (!is.null(overlay)) {
# Get named list of arguments
args <- as.list(environment())
# Split arguments
args <- .arg_split(
x = args[-c(match(
c(
"x",
"fs",
"channel",
"axes_trans",
"overlay",
"gate",
"xlim",
"ylim",
"popup",
"limits",
"layout",
"group_by",
"gates",
"typ"
),
names(args)
))],
channels = channel,
n = (length(overlay[[1]]) + 1) * length(fr.lst),
plots = length(fr.lst),
layers = (length(overlay[[1]]) + 1),
gates = gates
)
# Call to cyto_plot_1d
cnt <- 0
mapply(
function(fr,
gate,
overlay,
xlab,
ylab,
title,
title_text_font,
title_text_size,
title_text_col,
density_stack,
density_fill,
density_fill_alpha,
density_line_type,
density_line_width,
density_line_col,
axes_text_font,
axes_text_size,
axes_text_col,
axes_label_text_font,
axes_label_text_size,
axes_label_text_col,
legend,
legend_text,
legend_text_font,
legend_text_size,
legend_text_col,
legend_line_col,
legend_box_fill,
gate_line_type,
gate_line_width,
gate_line_col,
label,
label_text,
label_stat,
label_text_font,
label_text_size,
label_text_col,
label_box_x,
label_box_y,
label_box_alpha,
border_line_type,
border_line_width,
border_line_col, ...) {
cnt <<- cnt + 1
.cyto_plot_1d(
x = fr,
channel = channel,
axes_trans = axes_trans,
overlay = overlay,
gate = gate,
density_stack = density_stack,
xlim = xlim,
xlab = xlab,
ylab = ylab,
title = title,
title_text_font = title_text_font,
title_text_size = title_text_size,
title_text_col = title_text_col,
density_fill = density_fill,
density_fill_alpha = density_fill_alpha,
density_line_type = density_line_type,
density_line_width = density_line_width,
density_line_col = density_line_col,
axes_text_font = axes_text_font,
axes_text_size = axes_text_size,
axes_text_col = axes_text_col,
axes_label_text_font = axes_label_text_font,
axes_label_text_size = axes_label_text_size,
axes_label_text_col = axes_label_text_col,
legend = legend,
legend_text = legend_text,
legend_text_font = legend_text_font,
legend_text_size = legend_text_size,
legend_text_col = legend_text_col,
legend_line_col = legend_line_col,
legend_box_fill = legend_box_fill,
gate_line_type = gate_line_type,
gate_line_width = gate_line_width,
gate_line_col = gate_line_col,
label = label,
label_text = label_text,
label_stat = label_stat,
label_text_font = label_text_font,
label_text_size = label_text_size,
label_text_col = label_text_col,
label_box_x = label_box_x,
label_box_y = label_box_y,
label_box_alpha = label_box_alpha,
border_line_type = border_line_type,
border_line_width = border_line_width,
border_line_col = border_line_col, ...
)
if (popup == TRUE & cnt %% np == 0 & length(fr.lst) > cnt) {
.cyto_plot_window()
par(mfrow = layout)
}
}, fr.lst,
gate,
overlay,
args[["xlab"]],
args[["ylab"]],
args[["title"]],
args[["title_text_font"]],
args[["title_text_size"]],
args[["title_text_col"]],
args[["density_stack"]],
args[["density_fill"]],
args[["density_fill_alpha"]],
args[["density_line_type"]],
args[["density_line_width"]],
args[["density_line_col"]],
args[["axes_text_font"]],
args[["axes_text_size"]],
args[["axes_text_col"]],
args[["axes_label_text_font"]],
args[["axes_label_text_size"]],
args[["axes_label_text_col"]],
args[["legend"]],
args[["legend_text"]],
args[["legend_text_font"]],
args[["legend_text_size"]],
args[["legend_text_col"]],
args[["legend_line_col"]],
args[["legend_box_fill"]],
args[["gate_line_type"]],
args[["gate_line_width"]],
args[["gate_line_col"]],
args[["label"]],
args[["label_text"]],
args[["label_stat"]],
args[["label_text_font"]],
args[["label_text_size"]],
args[["label_text_col"]],
args[["label_box_x"]],
args[["label_box_y"]],
args[["label_box_alpha"]],
args[["border_line_type"]],
args[["border_line_width"]],
args[["border_line_col"]], ...
)
}
# Return mfrow to default
if (refresh == TRUE) {
par(mfrow = c(1, 1))
}
# Return options to default
options(scipen = 0)
}
)
#' cyto_plot_2d
#'
#' Visualise 2-D flow cytometry scatterplots with blue-red density colour scale.
#'
#' For a complete list of customisation arguments see
#' \code{\link{cyto_plot_2d,flowFrame-method}}.
#'
#' @param x object of class \code{\link[flowCore:flowFrame-class]{flowFrame}} or
#' \code{\link[flowCore:flowSet-class]{flowSet}}.
#' @param ... additional method-specific arguments for cyto_plot_2d,
#'
#' @seealso \code{\link{cyto_plot_2d,flowFrame-method}}
#' @seealso \code{\link{cyto_plot_2d,flowSet-method}}
#'
#' @author Dillon Hammill (Dillon.Hammill@anu.edu.au)
#'
#' @noRd
setGeneric(
name = ".cyto_plot_2d",
def = function(x, ...) {
standardGeneric(".cyto_plot_2d")
}
)
#' cyto_plot_2d - flowFrame Method
#'
#' Visualise 2-D flow cytometry scatterplots with blue-red density colour scale
#' for a flowFrame.
#'
#' @param x object of class \code{\link[flowCore:flowFrame-class]{flowFrame}}.
#' @param channels name of the channels or markers to be used to construct the
#' plot.
#' @param axes_trans object of class
#' \code{\link[flowCore:transformList-class]{transformList}} or
#' \code{\link[flowWorkspace]{transformerList}} generated by
#' \code{\link[flowCore:logicleTransform]{estimateLogicle}} which was used to
#' transform the fluorescent channels of the supplied flowFrame. This
#' transformation object will be used internally to ensure axes labels of the
#' plot are appropriately transformed. The transformation object will NOT be
#' applied to the flowFrame internally and should be applied to the flowFrame
#' prior to plotting.
#' @param overlay a \code{flowFrame}, \code{flowSet} or list of
#' \code{flowFrames} to be overlaid onto the plot.
#' @param contour_lines numeric indicating the number of levels to use for
#' contour lines, set to 0 by default to turn off contour lines.
#' @param gate gate object(s) to be added to plot. Gates can be of class
#' \code{\link[flowCore:rectangleGate-class]{rectangleGate}},
#' \code{\link[flowCore:polygonGate-class]{polygonGate}} or
#' \code{\link[flowCore:ellipsoidGate-class]{ellipsoidGate}}. Multiple gates
#' of mixed classes can also be supplied in \code{list} or
#' \code{\link[flowCore:filters-class]{filters}} objects.
#' @param display numeric indicating the number of events to plot, set to all
#' events by default. Reducing the sample size can significantly improve
#' plotting speed on less powerful machines.
#' @param popup logical indicating whether the plot should be constructed in a
#' pop-up window, set to FALSE by default. \code{popup} will open OS-specific
#' graphic device prior to plotting. Mac users will need to install
#' \href{https://www.xquartz.org/}{XQuartz} for this functionality.
#' @param limits indicates whether the axes limits should be based on the
#' \code{"data"} or \code{"machine"}, set to "machine" by default to show
#' complete axes ranges. This argument will only alter the upper axis limits,
#' to modify the lower limits use \code{xlim} and \code{ylim}.
#' @param xlim lower and upper limits of x axis (e.g. c(0,5)).
#' @param ylim lower and upper limits of y axis (e.g. c(0,5)).
#' @param title title to use for the plot, set to the name of the sample by
#' default.
#' @param xlab x axis label.
#' @param ylab y axis label.
#' @param point_shape point character to use for points, set to "." by default
#' to maximise plotting speed.
#' @param point_size numeric specifying the degree of character expansion for
#' points, set to 2 by default.
#' @param point_col colours to use for points, set to NA by default to blue-red
#' density colour scale.
#' @param point_alpha numeric [0,1] used to control colour transparency, set to
#' 1 by default to remove transparency.
#' @param contour_line_type type of line to use for contour lines, set to 1 by
#' default.
#' @param contour_line_width line width for contour lines, set to 2 by default.
#' @param contour_line_col colour to use for contour lines, set to "black" by
#' default.
#' @param axes_text_font numeric indicating the font to use for axes text, set
#' to 1 for plain font by default. See \code{\link[graphics:par]{?par}} font
#' for details.
#' @param axes_text_size character expansion for axis text.
#' @param axes_text_col colour of axis text.
#' @param axes_label_text_font numeric indicating the font to use for axes
#' labels, set to 1 for plain font by default. See
#' \code{\link[graphics:par]{?par}} font for details.
#' @param axes_label_text_size character expansion for axis labels.
#' @param axes_label_text_col colour of axis labels.
#' @param title_text_font numeric indicating the font to use for the title, set
#' to 2 for bold font by default. See \code{\link[graphics:par]{?par}} font
#' for details.
#' @param title_text_size character expansion for plot title.
#' @param title_text_col colour for plot title.
#' @param legend logical indicating whether a legend should be included for
#' plots including overlays, set to FALSE by default.
#' @param legend_text vector of labels to use for the legend.
#' @param legend_text_font numeric indicating the font to use for legend text,
#' set to 2 for bold font by default. See \code{\link[graphics:par]{?par}}
#' font for details.
#' @param legend_text_size character expansion for legend text, set to 1 by
#' default.
#' @param legend_text_col colour to use for legend text, set to "black by
#' default.
#' @param legend_point_col vector of colours to use for points in legend.
#' @param gate_line_type integer [0,6] which controls the line type, set to
#' \code{1} to draw solid lines by default.
#' @param gate_line_width numeric to adjust line thickness of gates, set to
#' \code{2.5} by default.
#' @param gate_line_col indicates the colour of the gate to be constructed, set
#' to \code{"red"} by default.
#' @param label logical indicating whether gated populations should be labelled.
#' If the names of the populations are supplied as the text.labels argument,
#' the population name and frequency will be included in the labels, otherwise
#' only the population frequencies will be included in the labels.
#' @param label_text vector of population names to use in labels.
#' @param label_stat indicates the type of statistic to include in the label,
#' can be either \code{"percent"} or \code{"count"}, set to \code{"percent"}
#' by default.
#' @param label_text_format indicates the type of text to include in the label,
#' can be either \code{"alias"}, \code{"percent"}, \code{"count"},
#' \code{c("alias","percent")} or \code{c("alias","count")}. Set to
#' \code{c("alias","percent")} by default.
#' @param label_text_font numeric indicating the font to use for labels, set to
#' 2 for bold font by default. See \code{\link[graphics:par]{?par}} font for
#' details.
#' @param label_text_size character expansion for label text, set to 0.8 by
#' default.
#' @param label_text_col colour of text used in labels, set to \code{"black"} by
#' default.
#' @param label_box_x x co-ordinate to manually adjust the position of the label
#' on the plot.
#' @param label_box_y y co-ordinate(s) to manually adjust the position of the
#' label(s) on the plot.
#' @param label_box_alpha numeric controlling backgropund fill transparency of
#' labels, set to 0.6 by default to introduce some transparency.
#' @param border_line_type line type to use for plot border, set to 1 by default
#' for a sold border.
#' @param border_line_width line width for plot border, set to 1 by default.
#' @param border_line_coline colour for plot border, set to "black" by default.l
#' @param ... additional arguments passed to \code{\link[graphics:plot]{plot}}.
#'
#' @examples
#' \dontrun{
#' library(CytoRSuiteData)
#' fs <- Activation
#'
#' cyto_plot_2d(fs[[1]],
#' channel = c("FSC-A", "SSC-A"),
#' overlay = fs[[2]],
#' point_col = c(NA, "purple")
#' )
#'
#' cyto_plot_2d(fs[[1]],
#' channel = c("FSC-A", "SSC-A"),
#' overlay = fs[[2]],
#' point_col = c("black", "red")
#' )
#' }
#'
#' @importFrom flowCore exprs parameters fsApply
#' @importFrom flowWorkspace pData
#' @importFrom MASS kde2d
#' @importFrom graphics plot axis title abline polygon contour legend points par
#' box
#' @importFrom grDevices densCols colorRampPalette adjustcolor
#'
#' @author Dillon Hammill (Dillon.Hammill@anu.edu.au)
#'
#' @noRd
setMethod(.cyto_plot_2d,
signature = "flowFrame",
definition = function(x,
channels,
axes_trans = NULL,
overlay = NULL,
contour_lines = 0,
gate = NA,
display = NULL,
popup = FALSE,
limits = "machine",
xlim = NULL,
ylim = NULL,
title,
xlab = NA,
ylab = NA,
point_shape = ".",
point_size = 2,
point_col = NA,
point_alpha = 1,
contour_line_type = 1,
contour_line_width = 1,
contour_line_col = "black",
axes_text_font = 1,
axes_text_size = 1,
axes_text_col = "black",
axes_label_text_font = 1,
axes_label_text_size = 1.1,
axes_label_text_col = "black",
title_text_font = 2,
title_text_size = 1.1,
title_text_col = "black",
legend = FALSE,
legend_text,
legend_text_font = 1,
legend_text_size = 1,
legend_text_col = "black",
legend_point_col = NA,
gate_line_type = 1,
gate_line_width = 2.5,
gate_line_col = "red",
label = TRUE,
label_text = NA,
label_stat = "percent",
label_text_format = c("alias", "percent"),
label_text_font = 2,
label_text_size = 1,
label_text_col = "black",
label_box_x = NA,
label_box_y = NA,
label_box_alpha = 0.6,
border_line_type = 1,
border_line_width = 1,
border_line_col = "black", ...) {
# Prevent scientific notation
options(scipen = 999)
# Assign x to fr
fr <- x
# All channels
fr.channels <- BiocGenerics::colnames(fr)
# Check channels
channels <- cyto_channel_check(fr,
channels = channels,
plot = TRUE
)
# X axis limits
if (is.null(xlim)) {
xlim <- suppressWarnings(.cyto_plot_limits(
x = fr,
channels = channels,
overlay = overlay,
limits = limits
)[[1]])
}
# Y axis limits
if (is.null(ylim)) {
ylim <- suppressWarnings(.cyto_plot_limits(
x = fr,
channels = channels,
overlay = overlay,
limits = limits
)[[2]])
}
# Display
if (!is.null(display)) {
fr <- cyto_sample(fr, display)
}
# Get Axis Breaks and Labels from trans if supplied
axs <- .cyto_axes_text(
x = fr,
channels = channels,
trans = axes_trans
)
xtext <- axs[[1]]
ytext <- axs[[2]]
# overlay
if (!is.null(overlay)) {
overlay <- .cyto_overlay_check(
x = fr,
overlay = overlay,
display = display
)
}
ovn <- length(overlay)
smp <- ovn + 1
# Extract data for plotting
fr.exprs <- exprs(fr)[, channels]
# Extract pData and Channels
fr.data <- pData(parameters(fr))
# Colours
col_scale <- colorRampPalette(c(
"blue",
"turquoise",
"green",
"yellow",
"orange",
"red",
"darkred"
))
cols <- colorRampPalette(c(
"black",
"darkorchid",
"blueviolet",
"magenta",
"deeppink",
"red4",
"orange",
"springgreen4"
))
# Point colours
if (all(is.na(point_col))) {
point_col <- densCols(fr.exprs[, channels],
colramp = col_scale
)
overlay_col <- cols(ovn)
if (all(is.na(legend_point_col))) {
legend_point_col <- c("blue", overlay_col)
}
overlay_col <- split(overlay_col, 1:ovn)
} else if (length(point_col) == 1) {
overlay_col <- cols(ovn)
if (is.na(point_col)) {
point_col <- densCols(fr.exprs[, channels],
colramp = col_scale
)
if (all(is.na(legend_point_col))) {
legend_point_col <- c("blue", overlay_col)
}
} else {
if (all(is.na(legend_point_col))) {
legend_point_col <- c(point_col, overlay_col)
}
}
overlay_col <- split(overlay_col, 1:ovn)
} else if (length(point_col) == smp) {
overlay_col <- point_col[-1]
point_col <- point_col[1]
if (is.na(point_col)) {
point_col[is.na(point_col)] <- densCols(fr.exprs[, channels],
colramp = col_scale
)
if (all(is.na(legend_point_col))) {
legend_point_col <- c("blue", overlay_col)
if (any(is.na(legend_point_col))) {
legend_point_col[match(NA, legend_point_col)] <- "blue"
}
}
} else {
if (all(is.na(legend_point_col))) {
legend_point_col <- c(point_col, overlay_col)
}
if (any(is.na(legend_point_col))) {
legend_point_col[match(NA, legend_point_col)] <- "blue"
}
}
overlay_col <- split(overlay_col, 1:ovn)
if (any(is.na(overlay_col))) {
lapply(match(NA, overlay_col), function(x) {
overlay_col[[x]] <<- densCols(exprs(overlay[[x]])[, channels],
colramp = col_scale
)
})
}
} else if (length(point_col) != smp) {
if (length(point_col) < smp) {
overlay_col <- c(
point_col[-1],
cols(ovn - length(point_col[-1]))
)
point_col <- point_col[1]
if (any(is.na(point_col))) {
point_col[is.na(point_col)] <- densCols(fr.exprs[, channels],
colramp = col_scale
)
if (all(is.na(legend_point_col))) {
legend_point_col <- c("blue", overlay_col)
if (any(is.na(legend_point_col))) {
legend_point_col[match(NA, legend_point_col)] <- "blue"
}
}
} else {
if (all(is.na(legend_point_col))) {
legend_point_col <- c(point_col, overlay_col)
}
if (any(is.na(legend_point_col))) {
legend_point_col[match(NA, legend_point_col)] <- "blue"
}
}
overlay_col <- split(overlay_col, 1:ovn)
if (any(is.na(overlay_col))) {
lapply(match(NA, overlay_col), function(x) {
overlay_col[[x]] <<- densCols(exprs(overlay[[x]])[, channels],
colramp = col_scale
)
})
}
} else if (length(point_col) > smp) {
point_col <- point_col[1:smp]
overlay_col <- point_col[-1]
point_col <- point_col[1]
if (is.na(point_col)) {
point_col[is.na(point_col)] <- densCols(fr.exprs[, channels],
colramp = col_scale
)
if (all(is.na(legend_point_col))) {
legend_point_col <- c("blue", overlay_col)
if (any(is.na(legend_point_col))) {
legend_point_col[match(NA, legend_point_col)] <- "blue"
}
}
} else {
if (all(is.na(legend_point_col))) {
legend_point_col <- c(point_col, overlay_col)
}
if (any(is.na(legend_point_col))) {
legend_point_col[match(NA, legend_point_col)] <- "blue"
}
}
overlay_col <- split(overlay_col, 1:ovn)
if (any(is.na(overlay_col))) {
lapply(match(NA, overlay_col), function(x) {
overlay_col[[x]] <<- densCols(exprs(overlay[[x]])[, channels],
colramp = col_scale
)
})
}
}
}
# X Axis Title
if (is.na(xlab)) {
if (!is.na(fr.data$desc[which(fr.channels == channels[1])])) {
xlab <- paste(fr.data$desc[which(fr.channels == channels[1])],
channels[1],
sep = " "
)
} else if (is.na(fr.data$desc[which(fr.channels == channels[1])])) {
xlab <- paste(channels[1], sep = " ")
}
}
# Y Axis Title
if (is.na(ylab)) {
if (!is.na(fr.data$desc[which(fr.channels == channels[2])])) {
ylab <- paste(fr.data$desc[which(fr.channels == channels[2])],
channels[2],
sep = " "
)
} else if (is.na(fr.data$desc[which(fr.channels == channels[2])])) {
ylab <- paste(channels[2], sep = " ")
}
}
# Title
if (missing(title)) {
title <- fr@description$GUID
}
# Legend labels
if (missing(legend_text)) {
if (!is.null(overlay)) {
legend_text <- c(
fr@description$GUID,
unlist(lapply(overlay, function(fr) {
fr@description$GUID
}))
)
} else {
legend_text <- fr@description$GUID
}
}
# Number of gates
typ <- c("rectangleGate", "polygonGate", "ellipsoidGate", "filters")
if (class(gate) %in% typ) {
gates <- length(gate)
} else if (inherits(gate, "list")) {
if (all(unlist(lapply(gate, "class")) %in% typ)) {
gates <- length(gate)
} else if (all(unlist(lapply(gate, "class")) == "list")) {
gates <- length(gate[[1]])
}
} else if (!.valid_gates(gate, channels)) {
gates <- 0
}
# Get named list of arguments
args <- as.list(environment())
# Split arguments
args <- .arg_split(
x = args[-c(match(
c(
"x",
"fr",
"channels",
"axes_trans",
"overlay",
"gate",
"xlim",
"ylim",
"popup",
"limits",
"display",
"gates",
"typ",
"overlay_col",
"cols",
"col_scale",
"fr.data",
"fr.exprs",
"smp",
"ovn",
"ytext",
"xtext",
"axs",
"fr.channels"
),
names(args)
))],
channels = channels,
n = smp,
plots = 1,
layers = smp,
gates = gates
)
# Unlist arguments for single plot
args <- lapply(args, function(x) x[[1]])
# Pop-up
if (popup == TRUE) {
.cyto_plot_window()
}
# Plot margins
.cyto_plot_margins(
x = fr,
overlay = overlay,
legend = args[["legend"]],
legend_text = args[["legend_text"]],
title = args[["title"]]
)
# Plot
if (nrow(fr) < 2) {
graphics::plot(1,
type = "n",
axes = FALSE,
pch = args[["point_shape"]][1],
cex.pts = args[["point_size"]][1],
xlim = xlim,
ylim = ylim,
xlab = args[["xlab"]],
ylab = args[["ylab"]],
main = args[["title"]],
cex.axis = args[["axes_text_size"]],
col.axis = args[["axes_text_col"]],
cex.lab = args[["axes_label_text_size"]],
col.lab = args[["axes_label_text_col"]],
font.main = args[["title_text_font"]],
cex.main = args[["title_text_size"]],
col.main = args[["title_text_col"]],
bty = "n", ...
)
box(
which = "plot",
lty = args[["border_line_type"]],
lwd = args[["border_line_width"]],
col = args[["border_line_col"]]
)
} else {
if (is.null(xtext) & is.null(ytext)) {
graphics::plot(fr.exprs,
col = adjustcolor(point_col, args[["point_alpha"]][1]),
pch = args[["point_shape"]][1],
main = args[["title"]],
xlab = args[["xlab"]],
ylab = args[["ylab"]],
xlim = xlim,
ylim = ylim,
cex = args[["point_size"]][1],
cex.axis = args[["axes_text_size"]],
col.axis = args[["axes_text_col"]],
cex.lab = args[["axes_label_text_size"]],
col.lab = args[["axes_label_text_col"]],
font.main = args[["title_text_font"]],
cex.main = args[["title_text_size"]],
col.main = args[["title_text_col"]],
bty = "n", ...
)
box(
which = "plot",
lty = args[["border_line_type"]],
lwd = args[["border_line_width"]],
col = args[["border_line_col"]]
)
} else if (!is.null(xtext) & is.null(ytext)) {
graphics::plot(fr.exprs,
xaxt = "n",
col = adjustcolor(point_col, args[["point_alpha"]][1]),
pch = args[["point_shape"]][1],
main = args[["title"]],
xlab = args[["xlab"]],
ylab = args[["ylab"]],
xlim = xlim,
ylim = ylim,
cex = args[["point_size"]],
cex.axis = args[["axes_text_size"]],
col.axis = args[["axes_text_col"]],
cex.lab = args[["axes_label_text_size"]],
col.lab = args[["axes_label_text_col"]],
font.main = args[["title_text_font"]],
cex.main = args[["title_text_size"]],
col.main = args[["title_text_col"]],
bty = "n", ...
)
axis(1,
at = xtext$at,
labels = xtext$label,
font.axis = args[["axes_text_font"]],
col.axis = args[["axes_text_col"]],
cex.axis = args[["axes_text_size"]]
)
box(
which = "plot",
lty = args[["border_line_type"]],
lwd = args[["border_line_width"]],
col = args[["border_line_col"]]
)
} else if (is.null(xtext) & !is.null(ytext)) {
graphics::plot(fr.exprs,
yaxt = "n",
col = adjustcolor(point_col, args[["point_alpha"]][1]),
pch = args[["point_shape"]][1],
main = args[["title"]],
xlab = args[["xlab"]],
ylab = args[["ylab"]],
xlim = xlim,
ylim = ylim,
cex = args[["point_size"]],
cex.axis = args[["axes_text_size"]],
col.axis = args[["axes_text_col"]],
cex.lab = args[["axes_label_text_size"]],
col.lab = args[["axes_label_text_col"]],
font.main = args[["title_text_font"]],
cex.main = args[["title_text_size"]],
col.main = args[["title_text_col"]],
bty = "n", ...
)
axis(2,
at = ytext$at,
labels = ytext$label,
font.axis = args[["axes_text_font"]],
col.axis = args[["axes_text_col"]],
cex.axis = args[["axes_text_size"]]
)
box(
which = "plot",
lty = args[["border_line_type"]],
lwd = args[["border_line_width"]],
col = args[["border_line_col"]]
)
} else if (!is.null(xtext) & !is.null(ytext)) {
graphics::plot(fr.exprs,
xaxt = "n",
yaxt = "n",
col = adjustcolor(point_col, args[["point_alpha"]][1]),
pch = args[["point_shape"]][1],
main = args[["title"]],
xlab = args[["xlab"]],
ylab = args[["ylab"]],
xlim = xlim,
ylim = ylim,
cex = args[["point_size"]],
cex.axis = args[["axes_text_size"]],
col.axis = args[["axes_text_col"]],
cex.lab = args[["axes_label_text_size"]],
col.lab = args[["axes_label_text_col"]],
font.main = args[["title_text_font"]],
cex.main = args[["title_text_size"]],
col.main = args[["title_text_col"]],
bty = "n", ...
)
axis(1,
at = xtext$at,
labels = xtext$label,
font.axis = args[["axes_text_font"]],
col.axis = args[["axes_text_col"]],
cex.axis = args[["axes_text_size"]]
)
axis(2,
at = ytext$at,
labels = ytext$label,
font.axis = args[["axes_text_font"]],
col.axis = args[["axes_text_col"]],
cex.axis = args[["axes_text_size"]]
)
box(
which = "plot",
lty = args[["border_line_type"]],
lwd = args[["border_line_width"]],
col = args[["border_line_col"]]
)
}
}
# Contour Lines
if (args[["contour_lines"]] != 0) {
cyto_plot_contour(
x = fr,
channels = channels,
contour_lines = args[["contour_lines"]],
contour_line_type = args[["contour_line_type"]],
contour_line_width = args[["contour_line_width"]],
contour_line_col = args[["contour_line_col"]]
)
}
# Add overlays
if (!is.null(overlay)) {
cyto_plot_overlay(
x = overlay,
channels = channels,
point_shape = args[["point_shape"]][-1],
point_size = args[["point_size"]][-1],
point_col = overlay_col,
point_alpha = args[["point_alpha"]][-1]
)
}
# Add legend
if (!is.null(overlay) & args[["legend"]] == TRUE) {
# Legend position x
legend.x <- par("usr")[2] + 0.025 * par("usr")[2]
# Legend position y
legend.y <- mean(par("usr")[c(3, 4)])
legend.y <- legend.y + (((par("usr")[4]) / 21) * 0.5 * smp)
# Legend with points
if (!all(args[["point_alpha"]] == 1)) {
legend_point_col <- mapply(function(col, alpha) {
adjustcolor(col, alpha)
}, legend_point_col, args[["point_alpha"]])
}
legend(
x = legend.x,
y = legend.y,
legend = rev(args[["legend_text"]]),
col = rev(legend_point_col),
pch = rev(args[["point_shape"]]),
pt.cex = rev(2 * args[["point_size"]]),
xpd = TRUE,
bty = "n",
x.intersp = 0.5
)
}
# Valid gates supplied?
valid_gates <- .valid_gates(gate, channels)
# Gates
if (valid_gates) {
gate <- cyto_plot_gate(gate,
channels = channels,
gate_line_col = args[["gate_line_col"]],
gate_line_width = args[["gate_line_width"]],
gate_line_type = args[["gate_line_type"]]
)
}
# Labels
if (valid_gates & args[["label"]] == TRUE) {
cyto_plot_label(
x = fr,
channels = channels,
trans = axes_trans,
text = args[["label_text"]],
gates = gate,
stat = args[["label_stat"]],
text_x = args[["label_box_x"]],
text_y = args[["label_box_y"]],
text_size = args[["label_text_size"]],
text_font = args[["label_text_font"]],
text_col = args[["label_text_col"]],
box_alpha = args[["label_box_alpha"]]
)
# Labels without gates - 1 per layer
} else if (!valid_gates &
!all(is.na(args[["label_text"]])) &
args[["label"]]) {
# label # limited to # layers - arg_split
mapply(
function(label_text,
label_stat,
label_text_size,
label_text_font,
label_text_col,
label_box_x,
label_box_y,
label_box_alpha) {
if (label_stat == "percent") {
label_stat <- NA
}
suppressMessages(cyto_plot_label(
x = fr,
channels = channels,
gates = gate,
trans = axes_trans,
text = label_text,
stat = label_stat,
text_x = label_box_x,
text_y = label_box_y,
text_size = label_text_size,
text_font = label_text_font,
text_col = label_text_col,
box_alpha = label_box_alpha
))
}, args[["label_text"]],
args[["label_stat"]],
args[["label_text_size"]],
args[["label_text_font"]],
args[["label_text_col"]],
args[["label_box_x"]],
args[["label_box_y"]],
args[["label_box_alpha"]]
)
}
# Return options to default
options(scipen = 0)
# Return plot margins to default
par(mar = c(5, 4, 4, 2) + 0.1)
}
)
#' cyto_plot_2d - flowSet Method
#'
#' Visualise 2-D flow cytometry scatterplots with blue-red density colour scale
#' for a flowSet.
#'
#' @param x object of class \code{\link[flowCore:flowSet-class]{flowSet}}.
#' @param axes_trans object of class
#' \code{\link[flowCore:transformList-class]{transformList}} or
#' \code{\link[flowWorkspace]{transformerList}} generated by
#' \code{\link[flowCore:logicleTransform]{estimateLogicle}} which was used to
#' transform the fluorescent channels of the supplied flowFrame. This
#' transformation object will be used internally to ensure axes labels of the
#' plot are appropriately transformed. The transformation object will NOT be
#' applied to the flowFrame internally and should be applied to the flowFrame
#' prior to plotting.
#' @param overlay a \code{flowFrame}, \code{flowSet}, \code{list of flowFrames},
#' \code{list of flowSets} or \code{list of flowFrame lists} containing
#' populations to be overlaid onto the plot(s).
#' @param contour_lines numeric indicating the number of levels to use for
#' contour lines, set to 0 by default to turn off contour lines.
#' @param gate gate object(s) to be added to plot. Gates can be of class
#' \code{\link[flowCore:rectangleGate-class]{rectangleGate}},
#' \code{\link[flowCore:polygonGate-class]{polygonGate}} or
#' \code{\link[flowCore:ellipsoidGate-class]{ellipsoidGate}}. Multiple gates
#' of mixed classes can also be supplied in \code{list} or
#' \code{\link[flowCore:filters-class]{filters}} objects. Gates can also be
#' supplied on a per sample basis as a list of length samples, with each
#' element being a list of length gates containing the gates per sample.
#' @param group_by a vector of pData variables to sort and merge samples into
#' groups, set to FALSE by default to prevent merging. To merge all samples
#' set this argument to "all".
#' @param display numeric [0,1] to control the percentage of events to be
#' plotted. Specifying a value for \code{display} can substantial improve
#' plotting speed for less powerful machines.
#' @param layout a vector of the length 2 indicating the dimensions of the grid
#' for plotting \code{c(#rows, #columns)}.
#' @param popup logical indicating whether the plot should be constructed in a
#' pop-up window, set to FALSE by default. \code{popup} will open OS-specific
#' graphic device prior to plotting. Mac users will need to install
#' \href{https://www.xquartz.org/}{XQuartz} for this functionality.
#' @param limits indicates whether the axes limits should be based on the
#' \code{"data"} or \code{"machine"}, set to "machine" by default to show
#' complete axes ranges. This argument will only alter the upper axis limits,
#' to modify the lower limits use \code{xlim} and \code{ylim}.
#' @param xlim lower and upper limits of x axis (e.g. c(0,5)).
#' @param ylim lower and upper limits of y axis (e.g. c(0,5)).
#' @param title title to use for the plot, set to the name of the sample by
#' default.
#' @param xlab x axis label.
#' @param ylab y axis label.
#' @param point_shape point character to use for points, set to "." by default
#' to maximise plotting speed.
#' @param point_size numeric specifying the degree of character expansion for
#' points, set to 2 by default.
#' @param point_col colours to use for points, set to NA by default to blue-red
#' density colour scale.
#' @param point_alpha numeric [0,1] used to control colour transparency, set to
#' 1 by default to remove transparency.
#' @param contour_line_type type of line to use for contour lines, set to 1 by
#' default.
#' @param contour_line_width line width for contour lines, set to 2 by default.
#' @param contour_line_col colour to use for contour lines, set to "black" by
#' default.
#' @param axes_text_font numeric indicating the font to use for axes text, set
#' to 1 for plain font by default. See \code{\link[graphics:par]{?par}} font
#' for details.
#' @param axes_text_size character expansion for axis text.
#' @param axes_text_col colour of axis text.
#' @param axes_label_text_font numeric indicating the font to use for axes
#' labels, set to 1 for plain font by default. See
#' \code{\link[graphics:par]{?par}} font for details.
#' @param axes_label_text_size character expansion for axis labels.
#' @param axes_label_text_col colour of axis labels.
#' @param title_text_font numeric indicating the font to use for the title, set
#' to 2 for bold font by default. See \code{\link[graphics:par]{?par}} font
#' for details.
#' @param title_text_size character expansion for plot title.
#' @param title_text_col colour for plot title.
#' @param legend logical indicating whether a legend should be included for
#' plots including overlays, set to FALSE by default.
#' @param legend_text vector of labels to use for the legend.
#' @param legend_text_font numeric indicating the font to use for legend text,
#' set to 2 for bold font by default. See \code{\link[graphics:par]{?par}}
#' font for details.
#' @param legend_text_size character expansion for legend text, set to 1 by
#' default.
#' @param legend_text_col colour to use for legend text, set to "black by
#' default.
#' @param legend_point_col vector of colours to use for points in legend.
#' @param gate_line_type integer [0,6] which controls the line type, set to
#' \code{1} to draw solid lines by default.
#' @param gate_line_width numeric to adjust line thickness of gates, set to
#' \code{2.5} by default.
#' @param gate_line_col indicates the colour of the gate to be constructed, set
#' to \code{"red"} by default.
#' @param label logical indicating whether gated populations should be labelled.
#' If the names of the populations are supplied as the text.labels argument,
#' the population name and frequency will be included in the labels, otherwise
#' only the population frequencies will be included in the labels.
#' @param label_text vector of population names to use in labels.
#' @param label_stat indicates the type of statistic to include in the label,
#' can be either \code{"percent"} or \code{"count"}, set to \code{"percent"}
#' by default.
#' @param label_text_format indicates the type of text to include in the label,
#' can be either \code{"alias"}, \code{"percent"}, \code{"count"},
#' \code{c("alias","percent")} or \code{c("alias","count")}. Set to
#' \code{c("alias","percent")} by default.
#' @param label_text_font numeric indicating the font to use for labels, set to
#' 2 for bold font by default. See \code{\link[graphics:par]{?par}} font for
#' details.
#' @param label_text_size character expansion for label text, set to 0.8 by
#' default.
#' @param label_text_col colour of text used in labels, set to \code{"black"} by
#' default.
#' @param label_box_x x co-ordinate to manually adjust the position of the label
#' on the plot.
#' @param label_box_y y co-ordinate(s) to manually adjust the position of the
#' label(s) on the plot.
#' @param label_box_alpha numeric controlling backgropund fill transparency of
#' labels, set to 0.6 by default to introduce some transparency.
#' @param border_line_type line type to use for plot border, set to 1 by default
#' for a sold border.
#' @param border_line_width line width for plot border, set to 1 by default.
#' @param border_line_col line colour for plot border, set to "black" by
#' default.
#' @param ... additional arguments passed to \code{\link[graphics:plot]{plot}}.
#'
#' @examples
#' \dontrun{
#' library(CytoRSuiteData)
#' fs <- Activation
#'
#' cyto_plot_2d(fs,
#' channel = c("FSC-A", "SSC-A"),
#' overlay = fs[[2]],
#' point_col = c(NA, "purple")
#' )
#'
#' cyto_plot_2d(fs,
#' channel = c("FSC-A", "SSC-A"),
#' overlay = fs[[2]],
#' point_col = c("black", "red")
#' )
#' }
#'
#' @importFrom flowCore exprs parameters fsApply
#' @importFrom flowWorkspace pData sampleNames
#' @importFrom graphics plot axis title abline polygon contour legend points par
#' @importFrom grDevices densCols colorRampPalette n2mfrow
#' @importFrom methods as
#'
#' @author Dillon Hammill (Dillon.Hammill@anu.edu.au)
#'
#' @noRd
setMethod(.cyto_plot_2d,
signature = "flowSet",
definition = function(x,
channels,
axes_trans = NULL,
overlay = NULL,
contour_lines = 0,
gate = NA,
group_by = FALSE,
display = NULL,
layout = NULL,
popup = FALSE,
limits = "machine",
xlim = NULL,
ylim = NULL,
title,
xlab = NA,
ylab = NA,
point_shape = ".",
point_size = 2,
point_col = NA,
point_alpha = 1,
contour_line_type = 1,
contour_line_width = 1,
contour_line_col = "black",
axes_text_font = 1,
axes_text_size = 1,
axes_text_col = "black",
axes_label_text_font = 1,
axes_label_text_size = 1.1,
axes_label_text_col = "black",
title_text_font = 2,
title_text_size = 1.1,
title_text_col = "black",
legend = FALSE,
legend_text,
legend_text_font = 1,
legend_text_size = 1,
legend_text_col = "black",
legend_point_col = NA,
gate_line_type = 1,
gate_line_width = 2.5,
gate_line_col = "red",
label = TRUE,
label_text = NA,
label_stat = "percent",
label_text_font = 2,
label_text_size = 1,
label_text_col = "black",
label_box_x = NA,
label_box_y = NA,
label_box_alpha = 0.6,
border_line_type = 1,
border_line_width = 1,
border_line_col = "black", ...) {
# Prevent scientific notation
options(scipen = 999)
# Assign x to fr
fs <- x
# Label text supplied turn on labels
if(!all(is.na(label_text))){
label <- TRUE
}
# Refresh mfrow after plotting?
if (is.null(layout[1])) {
refresh <- TRUE
} else {
if (layout[1] == FALSE) {
refresh <- FALSE
} else {
refresh <- TRUE
}
}
# Assign x to fs
fs.channels <- BiocGenerics::colnames(fs)
# Sample names
fsnms <- sampleNames(fs)
# Check channels
channels <- cyto_channel_check(fs,
channels = channels,
plot = TRUE
)
# Transformation object
if (!is.null(axes_trans)) {
axes_trans <- cyto_trans_check(axes_trans,
inverse = FALSE
)
}
# X axis limits
if (is.null(xlim)) {
xlim <- suppressWarnings(.cyto_plot_limits(
x = fs,
channels = channels,
overlay = overlay,
limits = limits
)[[1]])
}
# Y axis limits
if (is.null(ylim)) {
ylim <- suppressWarnings(.cyto_plot_limits(
x = fs,
channels = channels,
overlay = overlay,
limits = limits
)[[2]])
}
# group_by?
if (group_by[1] != FALSE) {
# group_by set to TRUE
if (group_by[1] == TRUE) {
group_by <- "all"
}
# Return a list of merged flowFrames - sample later
fr.lst <- .cyto_merge(
x = fs,
group_by = group_by,
display = NULL
)
smp <- length(fr.lst)
# Title
if (missing(title)) {
if (group_by[1] == "all") {
title <- "Combined Events"
} else {
title <- names(fr.lst)
}
}
# overlay - keep sampling for cyto_plot flowFrame method
if (!is.null(overlay)) {
overlay <- .cyto_overlay_check(
x = fs,
overlay = overlay,
display = NULL
)
# list of flowFrame lists to overlay (1 per group)
overlay <- .cyto_overlay_merge(
x = fs,
overlay = overlay,
group_by = group_by,
display = NULL
)
}
} else if (group_by[1] == FALSE) {
# Number of samples
smp <- length(fs)
# Convert fs to list of flowFrames - sample at cyto_plot flowFrame method
fr.lst <- lapply(seq(1, length(fs), 1), function(x) fs[[x]])
names(fr.lst) <- fsnms
# Titles
if (missing(title)) {
title <- names(fr.lst)
}
# Overlays - keep sampling for cyto_plot flowFrame method
if (!is.null(overlay)) {
overlay <- .cyto_overlay_check(
x = fs,
overlay = overlay,
display = NULL
)
}
}
# Gates
if (.valid_gates(gate, channels)) {
gate <- .cyto_gate_check(gate, length(fr.lst))
}
# Number of overlays per plot
if (is.null(overlay)) {
ovn <- 0
} else {
ovn <- length(overlay[[1]])
}
# Legend text
if (missing(legend_text)) {
legend_text <- paste0("layer", 1:(ovn + 1))
}
# popup
if (popup == TRUE) {
.cyto_plot_window()
}
# Plot layout
if (is.null(layout)) {
layout <- .cyto_plot_layout(
x = fr.lst,
layout = layout
)
# Set plot space
par(mfrow = layout)
} else if (all(layout == FALSE)) {
layout <- par("mfrow")
} else {
par(mfrow = layout)
}
# Plot space
np <- layout[1] * layout[2]
# Number of gates
typ <- c(
"rectangleGate",
"polygonGate",
"ellipsoidGate",
"filters"
)
if (class(gate) %in% typ) {
gates <- length(gate)
} else if (inherits(gate, "list")) {
if (all(unlist(lapply(gate, "class")) %in% typ)) {
gates <- length(gate)
} else if (all(unlist(lapply(gate, "class")) == "list")) {
gates <- length(gate[[1]])
}
} else if (!.valid_gates(gate, channels)) {
gates <- 0
}
# Get named list of arguments
args <- as.list(environment())
# Split arguments
args <- .arg_split(
x = args[-c(match(
c(
"x",
"fs",
"channels",
"axes_trans",
"overlay",
"gate",
"xlim",
"ylim",
"popup",
"limits",
"layout",
"group_by",
"display",
"gates",
"typ",
"np",
"ovn",
"fr.lst",
"fsnms",
"fs.channels",
"refresh"
),
names(args)
))],
channels = channels,
n = (length(fr.lst) + ovn * (length(fr.lst))),
plots = length(fr.lst),
layers = ovn + 1,
gates = gates
)
# Plots
if (is.null(overlay)) {
cnt <- 0
mapply(
function(fr,
gate,
xlab,
ylab,
title,
title_text_font,
title_text_size,
title_text_col,
point_col,
point_shape,
point_size,
point_alpha,
contour_lines,
contour_line_type,
contour_line_width,
contour_line_col,
axes_text_font,
axes_text_size,
axes_text_col,
axes_label_text_font,
axes_label_text_size,
axes_label_text_col,
legend,
legend_text,
legend_text_font,
legend_text_size,
legend_text_col,
legend_point_col,
gate_line_type,
gate_line_width,
gate_line_col,
label,
label_text,
label_stat,
label_text_font,
label_text_size,
label_text_col,
label_box_x,
label_box_y,
label_box_alpha,
border_line_type,
border_line_width,
border_line_col) {
cnt <<- cnt + 1
.cyto_plot_2d(
x = fr,
channels = channels,
display = display,
axes_trans = axes_trans,
gate = gate,
xlim = xlim,
ylim = ylim,
xlab = xlab,
ylab = ylab,
title = title,
title_text_font = title_text_font,
title_text_size = title_text_size,
title_text_col = title_text_col,
point_col = point_col,
point_shape = point_shape,
point_size = point_size,
point_alpha = point_alpha,
axes_text_font = axes_text_font,
axes_text_size = axes_text_size,
axes_text_col = axes_text_col,
axes_label_text_font = axes_label_text_font,
contour_lines = contour_lines,
contour_line_type = contour_line_type,
contour_line_width = contour_line_width,
contour_line_col = contour_line_col,
axes_label_text_size = axes_label_text_size,
axes_label_text_col = axes_label_text_col,
legend = legend,
legend_text = legend_text,
legend_text_font = legend_text_font,
legend_text_size = legend_text_size,
legend_text_col = legend_text_col,
legend_point_col = legend_point_col,
gate_line_type = gate_line_type,
gate_line_width = gate_line_width,
gate_line_col = gate_line_col,
label = label,
label_text = label_text,
label_stat = label_stat,
label_text_font = label_text_font,
label_text_size = label_text_size,
label_text_col = label_text_col,
label_box_x = label_box_x,
label_box_y = label_box_y,
label_box_alpha = label_box_alpha,
border_line_type = border_line_type,
border_line_width = border_line_width,
border_line_col = border_line_col, ...
)
if (popup == TRUE & cnt %% np == 0 & length(fr.lst) > cnt) {
.cyto_plot_window()
par(mfrow = layout)
}
}, fr.lst,
gate, args[["xlab"]],
args[["ylab"]],
args[["title"]],
args[["title_text_font"]],
args[["title_text_size"]],
args[["title_text_col"]],
args[["point_col"]],
args[["point_shape"]],
args[["point_size"]],
args[["point_alpha"]],
args[["contour_lines"]],
args[["contour_line_type"]],
args[["contour_line_width"]],
args[["contour_line_col"]],
args[["axes_text_font"]],
args[["axes_text_size"]],
args[["axes_text_col"]],
args[["axes_label_text_font"]],
args[["axes_label_text_size"]],
args[["axes_label_text_col"]],
args[["legend"]],
args[["legend_text"]],
args[["legend_text_font"]],
args[["legend_text_size"]],
args[["legend_text_col"]],
args[["legend_point_col"]],
args[["gate_line_type"]],
args[["gate_line_width"]],
args[["gate_line_col"]],
args[["label"]],
args[["label_text"]],
args[["label_stat"]],
args[["label_text_font"]],
args[["label_text_size"]],
args[["label_text_col"]],
args[["label_box_x"]],
args[["label_box_y"]],
args[["label_box_alpha"]],
args[["border_line_type"]],
args[["border_line_width"]],
args[["border_line_col"]]
)
} else if (!is.null(overlay)) {
cnt <- 0
mapply(
function(fr,
gate,
overlay,
xlab,
ylab,
title,
title_text_font,
title_text_size,
title_text_col,
point_col,
point_shape,
point_size,
point_alpha,
contour_lines,
contour_line_type,
contour_line_width,
contour_line_col,
axes_text_font,
axes_text_size,
axes_text_col,
axes_label_text_font,
axes_label_text_size,
axes_label_text_col,
legend,
legend_text,
legend_text_font,
legend_text_size,
legend_text_col,
legend_point_col,
gate_line_type,
gate_line_width,
gate_line_col,
label, label_text,
label_stat,
label_text_font,
label_text_size,
label_text_col,
label_box_x,
label_box_y,
label_box_alpha,
border_line_type,
border_line_width,
border_line_col) {
cnt <<- cnt + 1
.cyto_plot_2d(
x = fr,
channels = channels,
display = display,
axes_trans = axes_trans,
overlay = overlay,
gate = gate,
xlim = xlim,
ylim = ylim,
xlab = xlab,
ylab = ylab,
title = title,
title_text_font = title_text_font,
title_text_size = title_text_size,
title_text_col = title_text_col,
contour_lines = contour_lines,
contour_line_type = contour_line_type,
contour_line_width = contour_line_width,
contour_line_col = contour_line_col,
point_col = point_col,
point_shape = point_shape,
point_size = point_size,
point_alpha = point_alpha,
axes_text_font = axes_text_font,
axes_text_size = axes_text_size,
axes_text_col = axes_text_col,
axes_label_text_font = axes_label_text_font,
axes_label_text_size = axes_label_text_size,
axes_label_text_col = axes_label_text_col,
legend = legend,
legend_text = legend_text,
legend_text_font = legend_text_font,
legend_text_size = legend_text_size,
legend_text_col = legend_text_col,
legend_point_col = legend_point_col,
gate_line_type = gate_line_type,
gate_line_width = gate_line_width,
gate_line_col = gate_line_col,
label = label,
label_text = label_text,
label_stat = label_stat,
label_text_font = label_text_font,
label_text_size = label_text_size,
label_text_col = label_text_col,
label_box_x = label_box_x,
label_box_y = label_box_y,
label_box_alpha = label_box_alpha,
border_line_type = border_line_type,
border_line_width = border_line_width,
border_line_col = border_line_col, ...
)
if (popup == TRUE &
cnt %% np == 0 &
length(fr.lst) > cnt) {
.cyto_plot_window()
par(mfrow = layout)
}
}, fr.lst,
gate,
overlay,
args[["xlab"]],
args[["ylab"]],
args[["title"]],
args[["title_text_font"]],
args[["title_text_size"]],
args[["title_text_col"]],
args[["point_col"]],
args[["point_shape"]],
args[["point_size"]],
args[["point_alpha"]],
args[["contour_lines"]],
args[["contour_line_type"]],
args[["contour_line_width"]],
args[["contour_line_col"]],
args[["axes_text_font"]],
args[["axes_text_size"]],
args[["axes_text_col"]],
args[["axes_label_text_font"]],
args[["axes_label_text_size"]],
args[["axes_label_text_col"]],
args[["legend"]],
args[["legend_text"]],
args[["legend_text_font"]],
args[["legend_text_size"]],
args[["legend_text_col"]],
args[["legend_point_col"]],
args[["gate_line_type"]],
args[["gate_line_width"]],
args[["gate_line_col"]],
args[["label"]],
args[["label_text"]],
args[["label_stat"]],
args[["label_text_font"]],
args[["label_text_size"]],
args[["label_text_col"]],
args[["label_box_x"]],
args[["label_box_y"]],
args[["label_box_alpha"]],
args[["border_line_type"]],
args[["border_line_width"]],
args[["border_line_col"]]
)
}
# Return mfrow to default
if (refresh == TRUE) {
par(mfrow = c(1, 1))
}
# Return options to default
options(scipen = 0)
}
)
#' Split arguments for cyto_plot
#'
#' @param x list of arguments
#' @param channels vector of channels used to construct the plot
#' @param n total number of layers
#' @param plots number of plots
#' @param layers number of layers per plot
#' @param gates number of gates per plot
#'
#' @author Dillon Hammill (Dillon.Hammill@anu.edu.au)
#'
#' @noRd
.arg_split <- function(x,
channels,
n,
plots,
layers,
gates) {
# Arguments per plot cyto_plot_1d/cyto_plot_2d
args <- c(
"xlab",
"ylab",
"title",
"title_text_font",
"title_text_size",
"title_text_col",
"density_stack",
"axes_text_font",
"axes_text_size",
"axes_text_col",
"axes_label_text_font",
"axes_label_text_size",
"axes_label_text_col",
"legend",
"legend_text_size",
"label",
"border_line_type",
"border_line_width",
"border_line_col",
"contour_lines",
"contour_line_type",
"contour_line_width",
"contour_line_col"
)
lapply(args, function(arg) {
if (arg %in% names(x)) {
res <- rep(x[[arg]], length.out = plots)
if (plots == 1) {
res <- list(res)
} else {
res <- split(res, rep(1:plots, length.out = plots))
}
x[[arg]] <<- res
}
})
# Arguments per layer
args <- c(
"density_fill",
"density_fill_alpha",
"density_line_type",
"density_line_width",
"density_line_col",
"legend_text",
"legend_text_font",
"legend_text_col",
"legend_line_col",
"legend_box_fill",
"legend_point_col",
"point_shape",
"point_size",
"point_col",
"point_alpha"
)
lapply(args, function(arg) {
if (arg %in% names(x)) {
res <- rep(x[[arg]], length.out = n)
if (plots == 1) {
res <- list(res)
} else {
res <- split(res, rep(1:plots, length.out = n, each = layers))
}
x[[arg]] <<- res
}
})
# Arguments per gate
args <- c("gate_line_type", "gate_line_width", "gate_line_col")
if (gates != 0) {
lapply(args, function(arg) {
if (arg %in% names(x)) {
res <- rep(x[[arg]], length.out = gates * plots)
if (plots == 1) {
res <- list(res)
} else {
res <- split(res, rep(1:plots,
length.out = gates * plots,
each = gates
))
}
x[[arg]] <<- res
}
})
}
# cyto_plot_1d
if (length(channels) == 1) {
# Arguments per label
args <- c(
"label_text",
"label_stat",
"label_text_font",
"label_text_size",
"label_text_col",
"label_box_x",
"label_box_y",
"label_box_alpha"
)
lapply(args, function(arg) {
if (arg %in% names(x)) {
if (gates != 0) {
res <- rep(x[[arg]], length.out = gates * plots * layers)
if (plots == 1) {
res <- list(res)
} else {
res <- split(res, rep(1:plots,
length_out = gates * plots * layers,
each = gates * layers
))
}
x[[arg]] <<- res
# labels without gates
} else {
res <- rep(x[[arg]], length.out = n)
if (plots == 1) {
res <- list(res)
} else {
res <- split(res, rep(1:plots,
length_out = n,
each = layers
))
}
x[[arg]] <<- res
}
}
})
# cyto_plot_2d
} else if (length(channels) == 2) {
# Arguments per gate
args <- c(
"label_text",
"label_stat",
"label_text_font",
"label_text_size",
"label_text_col",
"label_box_x",
"label_box_y",
"label_box_alpha"
)
if (gates != 0) {
lapply(args, function(arg) {
if (arg %in% names(x)) {
res <- rep(x[[arg]],
length.out = gates * plots
)
if (plots == 1) {
res <- list(res)
} else {
res <- split(res, rep(1:plots,
length.out = gates * plots,
each = gates
))
}
x[[arg]] <<- res
}
})
# No gates expect 1 label per layer
} else if (gates == 0) {
lapply(args, function(arg) {
if (arg %in% names(x)) {
res <- rep(x[[arg]], length.out = n)
if (plots == 1) {
res <- list(res)
} else {
res <- split(res, rep(1:plots,
length_out = n,
each = layers
))
}
x[[arg]] <<- res
}
})
}
}
return(x)
}
#' Check if supplied gates are valid
#'
#' @param x gate object(s) to check.
#' @param channels channel(s) used to construct the plot.
#'
#' @noRd
.valid_gates <- function(x,
channels) {
# 1-D plots only accept rectangleGates
if (length(channels) == 1) {
# Valid gates supplied?
if (inherits(x, "rectangleGate") | inherits(x, "filters")) {
valid_gates <- TRUE
} else if (inherits(x, "list")) {
if (all(unlist(lapply(x, "class")) %in%
c("rectangleGate", "filters"))) {
valid_gates <- TRUE
} else if (all(unlist(lapply(x, "class")) == "list")) {
if (all(unlist(lapply(x, function(y) {
lapply(y, "class")
})) %in% c("rectangleGate", "filters"))) {
valid_gates <- TRUE
} else {
valid_gates <- FALSE
}
} else {
valid_gates <- FALSE
}
} else if (inherits(x, "filtersList")) {
valid_gates <- TRUE
} else {
valid_gates <- FALSE
}
} else if (length(channels) == 2) {
# Supported gates
typ <- c(
"rectangleGate",
"polygonGate",
"ellipsoidGate",
"filters"
)
# Valid gates supplied?
if (inherits(x, "rectangleGate") |
inherits(x, "polygonGate") |
inherits(x, "ellipsoidGate") |
inherits(x, "filters")) {
valid_gates <- TRUE
} else if (inherits(x, "list")) {
if (all(unlist(lapply(x, "class")) %in% typ)) {
valid_gates <- TRUE
} else if (all(unlist(lapply(x, "class")) == "list")) {
if (all(unlist(lapply(x, function(y) {
lapply(y, "class")
})) %in% typ)) {
valid_gates <- TRUE
} else {
valid_gates <- FALSE
}
} else {
valid_gates <- FALSE
}
} else if (inherits(x, "filtersList")) {
valid_gates <- TRUE
} else {
valid_gates <- FALSE
}
}
return(valid_gates)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.