Skip to contents

Visualize differentially expressed genes

Usage

VizDEGs(
  markers,
  object = NULL,
  plot_type = c("volcano", "volcano_log2fc", "volcano_pct", "jitter", "jitter_log2fc",
    "jitter_pct", "heatmap_log2fc", "heatmap_pct", "dot_log2fc", "dot_pct", "heatmap",
    "violin", "box", "bar", "ridge", "dot"),
  each = NULL,
  facet_each = FALSE,
  p_adjust = TRUE,
  cutoff = NULL,
  order_by = "desc(abs(avg_log2FC))",
  select = ifelse(plot_type %in% c("volcano", "volcano_log2fc", "volcano_pct",
    "jitter", "jitter_log2fc", "jitter_pct", "heatmap_log2fc", "heatmap_pct"), 5, 10),
  outprefix = NULL,
  devpars = list(res = 100),
  more_formats = c(),
  save_code = FALSE,
  log = NULL,
  log_prefix = "",
  cache = NULL,
  ...
)

Arguments

markers

A data frame of differential expression results, typically the output of Seurat::FindMarkers() or Seurat::FindAllMarkers(). Must contain columns "gene" (or gene symbols as rownames), "p_val", and "avg_log2FC". For percentage-based plots (volcano_pct, jitter_pct, heatmap_pct, dot_pct), columns "pct.1" and "pct.2" are also required.

object

A Seurat object. Required for expression-based plot types: "heatmap", "violin", "box", "bar", "ridge", and "dot". Not used for DE summary plot types. Default: NULL.

plot_type

The type of plot to generate. One of "volcano", "volcano_log2fc", "volcano_pct", "jitter", "jitter_log2fc", "jitter_pct", "heatmap_log2fc", "heatmap_pct", "dot_log2fc", "dot_pct", "heatmap", "violin", "box", "bar", "ridge", or "dot". See Description for details on each type.

each

A column name in markers indicating the grouping from which each marker was identified (e.g., the cluster column from FindAllMarkers()). Required for jitter and DE heatmap/dot plot types, where it defines the x-axis or column groups. For volcano plot types, it splits the plot by group (or facets it, with facet_each = TRUE). For expression plot types, each is used to select the markers within each group; a plain column name does not split the plot — use the "marker_column:metadata_column" syntax (see Metadata column mapping) to also split the plot by the mapped metadata column. Alternatively, pass ":metadata_column" with an empty marker part to split the expression plot by the metadata column directly, without selecting markers per group (markers are selected overall) and without merging metadata. Default: NULL.

facet_each

Logical. Only for volcano plot types: if TRUE, facet the volcano plot by the each groups instead of splitting it into separate subplots. Ignored for other plot types. Default: FALSE.

p_adjust

Logical. If TRUE (default), use adjusted p-value (p_val_adj column) for significance calculations and y-axis transformations. If FALSE, use raw p-value (p_val column).

cutoff

Numeric. The p-value (or adjusted p-value, depending on p_adjust) threshold for labeling significance. For volcano plots, sets y_cutoff. For DE heatmap plots (heatmap_log2fc, heatmap_pct), controls which cells receive significance marks. For expression plot types with a numeric select, only markers with a p-value below cutoff are eligible for selection. Ignored by DE dot plots (dot_log2fc, dot_pct). Default: NULL (no cutoff; defaults to 0.05 for volcano plots).

order_by

A string of one or more comma-separated expressions used to order the markers (evaluated with dplyr::arrange()). Can reference columns in markers as well as metadata columns merged in via a colon-form each (see Metadata column mapping). Only the first value of each merged metadata column is kept. Example: "desc(avg_log2FC)" or "desc(avg_log2FC), desc(pct.1)". The ordering determines which markers are selected when select is numeric. For jitter plots, it is also passed to plotthis::JitterPlot(). Default: "desc(abs(avg_log2FC))".

select

How to select markers for display or labeling. See Marker selection and filtering section for full details.

  • Numeric: Top N markers per each group, or overall when each is NULL (default: 5 for volcano/jitter types and for expression plot types when each selects markers per group, 10 otherwise).

  • Single expression: Filter condition for dplyr::filter().

  • Character vector of multiple expressions (DE heatmap/dot plot types only): expressions mentioning the each column name filter the overall data, others filter within the remaining data.

outprefix

Prefix of the output file

devpars

List of parameters to save the plot

more_formats

Additional formats to save the plot in addition to 'png'

save_code

Whether to save the code to reproduce the plot

