Latent-Component PCA#
qiime gglasso pca projects your samples onto the eigenvectors of the
low-rank component L of a Sparse + Low-Rank solution, not onto the
principal components of the feature table. The sparse component Θ answers
“which taxa are directly linked?”; L absorbs the dense, global structure that
no sparse graph can represent — environmental gradients, sequencing depth,
batch. Use the visualizer to see that structure and ask what it corresponds to.
Prerequisites#
Important
1. The solution must come from --p-latent True. pca reads
solution/lowrank_ out of the solution artifact, and that group only exists for
a latent problem. An SGL solution from Single Graphical Lasso fails
here with a lookup error on the solution’s internals rather than a message about
missing latent variables.
2. --m-sample-metadata-file is effectively required. It is registered as an
optional Metadata parameter, but the function body dereferences it
unconditionally — the first thing it does with the metadata is filter it to
numeric columns — so omitting it raises an AttributeError on NoneType. Pass
it every time.
Troubleshooting lists both: they are the
two ways a first pca call usually fails.
Running the visualizer#
The solution comes from the latent fit in Sparse + Low-Rank:
qiime gglasso pca \
--i-table data/atacama-table-mclr.qza \
--i-solution data/atacama-solution-slr.qza \
--m-sample-metadata-file data/selected-atacama-sample-metadata.tsv \
--p-n-components 2 \
--p-color-by ph \
--o-visualization data/slr-pca.qzv
Explanation:
--i-table: the transformed table — the same artifact you passed tocalculate-covariancein Data Preparation. The projection is a matrix product between the table and the eigenvectors ofL, so the features must be the same set, in the same order, as the ones behind the covariance matrix. Passing the raw counts, or a table filtered differently, produces either a shape error or a silently meaningless plot.--i-solution: a latent solution, per the prerequisite above.--m-sample-metadata-file: sample metadata, used both to colour the points and to populate the axis-selection dropdowns.--p-n-components: how many principal components enter the pair-plot grid (default3). The command above runs only if the fitted low-rank block has rank 3 or more.--p-color-by: the metadata column used for the colour scale.--o-visualization: the.qzv, viewable withqiime tools viewor at QIIME 2 View.
Note
No QIIME 2 2026.7 environment exists yet, so nothing has been re-run; the
achieved rank, the variance shares on the axis labels and the appearance of the
tabs are all pending verification against QIIME 2 2026.7. Read the rank off your
own solution before fixing --p-n-components.
--p-n-components must not exceed the achieved rank#
The constraint is n_components <= rank(L) — asking for exactly as many
components as the achieved rank is legitimate. pca validates it up front and
raises
n_components (N) exceeds the rank of the low-rank component (R).
Pass --p-n-components R or lower.
The pair-plot carries the same check as a defensive assertion for direct callers,
worded n_components (N) is greater than the rank of the low-rank component (R).
With the default of 3 you need a low-rank block of rank 3 or more. The rank is
set indirectly by μ₁, and a larger μ₁ gives a smaller rank. If you tuned
μ₁ for a compact, interpretable latent block you may well end up with rank 2,
at which point the largest admissible value is --p-n-components 2 — enough for
exactly one pair in the grid. Rank 1 is unusable outright: the single-plot tab
defaults to PC1 against PC2 and needs at least two components to exist.
You cannot set the rank directly. --p-rank raises NotImplementedError on
every released GGLasso; see
Troubleshooting and, for the practical
μ₁ scouting procedure, Choosing the Latent Rank.
To read the achieved rank, open the solution with
summarize and look at the rank column of the statistics
tab. That column comes from the model-selection path, so it is present only if
the solution was fitted over a grid rather than as a single fit — see
Regularization Paths & Model Selection.
Important
Do not size --p-n-components exactly to the number you read off that tab. Two
things stand between it and the components you get. First, the tab prints one
rank per grid point, so match the row to the selected λ₁/μ₁ from the
best-parameter table yourself; that table reports the chosen hyperparameters, not
the rank. Second, the limit pca enforces is np.linalg.matrix_rank recomputed
on the stored L, whose default tolerance is far finer than the hard 1e-9
eigenvalue cut the projection itself applies — so matrix_rank can count
eigenvalues that the projection then discards, and the guard can pass while fewer
than n_components components exist. Leave yourself a margin below the reported
rank rather than sizing to it exactly.
--p-color-by sees numeric columns only#
Before anything is plotted, the metadata is filtered to numeric columns. A
categorical column — a yes/no vegetation flag, say, as carried by tier 2’s
sample-metadata.tsv — is dropped, and naming it in --p-color-by fails with a
lookup error on a column that is no longer there. The same filter governs the
axis dropdowns, so categorical variables cannot be plotted against a component
either. To see a grouping variable, encode it numerically in the metadata file
first. The tier-1 file used above, selected-atacama-sample-metadata.tsv, holds
four numeric columns and no categorical one, so on this data the filter is a
no-op and nothing is dropped.
The filtered metadata is then re-indexed onto the sample IDs of the table. Any sample ID present in the table but absent from the metadata file, or spelled differently in the two, becomes a missing value rather than an error. Missing values in the colouring column are load-bearing: the pair-plot drops those samples before projecting, so it can show fewer points than the single plot, and the single plot derives its colour-scale bounds from the raw minimum and maximum of the column, which missing entries can poison. Check that your colouring column is complete for exactly the samples in the table.
Tip
pca builds a complete pair-plot grid for every numeric metadata column and
then displays only the one named by --p-color-by. Wide metadata therefore costs
real time for output you never see. Trim the metadata file to the columns you
care about before running it on anything large.
The seq-depth fallback#
Omit --p-color-by and the visualizer computes a column itself: per-sample
sequencing depth from the input table, rescaled to [0, 1] and added as
seq-depth. If the leading component tracks seq-depth, the low-rank block is
modelling a technical gradient, and any biological reading of it is unsafe.
Note
The orientation is not guessed. pca first lines the table up against the
low-rank component — whichever axis has \(p\) entries becomes the feature axis,
and the table is transposed if needed — and raises if neither axis matches. The
helper then sums over features unconditionally, so the derived column is always
indexed by sample and joins cleanly to the sample-indexed metadata at any \(p/N\)
ratio, including the 13 ASVs of this Atacama table. Prefer --p-color-by
whenever you have a variable in mind; the fallback is the default because it is
the right first plot.
The two tabs#
Single plot. One large scatter of the samples, PC1 against PC2 by default,
with a colour bar for the selected variable and hover tooltips carrying the
coordinates. The two X-Axis / Y-Axis dropdowns to the right of the plot
re-map the axes client-side to any other component or any numeric metadata
column. Plotting PC1 directly against ph or elevation is the quickest way
to see whether a latent axis is a measured gradient in disguise.
Axis labels carry the share of variance each component explains, computed from
the eigenvalues of L — that is, the proportion of the latent structure, not
of the total variance in the table. Only eigenvalues above a numerical tolerance
are kept, so the number of components on offer is the numerical rank of L. The
projection is whitened by those eigenvalues, so scores on different components
are on comparable scales and a wide spread on a late component does not mean it
dominates.
Pair-plot. A triangular grid of every pair among the first
--p-n-components components, all coloured by --p-color-by, with the colour
bar in the corner cell; the diagonal and one triangle stay empty. Panels are
small and fixed-size, so use the grid to spot which pair separates your samples
and go back to the single plot to look at that pair properly.
The two tabs use different colour palettes for the same variable — a blue ramp in the single plot, viridis in the pair-plot. Compare positions across tabs, not shades.
Reading latent components as putative drivers#
Do not ask what PC1 is; ask whether PC1 lines up with anything you measured.
If a component correlates visibly with a measured covariate, the low-rank block
is standing in for that covariate. Stop treating it as latent: append the
covariate to the table with transform-features --p-add-metadata True and
re-fit, as in Adaptive Graphical Lasso, so the variable
is modelled explicitly and the remaining sparse edges are conditional on it.
Comparing the edge set before and after turns “there is confounding” into “these
specific edges were environment-mediated” — the comparison set out in
Interpretation.
If a component lines up with nothing you measured, you have a candidate unmeasured driver: an unrecorded gradient, a collection batch, an extraction run. That is a hypothesis to check against your study design, not a result.
Important
Do not over-read individual axes. The eigenvectors of L are determined only up
to sign, so the direction of an axis carries no meaning, and components with
close eigenvalues are only defined up to rotation within their shared subspace —
which of two near-tied components a sample loads on is not interpretable.
Interpret the subspace spanned by the leading components, and treat a
component-by-component story as unsupported unless the eigenvalues are clearly
separated.
A worked, higher-dimensional version of this analysis — several ranks, the same metadata — is in Latent PCA on the 300-ASV table. The full parameter list is in the q2-gglasso parameter reference.