plot_cluster_omic_profile: Plot per-cluster omics profiles

View source: R/plot_cluster_omic_profile.R

plot_cluster_omic_profileR Documentation

Plot per-cluster omics profiles

Description

Shows which omics features distinguish the latent clusters, and in which direction, for an early, parallel or serial fit. A parallel or serial model produces one plot per omics layer, returned as a named list, so no figure has to accommodate every layer at once.

The default rendering is a cluster-by-feature heatmap in the style used for single-cell cluster markers: features on the vertical axis ordered by how strongly they separate the clusters, clusters across the top, and fill showing how high or low each cluster sits for that feature.

Usage

plot_cluster_omic_profile(
  x,
  type = c("heatmap", "bar"),
  top_n = 10,
  importance = c("separation", "range", "sd"),
  layer_names = NULL,
  layer_colors = NULL,
  cluster_labels = NULL,
  scale = TRUE
)

Arguments

x

A fitted LUCID model: early_lucid, lucid_parallel or lucid_serial.

type

"heatmap" (default) or "bar".

top_n

Number of features to show per panel, default 10. A layer with fewer features than this shows all of them rather than erroring.

importance

Ranking measure; see Which features are shown.

layer_names

Character vector of layer or stage names, used as plot subtitles. Defaults to the names of the omics list the model was fitted to, falling back to "Layer 1", "Layer 2" and so on.

layer_colors

One colour per layer. The heatmap uses it as the high end of its diverging scale, and the bar plot as the darkest of a sequential ramp across clusters – which is what lets the bar plot handle any number of clusters without recycling colours.

cluster_labels

Optional labels for the clusters, defaulting to "Cluster 1", "Cluster 2" and so on. Must have one entry per cluster.

scale

If TRUE (default) the fill is a per-feature z-score across clusters; if FALSE it is the fitted cluster mean. At K = 2 the default instead centres without rescaling, because a two-value z-score is degenerate – see What the colour means.

Value

A named list of ggplot objects, one per omics layer – length one for an early fit. Each carries the data it drew as the attribute "profile_data": a data frame of feature, cluster, value (what is plotted), mean (the fitted cluster mean), sd (within-cluster standard deviation) and score (the importance value the ranking used), so the ranking can be extracted without recomputing it. That data frame also carries a "centred" attribute recording whether the fill was centred rather than z-scored, which is what happens by default at K = 2.

Which features are shown

Only the top_n most discriminating features per panel are drawn, ranked by importance:

"separation" (default)

The spread of the cluster means divided by the typical within-cluster spread, \mathrm{sd}_k(\mu_{kj}) / \sqrt{\overline{\sigma^2_{kj}}}. This is the only option that accounts for noise: a feature whose cluster means differ by two units is uninformative if its within-cluster standard deviation is also two. It is scale-free, so features on different scales are comparable, and it is defined the same way for any number of clusters.

"range"

\max_k \mu_{kj} - \min_k \mu_{kj}, in the data's own units. The most directly interpretable, and the quantity the package's own feature selection thresholds.

"sd"

The standard deviation of the cluster means, without standardizing by within-cluster spread.

A feature the model deselected has identical means across clusters and so scores zero under all three, sorting last.

What the colour means

With scale = TRUE (the default) the fill is a z-score computed across clusters within each feature, so the palette is centred at zero and a feature's own baseline does not dominate. With scale = FALSE the fill is the fitted cluster mean on the data's original scale.

Two clusters are a special case. A z-score over two values is always exactly \pm 1/\sqrt{2}, so at K = 2 every tile would saturate and the fill would carry the sign of the difference but nothing about its size. When K = 2 and scale is left at its default, the fill is therefore centred without rescaling – each cluster mean minus that feature's average across clusters – which keeps the palette diverging while restoring magnitude. Passing scale = TRUE explicitly overrides this and gives the degenerate z-score. The legend always names whichever quantity was used, and the returned data records it in the "centred" attribute.

The underlying means and within-cluster standard deviations are always available on the returned object, see Value.

Examples


# a small subset keeps the example quick
G <- sim_data$G[1:150, , drop = FALSE]
Z <- sim_data$Z[1:150, , drop = FALSE]
Y <- sim_data$Y_normal[1:150]

fit <- estimate_lucid(G = G, Z = Z, Y = Y, lucid_model = "early",
                      family = "normal", K = 2, seed = 1008,
                      max_itr = 20, max_tot.itr = 50)

p <- plot_cluster_omic_profile(fit)
p[[1]]

# bar rendering, and more features
plot_cluster_omic_profile(fit, type = "bar", top_n = 15)[[1]]

# the ranking behind the figure
head(unique(attr(p[[1]], "profile_data")[, c("feature", "score")]))



LUCIDus documentation built on Sept. 3, 2026, 1:06 a.m.