log

A logger object

log_prefix

Prefix to add to the log messages

cache

Directory to cache the plot. Default to gettempdir()

...

Arguments passed on to scplotter::MarkersPlot

group_by

Used only for expression-based plot types (ignored for DE summary plot types). A column in the Seurat object's metadata to group cells by, e.g., a condition column — useful when the DEs were calculated between conditions (such as cell cycle phases) and you want to compare the expression of the markers across those conditions. A single value is passed directly to FeatureStatPlot: for heatmap and dot plots it is applied as the column annotation (ident), and it only takes effect when each includes a metadata column mapping; for violin, box, bar, and ridge plots it is passed as group_by. The "marker_column:metadata_column" syntax (see Metadata column mapping) restricts the object to only the cells involved in the comparisons: for example, if a comparison column in the markers data frame holds "G1:G2M", passing group_by = "comparison:Phase" keeps only G1 and G2M cells in the plot, with the Phase column re-factored to these two levels in the order they first appear in the comparison column. Without the restriction, e.g., group_by = "Phase", all phase cells (G1, G2M, and S) are included in the plot. Default: NULL.

show_labels

Logical. For heatmap_log2fc and heatmap_pct plot types only. If TRUE, display numeric values in heatmap cells. When combined with cutoff, both values and significance marks are shown. Default: FALSE.

sig_mark

Character. The symbol or compound mark used to annotate statistically significant cells in heatmap_log2fc and heatmap_pct plots. Must be a valid ComplexHeatmap mark: single characters ("-", "|", "+", "/", "\\", "x", "o") or compound marks ("[*]", "<*>", "(*)", "{*}"). Note that "*" conflicts with show_labels = TRUE because both use the label layer — use a compound mark instead. Default: "*".

flatten_markers

Logical. Only for the expression heatmap and dot plot types. When each is used to select markers per group, the markers are by default provided to FeatureStatPlot as a named list (one entry per group), which splits the feature rows of the plot by group. With flatten_markers = TRUE, the selected markers are collapsed into a single vector so the plot shows one unsplit block of features — useful e.g. to mimic Seurat::DoHeatmap() on globally selected markers. Default: FALSE.

Value

A ggplot object if 'outprefix' is NULL, otherwise, save the plot to the output directory

Examples

# \donttest{
degs <- RunSeuratDEAnalysis(scplotter::pancreas_sub, "SubCellType")
#> 
VizDEGs(degs, plot_type = "volcano_pct")

VizDEGs(degs, plot_type = "volcano_log2fc")

VizDEGs(degs, plot_type = "jitter_log2fc", each = "SubCellType")
#> Warning: [JitterPlot] `raster` is ignored when `size_by` is mapped to a column; falling back to vector points.

VizDEGs(degs,
    plot_type = "heatmap_log2fc", cutoff = 0.05,
    select = 5, each = "SubCellType"
)

# mimic Seurat's DoHeatmap()
top_degs <- degs[order(degs$avg_log2FC, decreasing = TRUE), ]
Seurat::DoHeatmap(scplotter::pancreas_sub, features = unique(top_degs$gene)[1:10],
   slot = "data", group.by = "SubCellType")

VizDEGs(degs,
    object = scplotter::pancreas_sub,
    layer = "data", plot_type = "heatmap",
    # Make the heatmap cells filled with bars
    cell_type = "bars",
    # Make sure "select" the top (positive) DEGs by avg_log2FC
    order_by = "desc(avg_log2FC)",  select = 10,
    # Select overall top 10 DEGs for each SubCellType (empty name before :)
    # But use the SubCellType for column splits
    each = ":SubCellType",
    # Column names/title
    show_column_names = "inplace", column_names_side = "top", column_title_rot = 45,
    column_annotation = list(.column = list(name = FALSE)),
    # Row names
    row_names_side = "left", row_annotation = list(.row = list(name = FALSE)),
)
#> Warning: Layer counts isn't present in the assay object; returning NULL


# Suppose we did comparison between G2M and S phase in each SubCellType
degs$Phase <- "G2M:S"

VizDEGs(degs,
    object = scplotter::pancreas_sub, plot_type = "violin",
    position_dodge_preserve = "single",
    select = 2, group_by = "Phase:Phase", each = "SubCellType:SubCellType"
)
#> Warning: Layer counts isn't present in the assay object; returning NULL
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.
#> Warning: Groups with fewer than two datapoints have been dropped.
#> ℹ Set `drop = FALSE` to consider such groups for position adjustment purposes.

