I am new to the scRNA-seq field and I have been doing some experiments of visualization of UMAP using different numbers of PCA components for initialization. The process involves projecting scRNA-seq data (count matrix) onto various numbers of PCA components, followed by non-linear dimension reduction using UMAP. It seems that the UMAP results are exactly the same across different initializations, regardless of the number of PCA components used. Are there any theoretical reasons for this? I am using Dynamo and their function dyn.tl.reduceDimension(adata, n_pca_components=30) for the experiments.

The results can be reproduced using the following code. Here I used the build-in zebrafish dataset with n_obs × n_vars = 4181 × 16940. I am just trying to see how the PCA initialization affects the Umap results.

import warnings

import dynamo as dyn 

dyn.configuration.set_figure_params('dynamo', background='white')

adata = dyn.sample_data.zebrafish()

preprocessor = dyn.pp.Preprocessor(cell_cycle_score_enable=True)
preprocessor.preprocess_adata(adata, recipe='monocle')


dyn.tl.reduceDimension(adata, n_pca_components=1, enforce=True)
dyn.pl.umap(adata, color='Cell_type')

dyn.tl.reduceDimension(adata, n_pca_components=30, enforce=True)
dyn.pl.umap(adata, color='Cell_type')

Here is the picture that shows the variance carried by PCA:

enter image description here

And the final umap results using n_pca_components= 1 and n_pca_components= 30:

enter image description here

  • $\begingroup$ Thank you for your reply @M__. I have tried actually n_pca_components= 1, 2, 5, 10, 30, and all umap results are the same. More information has been added. $\endgroup$
    – Zack
    Commented Aug 30, 2023 at 18:00
  • $\begingroup$ Thanks for your edits and new information. $\endgroup$
    – M__
    Commented Aug 30, 2023 at 18:51

2 Answers 2


It seems you are performing PCA -> UMAP. The results you are reporting actually look cool. It's a good answer and there's nothing to worry about. It also shows good analytics, 'cause you're questioning the robustness of your data.

The limiting factor is the variance carried by PCA - which needs to be calculated (it may be low, e.g. <50%). Well I mean you've calculated it via the PCs - but its not declared, its better to know how much it is, i.e. how much variance each PC holds. The UMAP is doing nothing more than representing the established variance identified by PCA.

If you change the number of components which UMAP is assessing then this will result in changes in the clusters observed, usually.

However if you are changing the no. PCs -> UMAP and there's little effect then the PCs are not introducing new information to cut-up the data set. Thats a fairly robust answer: it's attained "stationarity". Very desirable output, just make sure there isn't a bug in your code, but it demonstrates there's no hidden or partial information that might give a different result. So the clusters you are seeing are a good representation of the data (thats good).

Its not a complete analysis - as hinted - but I'd be happy with that result.

Overall, there's very heavy dispersion of the variance between PCs. I've never had to teach this stuff, beyond a few line explanations. An educator experienced with this theory would give a more succinct explanation. However, the discussion below arrives at a common understanding between the OP and I. If there's demand I'll summarise the discussion as a singular paragraph: the final comments should be the introduction, i.e. what PCA is doing at basic level.

Comments (discussion)

@Zach even when using n_pca_components=1 and n_pca_components=30, the results remain unchanged. The first PCA component should only capture a part of the overall information. Is this correct?

Response Number 0 (on your graph) is the first principle component (16%). PC = 1 is the second PC (5%). Thus PCA = 1 means 21% of the variance. This far exceeds the PC 3 at 2%. Thats why it works, so all information is PC1 and PC2, nothing beyond that discriminates against the data.

@Zach So, n_pca_components = 3 could capture almost all the information and adding more components doesn't really make any difference to the results. But if we only consider n_pca_components = 1, why there are still no differences compared to n_pca_components = 30?

Response its easy .. because if you add all the PCs from PC 4 + ... + PC 30 it will be <5% of the total variance. PC1 + PC2 + PC3 = 24% of the variance, so there is nothing to see beyond PC3, when the maximum is PC 30.

@Zach Why there are no differences between n_pca_components = 1 (using only PC1) and n_pca_components = 30 (using PC1+PC2+...+PC30)?

Response PC1 + PC2 = 24% and PC1 ... + PC30 <30%. There is no information in the variance for between group clusters for PC3 to PC30, there is likely to be within group differences but you are not measuring those.

@Zach there is little difference between PC1 + PC2 = 21% and PC1+...+PC30. I mean if we only consider PC1 = 16% and PC1+...+PC30 > 25%, do they have any differences between PC1 and PC1+...+PC30?

Response PCA works on individual elements it, it doesn't work on groups. The analysis of groups is post-hoc (usually via colour coding). PC=1 in your UMAP calculation is PC1 + PC2 (PC1 is automatic, its position 0 in your graph). . You are only looking at between group variance and in your data that is resolved essentially for PC1 + PC2 = 21%. The within group positioning will change so, yes there will be difference against PC1+PC2 vs PC1 + .... + PC 30 but we can't see them. Again PCA is individual elements, it's not using group information. So if you did sub-group analysis you might see changes PC1+PC2 vs PC1 + ... PC 30. So to put it simply your group delineation is too big to spot in any differences (but that only matters if it is biologically relevant).

@Zach Actually what I mean is PC0 = 16% and PC0+...+PC30 > 25%. But your explanation makes sense to me and I appreciate your response.

  • $\begingroup$ Comments have been moved to chat; please do not continue the discussion here. Before posting a comment below this one, please review the purposes of comments. Comments that do not request clarification or suggest improvements usually belong as an answer, on Bioinformatics Meta, or in Bioinformatics Chat. Comments continuing discussion may be removed. $\endgroup$
    – gringer
    Commented Aug 31, 2023 at 0:41

It is a bit odd that different numbers of principal components are giving identical results, especially given that even the same initialisation settings with different UMAP epoch numbers will give different results.

I'm not familiar with the use of python for single cell data analysis, but it looks like the adata information might be being modified when running reduceDimension. If this is the case, then it's possible that the first PCA reduction is reducing the dataset as far as it will go, and the second PCA reduction doesn't do anything. This could be checked by changing the order of operations (from a fresh run) and seeing if the output is changed:

dyn.tl.reduceDimension(adata, n_pca_components=30, enforce=True)
dyn.pl.umap(adata, color='Cell_type')

dyn.tl.reduceDimension(adata, n_pca_components=1, enforce=True)
dyn.pl.umap(adata, color='Cell_type')

It's also possible that the umap command is doing its own reduction and ignoring the result of dyn.tl.reduceDimension. Maybe the UMAP plotting function doesn't actually do a UMAP reduction as well, and the UMAP result (or initial condition) is calculated earlier (e.g. in preprocessor.preprocess_adata).

It's also possible, as @M__ suggests, that you've reached a stationary result after however many UMAP iterations are set as default. But... I find that unlikely given how variable UMAP has been for me. I'd want to do a lot more exploration before settling on that as an explanation.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.