scverse / scverse/scanpy

`sc.pp.neighbors` uses the default value of `n_comps` in `sc.pp.pca` instead of `n_pcs` in `sc.pp.neighbors` when `X_pca ` is not precomputed

Open
#2,093 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
2.6k
Forks
779
Avg merge
1d 4h
Merged PRs (30d)
27

Description

  • [yes] I have checked that this issue has not already been reported.
  • [yes] I have confirmed this bug exists on the latest version of scanpy.
  • [yes] I have confirmed this bug exists on the master branch of scanpy.

Suggested fix: change line 44 in scanpy/scanpy/tools/_utils.py

https://github.com/theislab/scanpy/blob/83f90141fd18943a1795772d3d39f4e9eefd65c3/scanpy/tools/_utils.py#L44

from X = pca(adata.X) to X = pca(adata.X)[:, :n_pcs].


Note: Please read this guide detailing how to provide the necessary information for us to reproduce your bug.

Minimal code sample (that we can copy&paste without having any data)
# Minimal code 
import scanpy as sc
import anndata
import numpy as np
print('scanpy=', sc.__version__)
print('anndata=', anndata.__version__)
print('numpy=', np.__version__)

np.random.seed(0)
adata_raw = anndata.AnnData(np.random.randn(20,200))
print('adata shape', adata.shape)

# neighbors without precomputed pca
adata = adata_raw.copy()
sc.pp.neighbors(adata, n_neighbors=10, n_pcs=15)
mat_neighbor10_pc15_without_pca = adata.obsp["connectivities"].copy()

adata = adata_raw.copy()
sc.pp.pca(adata, n_comps=15)
sc.pp.neighbors(adata, n_neighbors=10, n_pcs=15)
mat_neighbor10_pc15_with_pca = adata.obsp["connectivities"].copy()

adata = adata_raw.copy()
sc.pp.pca(adata, n_comps=19) # max n_comps for 30 cells
sc.pp.neighbors(adata, n_neighbors=10, n_pcs=19)
mat_neighbor10_pc19_with_pca = adata.obsp["connectivities"].copy()

print('\nResults for `sc.pp.neighbors(adata, n_neighbors=10, n_pcs=15)` '
      'with and without precomputed pca are different:')
print(np.allclose(mat_neighbor10_pc15_without_pca.toarray(), mat_neighbor10_pc15_with_pca.toarray()))
print('\nResults of `sc.pp.neighbors(adata, n_neighbors=10, n_pcs=15)` without precomputed pca is same as '
      'results of `sc.pp.neighbors(adata, n_neighbors=10, n_pcs=19)` (19 is default `n_comps` for sc.pp.pca)'
      ' with precomputed pca')
print(np.allclose(mat_neighbor10_pc15_without_pca.toarray(), mat_neighbor10_pc19_with_pca.toarray()))
scanpy= 1.6.0
anndata= 0.7.4
numpy= 1.19.0
adata shape (20, 200)
WARNING: You’re trying to run this on 200 dimensions of `.X`, if you really want this, set `use_rep='X'`.
         Falling back to preprocessing with `sc.pp.pca` and default params.

Results for `sc.pp.neighbors(adata, n_neighbors=10, n_pcs=15)` with and without precomputed pca are different
False

Results of `sc.pp.neighbors(adata, n_neighbors=10, n_pcs=15)` without precomputed pca is same as results of `sc.pp.neighbors(adata, n_neighbors=10, n_pcs=19)` (19 is default `n_comps` for sc.pp.pca) with precomputed pca
True
Versions

WARNING: If you miss a compact list, please try print_header!

anndata 0.7.4
scanpy 1.6.0
sinfo 0.3.1

PIL 7.2.0
anndata 0.7.4
backcall 0.2.0
colorama 0.4.4
cycler 0.10.0
cython_runtime NA
dateutil 2.8.1
decorator 4.4.2
get_version 2.1
h5py 2.10.0
igraph 0.8.3
importlib_metadata 1.7.0
ipykernel 5.3.2
ipython_genutils 0.2.0
jedi 0.17.1
joblib 0.16.0
kiwisolver 1.2.0
legacy_api_wrap 1.2
leidenalg 0.8.3
llvmlite 0.35.0
louvain 0.7.0
matplotlib 3.3.0
mpl_toolkits NA
natsort 7.0.1
numba 0.52.0
numexpr 2.7.1
numpy 1.19.0
packaging 20.4
pandas 1.0.5
parso 0.7.0
pexpect 4.8.0
pickleshare 0.7.5
pkg_resources NA
prompt_toolkit 3.0.5
ptyprocess 0.6.0
pygments 2.6.1
pyparsing 2.4.7
pytz 2020.1
scanpy 1.6.0
scipy 1.5.1
setuptools_scm NA
sinfo 0.3.1
six 1.15.0
sklearn 0.23.1
storemagic NA
tables 3.6.1
texttable 1.6.3
tornado 6.0.4
traitlets 4.3.3
typing_extensions NA
umap 0.4.6
wcwidth 0.2.5
yaml 5.4.1
zipp NA
zmq 19.0.1
zope NA

IPython 7.16.1
jupyter_client 6.1.6
jupyter_core 4.6.3
notebook 6.0.3

Python 3.7.2 (default, Jul 16 2019, 22:54:18) [GCC 8.2.0]
Linux-3.10.0-1160.36.2.el7.x86_64-x86_64-with-centos-7.9.2009-Core
48 logical CPU cores, x86_64

Session information updated at 2021-12-24 13:42

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at scanpy/scanpy/tools/_utils.py line 44 and reproduce the behavior with the minimal Python example using sc.pp.neighbors and sc.pp.pca. Update the fallback PCA path so the requested n_pcs is respected, then verify that neighbor results match the precomputed-PCA case in the supplied comparisons.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
bioinformatics, machine-learning
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.