VizDEGs(degs,
    object = scplotter::pancreas_sub, plot_type = "box",
    select = 2, group_by = "Phase", each = "SubCellType:SubCellType"
)
#> Warning: Layer counts isn't present in the assay object; returning NULL

VizDEGs(degs,
    object = scplotter::pancreas_sub, plot_type = "bar",
    position_dodge_preserve = "single",
    select = 2, group_by = "Phase:Phase", each = "SubCellType:SubCellType"
)
#> Warning: Layer counts isn't present in the assay object; returning NULL

VizDEGs(degs,
    object = scplotter::pancreas_sub, plot_type = "ridge",
    select = 1, group_by = "Phase:Phase", each = "SubCellType:SubCellType"
)
#> Warning: Layer counts isn't present in the assay object; returning NULL
#> Picking joint bandwidth of 0.107
#> Picking joint bandwidth of 0.14
#> Picking joint bandwidth of 0.488
#> Picking joint bandwidth of 0.312
#> Picking joint bandwidth of 0.119
#> Picking joint bandwidth of 0.305
#> Picking joint bandwidth of 0.285
#> Picking joint bandwidth of 0.174
#> Picking joint bandwidth of 0.412
#> Picking joint bandwidth of 0.137
#> Picking joint bandwidth of 0.576
#> Picking joint bandwidth of 0.378
#> Picking joint bandwidth of 0.776
#> Picking joint bandwidth of 0.382
#> Picking joint bandwidth of 0.348
#> Picking joint bandwidth of 0.31
#> Picking joint bandwidth of 0.0552
#> Picking joint bandwidth of 0.0994
#> Picking joint bandwidth of 0.232
#> Picking joint bandwidth of 0.0465
#> Picking joint bandwidth of 0.221
#> Picking joint bandwidth of 0.212
#> Picking joint bandwidth of 0.265
#> Picking joint bandwidth of 0.102
#> Picking joint bandwidth of 0.783
#> Picking joint bandwidth of 0.783
#> Picking joint bandwidth of 0.27
#> Picking joint bandwidth of 0.783
#> Picking joint bandwidth of 0.119
#> Picking joint bandwidth of 0.783
#> Picking joint bandwidth of 0.783
#> Picking joint bandwidth of 0.27
#> Warning: No shared levels found between `names(values)` of the manual scale and the
#> data's fill values.
#> Picking joint bandwidth of 0.107
#> Picking joint bandwidth of 0.14
#> Picking joint bandwidth of 0.488
#> Picking joint bandwidth of 0.312
#> Picking joint bandwidth of 0.119
#> Picking joint bandwidth of 0.305
#> Picking joint bandwidth of 0.285
#> Picking joint bandwidth of 0.174
#> Picking joint bandwidth of 0.412
#> Picking joint bandwidth of 0.137
#> Picking joint bandwidth of 0.576
#> Picking joint bandwidth of 0.378
#> Picking joint bandwidth of 0.776
#> Picking joint bandwidth of 0.382
#> Picking joint bandwidth of 0.348
#> Picking joint bandwidth of 0.31
#> Picking joint bandwidth of 0.0552
#> Picking joint bandwidth of 0.0994
#> Picking joint bandwidth of 0.232
#> Picking joint bandwidth of 0.0465
#> Picking joint bandwidth of 0.221
#> Picking joint bandwidth of 0.212
#> Picking joint bandwidth of 0.265
#> Picking joint bandwidth of 0.102
#> Picking joint bandwidth of 0.783
#> Picking joint bandwidth of 0.783
#> Picking joint bandwidth of 0.27
#> Picking joint bandwidth of 0.783
#> Picking joint bandwidth of 0.119
#> Picking joint bandwidth of 0.783
#> Picking joint bandwidth of 0.783
#> Picking joint bandwidth of 0.27
#> Warning: No shared levels found between `names(values)` of the manual scale and the
#> data's fill values.

VizDEGs(degs,
    object = scplotter::pancreas_sub, plot_type = "heatmap", select = 3,
    cluster_columns = FALSE, group_by = "Phase:Phase", each = "SubCellType:SubCellType"
)
#> Warning: Layer counts isn't present in the assay object; returning NULL

VizDEGs(degs,
    object = scplotter::pancreas_sub, plot_type = "dot",
    select = 1, group_by = "Phase:Phase", each = "SubCellType:SubCellType"
)
#> Warning: Layer counts isn't present in the assay object; returning NULL

# }