From 25e7cd418ac258329944ced2b4ba443d5d06865b Mon Sep 17 00:00:00 2001 From: kaushal Date: Fri, 25 Oct 2024 08:53:13 +0530 Subject: [PATCH 001/118] updated for filter_cell --- src/scanpy/preprocessing/_simple.py | 124 ++++++++++++++++++++++++++-- 1 file changed, 116 insertions(+), 8 deletions(-) diff --git a/src/scanpy/preprocessing/_simple.py b/src/scanpy/preprocessing/_simple.py index 1e61b60ace..f885f872fc 100644 --- a/src/scanpy/preprocessing/_simple.py +++ b/src/scanpy/preprocessing/_simple.py @@ -52,6 +52,36 @@ from .._utils import AnyRandom +# @numba.jit(cache=True,parallel=True) +def get_rows_to_keep_1(indptr, data): + lens = np.zeros(len(indptr) - 1, dtype=type(data[0])) + for i in range(len(lens)): + lens[i] = np.sum(data[indptr[i] : indptr[i + 1]]) + return lens + + +def get_rows_to_keep(indptr, dtype): + lens = indptr[1:] - indptr[:-1] + # lens.astype(dtype) + return lens + + +@numba.njit(cache=True, parallel=True) +def get_cols_to_keep(indices, data, colcount, nthr, Flag): + counts = np.zeros((nthr, colcount), dtype=type(data[0])) + for i in numba.prange(nthr): + start = i * indices.shape[0] // nthr + end = (i + 1) * indices.shape[0] // nthr + for j in range(start, end): + if data[j] != 0: # and indices[j] 0, axis=1 - ) + print(type(X)) + import time + + t0 = time.time() + if isinstance(X, sp.sparse._csr.csr_matrix): + if min_genes is None and max_genes is None: + number_per_cell = get_rows_to_keep_1(X.indptr, X.data) + else: + number_per_cell = get_rows_to_keep(X.indptr, type(X.data[0])) + + # and ( min_genes is not None or max_genes is not None) : + # #number_per_cell=np.sum(X>0,axis=1) + # number_per_cell = get_rows_to_keep(X.indptr,type(X.data[0])) + elif isinstance(X, sp.sparse._csc.csc_matrix): + nclos = X.shape[0] + nthr = numba.get_num_threads() + if min_genes is None and max_genes is None: + number_per_cell = get_cols_to_keep(X.indices, X.data, nclos, nthr, False) + else: + number_per_cell = get_cols_to_keep(X.indices, X.data, nclos, nthr, True) + + else: + number_per_cell = axis_sum( + X if min_genes is None and max_genes is None else X > 0, axis=1 + ) + + print("Number_per_Cell", time.time() - t0) + if issparse(X): - number_per_cell = number_per_cell.A1 + number_per_cell = number_per_cell if min_number is not None: cell_subset = number_per_cell >= min_number if max_number is not None: @@ -286,11 +341,61 @@ def filter_genes( X = data # proceed with processing the data matrix min_number = min_counts if min_cells is None else min_cells max_number = max_counts if max_cells is None else max_cells - number_per_gene = axis_sum( - X if min_cells is None and max_cells is None else X > 0, axis=0 - ) + import time + + t0 = time.time() + + if isinstance(X, sp.sparse._csr.csr_matrix): + ncols = X.shape[1] + nthr = numba.get_num_threads() + print( + "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH", + X.shape, + nthr, + X.indices.shape, + X.data.shape, + ) + # number_per_gene = get_cols_to_keep(X.indices, X.data, ncols, nthr) + if min_cells is None and max_cells is None: + number_per_gene = get_cols_to_keep(X.indices, X.data, ncols, nthr, False) + else: + number_per_gene = get_cols_to_keep(X.indices, X.data, ncols, nthr, True) + + elif isinstance(X, sp.sparse._csc.csc_matrix): + # ncols = X.shape[1] + # nthr = numba.get_num_threads() + print( + "HHHHHHHHHHHHHHHHHHcscHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH" + ) # X.shape,nthr,X.indices.shape,X.data.shape) + # number_per_gene = get_cols_to_keep(X.indices, X.data, ncols, nthr) + if min_cells is None and max_cells is None: + number_per_gene = get_rows_to_keep_1( + X.indptr, X.data + ) # get_cols_to_keep(X.indices, X.data, ncols, nthr,False) + else: + number_per_gene = get_rows_to_keep(X.indptr, type(X.data[0])) + # if isinstance(number_per_gene,np.matrix): + # number_per_gene=number_per_gene.A1 + # print("I am here") + + print("Cols to keep,", time.time() - t0) + # print(number_per_gene,type(number_per_gene),number_per_gene.shape,ncols) + # number_per_gene = axis_sum( + # X if min_cells is None and max_cells is None else X > 0, axis=0 + # ) + # print(number_per_gene.A1) + else: + print("inside print") + number_per_gene = axis_sum( + X if min_cells is None and max_cells is None else X > 0, axis=0 + ) if issparse(X): - number_per_gene = number_per_gene.A1 + if isinstance(X, sp.sparse._csr.csr_matrix) or isinstance( + X, sp.sparse._csc.csc_matrix + ): # isinstance(X, sp.sparse._csr.csr_matrix): + number_per_gene = number_per_gene # cols_to_keep#number_per_gene + else: + number_per_gene = number_per_gene if min_number is not None: gene_subset = number_per_gene >= min_number if max_number is not None: @@ -597,6 +702,7 @@ def normalize_per_cell( # noqa: PLR0917 if not copy: raise ValueError("Can only be run with copy=True") cell_subset, counts_per_cell = filter_cells(X, min_counts=min_counts) + print(type(cell_subset), type(counts_per_cell)) X = X[cell_subset] counts_per_cell = counts_per_cell[cell_subset] if counts_per_cell_after is None: @@ -604,6 +710,8 @@ def normalize_per_cell( # noqa: PLR0917 with warnings.catch_warnings(): warnings.simplefilter("ignore") counts_per_cell += counts_per_cell == 0 + print("!!!!!!!!!!!", type(counts_per_cell[0]), type(counts_per_cell_after)) + # counts_per_cell.astype(type(counts_per_cell_after)) counts_per_cell /= counts_per_cell_after if not issparse(X): X /= counts_per_cell[:, np.newaxis] From fd6dd141af1c72c0ea72274525cbb4f68cc67702 Mon Sep 17 00:00:00 2001 From: kaushal Date: Fri, 15 Nov 2024 13:43:33 +0530 Subject: [PATCH 002/118] print statment removal --- src/scanpy/preprocessing/_simple.py | 45 ++--------------------------- 1 file changed, 3 insertions(+), 42 deletions(-) diff --git a/src/scanpy/preprocessing/_simple.py b/src/scanpy/preprocessing/_simple.py index f885f872fc..ad0922508a 100644 --- a/src/scanpy/preprocessing/_simple.py +++ b/src/scanpy/preprocessing/_simple.py @@ -51,8 +51,6 @@ from .._compat import DaskArray from .._utils import AnyRandom - -# @numba.jit(cache=True,parallel=True) def get_rows_to_keep_1(indptr, data): lens = np.zeros(len(indptr) - 1, dtype=type(data[0])) for i in range(len(lens)): @@ -62,7 +60,6 @@ def get_rows_to_keep_1(indptr, data): def get_rows_to_keep(indptr, dtype): lens = indptr[1:] - indptr[:-1] - # lens.astype(dtype) return lens @@ -199,7 +196,6 @@ def filter_cells( X = data # proceed with processing the data matrix min_number = min_counts if min_genes is None else min_genes max_number = max_counts if max_genes is None else max_genes - print(type(X)) import time t0 = time.time() @@ -209,9 +205,6 @@ def filter_cells( else: number_per_cell = get_rows_to_keep(X.indptr, type(X.data[0])) - # and ( min_genes is not None or max_genes is not None) : - # #number_per_cell=np.sum(X>0,axis=1) - # number_per_cell = get_rows_to_keep(X.indptr,type(X.data[0])) elif isinstance(X, sp.sparse._csc.csc_matrix): nclos = X.shape[0] nthr = numba.get_num_threads() @@ -225,8 +218,6 @@ def filter_cells( X if min_genes is None and max_genes is None else X > 0, axis=1 ) - print("Number_per_Cell", time.time() - t0) - if issparse(X): number_per_cell = number_per_cell if min_number is not None: @@ -348,52 +339,27 @@ def filter_genes( if isinstance(X, sp.sparse._csr.csr_matrix): ncols = X.shape[1] nthr = numba.get_num_threads() - print( - "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH", - X.shape, - nthr, - X.indices.shape, - X.data.shape, - ) - # number_per_gene = get_cols_to_keep(X.indices, X.data, ncols, nthr) if min_cells is None and max_cells is None: number_per_gene = get_cols_to_keep(X.indices, X.data, ncols, nthr, False) else: number_per_gene = get_cols_to_keep(X.indices, X.data, ncols, nthr, True) elif isinstance(X, sp.sparse._csc.csc_matrix): - # ncols = X.shape[1] - # nthr = numba.get_num_threads() - print( - "HHHHHHHHHHHHHHHHHHcscHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH" - ) # X.shape,nthr,X.indices.shape,X.data.shape) - # number_per_gene = get_cols_to_keep(X.indices, X.data, ncols, nthr) if min_cells is None and max_cells is None: number_per_gene = get_rows_to_keep_1( X.indptr, X.data - ) # get_cols_to_keep(X.indices, X.data, ncols, nthr,False) + ) else: number_per_gene = get_rows_to_keep(X.indptr, type(X.data[0])) - # if isinstance(number_per_gene,np.matrix): - # number_per_gene=number_per_gene.A1 - # print("I am here") - - print("Cols to keep,", time.time() - t0) - # print(number_per_gene,type(number_per_gene),number_per_gene.shape,ncols) - # number_per_gene = axis_sum( - # X if min_cells is None and max_cells is None else X > 0, axis=0 - # ) - # print(number_per_gene.A1) else: - print("inside print") number_per_gene = axis_sum( X if min_cells is None and max_cells is None else X > 0, axis=0 ) if issparse(X): if isinstance(X, sp.sparse._csr.csr_matrix) or isinstance( X, sp.sparse._csc.csc_matrix - ): # isinstance(X, sp.sparse._csr.csr_matrix): - number_per_gene = number_per_gene # cols_to_keep#number_per_gene + ): + number_per_gene = number_per_gene else: number_per_gene = number_per_gene if min_number is not None: @@ -478,7 +444,6 @@ def log1p_sparse(X: spmatrix, *, base: Number | None = None, copy: bool = False) @log1p.register(np.ndarray) def log1p_array(X: np.ndarray, *, base: Number | None = None, copy: bool = False): # Can force arrays to be np.ndarrays, but would be useful to not - # X = check_array(X, dtype=(np.float64, np.float32), ensure_2d=False, copy=copy) if copy: if not np.issubdtype(X.dtype, np.floating): X = X.astype(float) @@ -702,7 +667,6 @@ def normalize_per_cell( # noqa: PLR0917 if not copy: raise ValueError("Can only be run with copy=True") cell_subset, counts_per_cell = filter_cells(X, min_counts=min_counts) - print(type(cell_subset), type(counts_per_cell)) X = X[cell_subset] counts_per_cell = counts_per_cell[cell_subset] if counts_per_cell_after is None: @@ -710,8 +674,6 @@ def normalize_per_cell( # noqa: PLR0917 with warnings.catch_warnings(): warnings.simplefilter("ignore") counts_per_cell += counts_per_cell == 0 - print("!!!!!!!!!!!", type(counts_per_cell[0]), type(counts_per_cell_after)) - # counts_per_cell.astype(type(counts_per_cell_after)) counts_per_cell /= counts_per_cell_after if not issparse(X): X /= counts_per_cell[:, np.newaxis] @@ -1113,7 +1075,6 @@ def _pca_fallback(data, n_comps=2): # calculate eigenvectors & eigenvalues of the covariance matrix # use 'eigh' rather than 'eig' since C is symmetric, # the performance gain is substantial - # evals, evecs = np.linalg.eigh(C) evals, evecs = sp.sparse.linalg.eigsh(C, k=n_comps) # sort eigenvalues in decreasing order idcs = np.argsort(evals)[::-1] From a54e5412a8bacabe8429871690d8fda392d5f921 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 12:51:40 +0200 Subject: [PATCH 003/118] [pre-commit.ci] pre-commit autoupdate (#3119) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3f1fb93af5..4a624afae1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.4.9 + rev: v0.4.10 hooks: - id: ruff types_or: [python, pyi, jupyter] From 89aff868f952ee0baaca4b2400522648e0190857 Mon Sep 17 00:00:00 2001 From: Ilan Gold Date: Tue, 2 Jul 2024 11:04:48 +0200 Subject: [PATCH 004/118] (chore): add preparation-of-release documentation (#3122) * (chore): add preparation-of-release documentation * (chore): add versioning url * Update release.md * unify quotes * fmt * mention UI elements * clearer --------- Co-authored-by: Philipp A --- docs/dev/release.md | 21 ++++++++++++++++----- docs/dev/versioning.md | 1 + 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/docs/dev/release.md b/docs/dev/release.md index f4bcb528a6..e3ce2a31ab 100644 --- a/docs/dev/release.md +++ b/docs/dev/release.md @@ -3,13 +3,24 @@ First, check out {doc}`versioning` to see which kind of release you want to make. That page also explains concepts like *pre-releases* and applications thereof. +## Preparing the release + +1. Make a new branch off of `main` to prepare the release notes, and create a PR from this branch back into `main`. + Add a milestone for the desired version to be released. +2. Update the date in the desired release’s notes and if applicable, delete empty headers in the notes. + Create a new blank note for the next desired release and update the `index.md` to include it. +3. Push the changes to the PR, and merge into `main`. + If it is a patch release, backport the updated notes (see [](#versioning-tooling)) into the major/minor version branch. + ## Actually making the release -1. Go to GitHub’s [releases][] page -2. Click “Draft a new release” -3. Click “Choose a tag” and type the version of the tag you want to release, such as `1.9.6` -4. Click “**+ Create new tag: 1.\.\** on publish” -5. If the version is a *pre-release* version, such as `1.7.0rc1` or `1.10.0a1`, tick the “Set as a pre-release” checkbox +1. Go to GitHub’s [releases][] page. +2. Click the “Draft a new release” button. +3. Open the “Choose a tag” dropdown and type the version of the tag you want to release, such as `1.9.6`. +4. Select the dropdown entry “**+ Create new tag: 1.\.\** on publish”. +5. In the second dropdown “Target:”, select the base branch i.e. `main` for a minor/major release, + and e.g. `1.9.x` for our example patch release `1.9.6`. +6. If the version is a *pre-release* version, such as `1.7.0rc1` or `1.10.0a1`, tick the “Set as a pre-release” checkbox. [releases]: https://github.com/scverse/scanpy/releases diff --git a/docs/dev/versioning.md b/docs/dev/versioning.md index c2427f6a01..e87b3d7a9f 100644 --- a/docs/dev/versioning.md +++ b/docs/dev/versioning.md @@ -22,6 +22,7 @@ Valid version numbers are described in [PEP 440](https://peps.python.org/pep-044 [Development versions](https://peps.python.org/pep-0440/#developmental-releases) : should look like `1.8.0.dev0`, with a commit hash optionally appended as a local version identifier (e.g. `1.8.0.dev2+g00ad77b`). +(versioning-tooling)= ## Tooling To be sure we can follow this scheme and maintain some agility in development, we use some tooling and development practices. From 3bb4a734d4de2898752b3be648556e99d5916532 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 2 Jul 2024 11:46:33 +0200 Subject: [PATCH 005/118] [pre-commit.ci] pre-commit autoupdate (#3131) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ilan Gold --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4a624afae1..fb2f57fbd6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.4.10 + rev: v0.5.0 hooks: - id: ruff types_or: [python, pyi, jupyter] From b5337eabd917154564929a30121ac4048bffa045 Mon Sep 17 00:00:00 2001 From: Philipp A Date: Tue, 2 Jul 2024 11:55:34 +0200 Subject: [PATCH 006/118] Unpin numpy 2 (#3115) * Unpin numpy 2 * float64 and harmonize metrics code * Skip tests for old skmisc * Fix parallel tests * fix numpy 2 reprs * add relnote * (fix): release notes version --------- Co-authored-by: Ilan Gold --- docs/release-notes/1.10.3.md | 2 +- pyproject.toml | 4 +- src/scanpy/_utils/compute/is_constant.py | 8 +- src/scanpy/metrics/_gearys_c.py | 112 +++++++++++++++-------- src/scanpy/metrics/_morans_i.py | 77 ++++++++-------- src/scanpy/plotting/_utils.py | 2 +- src/scanpy/preprocessing/_simple.py | 6 +- src/testing/scanpy/_pytest/__init__.py | 9 +- src/testing/scanpy/_pytest/marks.py | 42 ++++++++- tests/test_datasets.py | 2 +- 10 files changed, 162 insertions(+), 102 deletions(-) diff --git a/docs/release-notes/1.10.3.md b/docs/release-notes/1.10.3.md index a0a96b5d3d..23fe2d8341 100644 --- a/docs/release-notes/1.10.3.md +++ b/docs/release-notes/1.10.3.md @@ -10,7 +10,7 @@ ``` * Fix `subset=True` of {func}`~scanpy.pp.highly_variable_genes` when `flavor` is `seurat` or `cell_ranger`, and `batch_key!=None` {pr}`3042` {smaller}`E Roellin` - +* Add compatibility with {mod}`numpy` 2.0 {pr}`3065` and {pr}`3115` {smaller}`P Angerer` ```{rubric} Performance ``` diff --git a/pyproject.toml b/pyproject.toml index 1f8d5a88f8..888a613ab7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,9 +48,7 @@ classifiers = [ ] dependencies = [ "anndata>=0.8", - # TODO: remove <2 requirement once PyNNDescent releases this fix: - # https://github.com/lmcinnes/pynndescent/issues/241 - "numpy>=1.23,<2", + "numpy>=1.23", "matplotlib>=3.6", "pandas >=1.5", "scipy>=1.8", diff --git a/src/scanpy/_utils/compute/is_constant.py b/src/scanpy/_utils/compute/is_constant.py index b5ef9c884a..7dac03b40a 100644 --- a/src/scanpy/_utils/compute/is_constant.py +++ b/src/scanpy/_utils/compute/is_constant.py @@ -81,7 +81,7 @@ def is_constant( def _(a: NDArray, axis: Literal[0, 1] | None = None) -> bool | NDArray[np.bool_]: # Should eventually support nd, not now. if axis is None: - return (a == a.flat[0]).all() + return bool((a == a.flat[0]).all()) if axis == 0: return _is_constant_rows(a.T) elif axis == 1: @@ -116,9 +116,9 @@ def _is_constant_csr_rows( indptr: NDArray[np.integer], shape: tuple[int, int], ): - N = len(indptr) - 1 - result = np.ones(N, dtype=np.bool_) - for i in range(N): + n = len(indptr) - 1 + result = np.ones(n, dtype=np.bool_) + for i in range(n): start = indptr[i] stop = indptr[i + 1] if stop - start == shape[1]: diff --git a/src/scanpy/metrics/_gearys_c.py b/src/scanpy/metrics/_gearys_c.py index 4efb9a14c7..a0ca9a0b61 100644 --- a/src/scanpy/metrics/_gearys_c.py +++ b/src/scanpy/metrics/_gearys_c.py @@ -1,3 +1,5 @@ +"""Geary's C autocorrelation.""" + from __future__ import annotations from functools import singledispatch @@ -87,7 +89,7 @@ def gearys_c( Examples -------- - Calculate Gearys C for each components of a dimensionality reduction: + Calculate Geary’s C for each components of a dimensionality reduction: .. code:: python @@ -135,29 +137,38 @@ def gearys_c( @numba.njit(cache=True, parallel=True) -def _gearys_c_vec(data, indices, indptr, x): +def _gearys_c_vec( + data: np.ndarray, + indices: np.ndarray, + indptr: np.ndarray, + x: np.ndarray, +) -> float: W = data.sum() return _gearys_c_vec_W(data, indices, indptr, x, W) @numba.njit(cache=True, parallel=True) -def _gearys_c_vec_W(data, indices, indptr, x, W): - N = len(indptr) - 1 - x = x.astype(np.float_) +def _gearys_c_vec_W( + data: np.ndarray, + indices: np.ndarray, + indptr: np.ndarray, + x: np.ndarray, + W: np.float64, +): + n = len(indptr) - 1 + x = x.astype(np.float64) x_bar = x.mean() total = 0.0 - for i in numba.prange(N): + for i in numba.prange(n): s = slice(indptr[i], indptr[i + 1]) i_indices = indices[s] i_data = data[s] total += np.sum(i_data * ((x[i] - x[i_indices]) ** 2)) - numer = (N - 1) * total + numer = (n - 1) * total denom = 2 * W * ((x - x_bar) ** 2).sum() - C = numer / denom - - return C + return numer / denom # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -172,36 +183,47 @@ def _gearys_c_vec_W(data, indices, indptr, x, W): @numba.njit(cache=True) -def _gearys_c_inner_sparse_x_densevec(g_data, g_indices, g_indptr, x, W): +def _gearys_c_inner_sparse_x_densevec( + g_data: np.ndarray, + g_indices: np.ndarray, + g_indptr: np.ndarray, + x: np.ndarray, + W: np.float64, +) -> float: x_bar = x.mean() total = 0.0 - N = len(x) - for i in numba.prange(N): + n = len(x) + for i in numba.prange(n): s = slice(g_indptr[i], g_indptr[i + 1]) i_indices = g_indices[s] i_data = g_data[s] total += np.sum(i_data * ((x[i] - x[i_indices]) ** 2)) - numer = (N - 1) * total + numer = (n - 1) * total denom = 2 * W * ((x - x_bar) ** 2).sum() - C = numer / denom - return C + return numer / denom @numba.njit(cache=True) def _gearys_c_inner_sparse_x_sparsevec( # noqa: PLR0917 - g_data, g_indices, g_indptr, x_data, x_indices, N, W -): - x = np.zeros(N, dtype=np.float_) + g_data: np.ndarray, + g_indices: np.ndarray, + g_indptr: np.ndarray, + x_data: np.ndarray, + x_indices: np.ndarray, + n: int, + W: np.float64, +) -> float: + x = np.zeros(n, dtype=np.float64) x[x_indices] = x_data - x_bar = np.sum(x_data) / N + x_bar = np.sum(x_data) / n total = 0.0 - N = len(x) - for i in numba.prange(N): + n = len(x) + for i in numba.prange(n): s = slice(g_indptr[i], g_indptr[i + 1]) i_indices = g_indices[s] i_data = g_data[s] total += np.sum(i_data * ((x[i] - x[i_indices]) ** 2)) - numer = (N - 1) * total + numer = (n - 1) * total # Expanded from 2 * W * ((x_k - x_k_bar) ** 2).sum(), but uses sparsity # to skip some calculations # fmt: off @@ -210,43 +232,53 @@ def _gearys_c_inner_sparse_x_sparsevec( # noqa: PLR0917 * ( np.sum(x_data ** 2) - np.sum(x_data * x_bar * 2) - + (x_bar ** 2) * N + + (x_bar ** 2) * n ) ) # fmt: on - C = numer / denom - return C + return numer / denom @numba.njit(cache=True, parallel=True) -def _gearys_c_mtx(g_data, g_indices, g_indptr, X): - M, N = X.shape - assert N == len(g_indptr) - 1 +def _gearys_c_mtx( + g_data: np.ndarray, + g_indices: np.ndarray, + g_indptr: np.ndarray, + X: np.ndarray, +) -> np.ndarray: + m, n = X.shape + assert n == len(g_indptr) - 1 W = g_data.sum() - out = np.zeros(M, dtype=np.float_) - for k in numba.prange(M): - x = X[k, :].astype(np.float_) + out = np.zeros(m, dtype=np.float64) + for k in numba.prange(m): + x = X[k, :].astype(np.float64) out[k] = _gearys_c_inner_sparse_x_densevec(g_data, g_indices, g_indptr, x, W) return out @numba.njit(cache=True, parallel=True) def _gearys_c_mtx_csr( # noqa: PLR0917 - g_data, g_indices, g_indptr, x_data, x_indices, x_indptr, x_shape -): - M, N = x_shape + g_data: np.ndarray, + g_indices: np.ndarray, + g_indptr: np.ndarray, + x_data: np.ndarray, + x_indices: np.ndarray, + x_indptr: np.ndarray, + x_shape: tuple, +) -> np.ndarray: + m, n = x_shape W = g_data.sum() - out = np.zeros(M, dtype=np.float_) + out = np.zeros(m, dtype=np.float64) x_data_list = np.split(x_data, x_indptr[1:-1]) x_indices_list = np.split(x_indices, x_indptr[1:-1]) - for k in numba.prange(M): + for k in numba.prange(m): out[k] = _gearys_c_inner_sparse_x_sparsevec( g_data, g_indices, g_indptr, x_data_list[k], x_indices_list[k], - N, + n, W, ) return out @@ -261,7 +293,7 @@ def _gearys_c_mtx_csr( # noqa: PLR0917 def _gearys_c(g: sparse.csr_matrix, vals: np.ndarray | sparse.spmatrix) -> np.ndarray: assert g.shape[0] == g.shape[1], "`g` should be a square adjacency matrix" vals = _resolve_vals(vals) - g_data = g.data.astype(np.float_, copy=False) + g_data = g.data.astype(np.float64, copy=False) if isinstance(vals, sparse.csr_matrix): assert g.shape[0] == vals.shape[1] new_vals, idxer, full_result = _check_vals(vals) @@ -269,7 +301,7 @@ def _gearys_c(g: sparse.csr_matrix, vals: np.ndarray | sparse.spmatrix) -> np.nd g_data, g.indices, g.indptr, - new_vals.data.astype(np.float_, copy=False), + new_vals.data.astype(np.float64, copy=False), new_vals.indices, new_vals.indptr, new_vals.shape, diff --git a/src/scanpy/metrics/_morans_i.py b/src/scanpy/metrics/_morans_i.py index 8497d83d99..7c7609323e 100644 --- a/src/scanpy/metrics/_morans_i.py +++ b/src/scanpy/metrics/_morans_i.py @@ -5,8 +5,8 @@ from functools import singledispatch from typing import TYPE_CHECKING +import numba import numpy as np -from numba import njit, prange from scipy import sparse from .._compat import fullname @@ -88,7 +88,7 @@ def morans_i( Examples -------- - Calculate Morans I for each components of a dimensionality reduction: + Calculate Moran’s I for each components of a dimensionality reduction: .. code:: python @@ -126,35 +126,31 @@ def morans_i( # This is done in a very similar way to gearys_c. See notes there for details. -@njit(cache=True) -def _morans_i_vec_W_sparse( # noqa: PLR0917 +@numba.njit(cache=True, parallel=True) +def _morans_i_vec( g_data: np.ndarray, g_indices: np.ndarray, g_indptr: np.ndarray, - x_data: np.ndarray, - x_indices: np.ndarray, - N: int, - W: np.float_, + x: np.ndarray, ) -> float: - x = np.zeros(N, dtype=x_data.dtype) - x[x_indices] = x_data + W = g_data.sum() return _morans_i_vec_W(g_data, g_indices, g_indptr, x, W) -@njit(cache=True) +@numba.njit(cache=True) def _morans_i_vec_W( g_data: np.ndarray, g_indices: np.ndarray, g_indptr: np.ndarray, x: np.ndarray, - W: np.float_, + W: np.float64, ) -> float: z = x - x.mean() z2ss = (z * z).sum() - N = len(x) + n = len(x) inum = 0.0 - for i in prange(N): + for i in numba.prange(n): s = slice(g_indptr[i], g_indptr[i + 1]) i_indices = g_indices[s] i_data = g_data[s] @@ -163,57 +159,61 @@ def _morans_i_vec_W( return len(x) / W * inum / z2ss -@njit(cache=True, parallel=True) -def _morans_i_vec( +@numba.njit(cache=True) +def _morans_i_vec_W_sparse( # noqa: PLR0917 g_data: np.ndarray, g_indices: np.ndarray, g_indptr: np.ndarray, - x: np.ndarray, + x_data: np.ndarray, + x_indices: np.ndarray, + n: int, + W: np.float64, ) -> float: - W = g_data.sum() + x = np.zeros(n, dtype=x_data.dtype) + x[x_indices] = x_data return _morans_i_vec_W(g_data, g_indices, g_indptr, x, W) -@njit(cache=True, parallel=True) +@numba.njit(cache=True, parallel=True) def _morans_i_mtx( g_data: np.ndarray, g_indices: np.ndarray, g_indptr: np.ndarray, X: np.ndarray, ) -> np.ndarray: - M, N = X.shape - assert N == len(g_indptr) - 1 + m, n = X.shape + assert n == len(g_indptr) - 1 W = g_data.sum() - out = np.zeros(M, dtype=np.float_) - for k in prange(M): + out = np.zeros(m, dtype=np.float64) + for k in numba.prange(m): x = X[k, :] out[k] = _morans_i_vec_W(g_data, g_indices, g_indptr, x, W) return out -@njit(cache=True, parallel=True) +@numba.njit(cache=True, parallel=True) def _morans_i_mtx_csr( # noqa: PLR0917 g_data: np.ndarray, g_indices: np.ndarray, g_indptr: np.ndarray, - X_data: np.ndarray, - X_indices: np.ndarray, - X_indptr: np.ndarray, - X_shape: tuple, + x_data: np.ndarray, + x_indices: np.ndarray, + x_indptr: np.ndarray, + x_shape: tuple, ) -> np.ndarray: - M, N = X_shape + m, n = x_shape W = g_data.sum() - out = np.zeros(M, dtype=np.float_) - x_data_list = np.split(X_data, X_indptr[1:-1]) - x_indices_list = np.split(X_indices, X_indptr[1:-1]) - for k in prange(M): + out = np.zeros(m, dtype=np.float64) + x_data_list = np.split(x_data, x_indptr[1:-1]) + x_indices_list = np.split(x_indices, x_indptr[1:-1]) + for k in numba.prange(m): out[k] = _morans_i_vec_W_sparse( g_data, g_indices, g_indptr, x_data_list[k], x_indices_list[k], - N, + n, W, ) return out @@ -228,7 +228,7 @@ def _morans_i_mtx_csr( # noqa: PLR0917 def _morans_i(g: sparse.csr_matrix, vals: np.ndarray | sparse.spmatrix) -> np.ndarray: assert g.shape[0] == g.shape[1], "`g` should be a square adjacency matrix" vals = _resolve_vals(vals) - g_data = g.data.astype(np.float_, copy=False) + g_data = g.data.astype(np.float64, copy=False) if isinstance(vals, sparse.csr_matrix): assert g.shape[0] == vals.shape[1] new_vals, idxer, full_result = _check_vals(vals) @@ -236,7 +236,7 @@ def _morans_i(g: sparse.csr_matrix, vals: np.ndarray | sparse.spmatrix) -> np.nd g_data, g.indices, g.indptr, - new_vals.data.astype(np.float_, copy=False), + new_vals.data.astype(np.float64, copy=False), new_vals.indices, new_vals.indptr, new_vals.shape, @@ -250,10 +250,7 @@ def _morans_i(g: sparse.csr_matrix, vals: np.ndarray | sparse.spmatrix) -> np.nd assert g.shape[0] == vals.shape[1] new_vals, idxer, full_result = _check_vals(vals) result = _morans_i_mtx( - g_data, - g.indices, - g.indptr, - new_vals.astype(np.float_, copy=False), + g_data, g.indices, g.indptr, new_vals.astype(np.float64, copy=False) ) full_result[idxer] = result return full_result diff --git a/src/scanpy/plotting/_utils.py b/src/scanpy/plotting/_utils.py index fddafdd973..ce46b27e85 100644 --- a/src/scanpy/plotting/_utils.py +++ b/src/scanpy/plotting/_utils.py @@ -230,7 +230,7 @@ def timeseries_as_heatmap( _, ax = plt.subplots(figsize=(1.5 * 4, 2 * 4)) img = ax.imshow( - np.array(X, dtype=np.float_), + np.array(X, dtype=np.float64), aspect="auto", interpolation="nearest", cmap=color_map, diff --git a/src/scanpy/preprocessing/_simple.py b/src/scanpy/preprocessing/_simple.py index ad0922508a..c691abfedb 100644 --- a/src/scanpy/preprocessing/_simple.py +++ b/src/scanpy/preprocessing/_simple.py @@ -148,19 +148,19 @@ def filter_cells( >>> sc.pp.filter_cells(adata, min_genes=0) >>> adata.n_obs 640 - >>> adata.obs['n_genes'].min() + >>> int(adata.obs['n_genes'].min()) 1 >>> # filter manually >>> adata_copy = adata[adata.obs['n_genes'] >= 3] >>> adata_copy.n_obs 554 - >>> adata_copy.obs['n_genes'].min() + >>> int(adata_copy.obs['n_genes'].min()) 3 >>> # actually do some filtering >>> sc.pp.filter_cells(adata, min_genes=3) >>> adata.n_obs 554 - >>> adata.obs['n_genes'].min() + >>> int(adata.obs['n_genes'].min()) 3 """ if copy: diff --git a/src/testing/scanpy/_pytest/__init__.py b/src/testing/scanpy/_pytest/__init__.py index 0403be07d8..ab5c3ab737 100644 --- a/src/testing/scanpy/_pytest/__init__.py +++ b/src/testing/scanpy/_pytest/__init__.py @@ -99,12 +99,11 @@ def _modify_doctests(request: pytest.FixtureRequest) -> None: func = _import_name(request.node.name) needs_mod: str | None - if needs_mod := getattr(func, "_doctest_needs", None): - needs_marker = needs[needs_mod] - if needs_marker.mark.args[0]: - pytest.skip(reason=needs_marker.mark.kwargs["reason"]) skip_reason: str | None - if skip_reason := getattr(func, "_doctest_skip_reason", None): + if ( + (needs_mod := getattr(func, "_doctest_needs", None)) + and (skip_reason := needs[needs_mod].skip_reason) + ) or (skip_reason := getattr(func, "_doctest_skip_reason", None)): pytest.skip(reason=skip_reason) if getattr(func, "_doctest_internet", False) and not request.config.getoption( "--internet-tests" diff --git a/src/testing/scanpy/_pytest/marks.py b/src/testing/scanpy/_pytest/marks.py index 5695009a40..c046dd7246 100644 --- a/src/testing/scanpy/_pytest/marks.py +++ b/src/testing/scanpy/_pytest/marks.py @@ -3,8 +3,30 @@ import sys from enum import Enum, auto from importlib.util import find_spec +from typing import TYPE_CHECKING import pytest +from packaging.version import Version + +if TYPE_CHECKING: + from collections.abc import Callable + + +SKIP_EXTRA: dict[str, Callable[[], str | None]] = {} + + +def _skip_if_skmisc_too_old() -> str | None: + import numpy as np + import skmisc + + if Version(skmisc.__version__) <= Version("0.3.1") and Version( + np.__version__ + ) >= Version("2"): + return "scikit-misc≤0.3.1 requires numpy<2" + return None + + +SKIP_EXTRA["skmisc"] = _skip_if_skmisc_too_old def _next_val(name: str, start: int, count: int, last_values: list[str]) -> str: @@ -31,6 +53,8 @@ class needs(QuietMarkDecorator, Enum): staticmethod(_next_val) if sys.version_info >= (3, 10) else _next_val ) + mod: str + dask = auto() dask_ml = auto() fa2 = auto() @@ -59,8 +83,18 @@ class needs(QuietMarkDecorator, Enum): wishbone = "wishbone-dev" def __init__(self, mod: str) -> None: - reason = f"needs module `{self._name_}`" - if self._name_.casefold() != mod.casefold().replace("-", "_"): - reason = f"{reason} (`pip install {mod}`)" - dec = pytest.mark.skipif(not find_spec(self._name_), reason=reason) + self.mod = mod + reason = self.skip_reason + dec = pytest.mark.skipif(bool(reason), reason=reason or "") super().__init__(dec.mark) + + @property + def skip_reason(self) -> str | None: + if find_spec(self._name_): + if skip_extra := SKIP_EXTRA.get(self._name_): + return skip_extra() + return None + reason = f"needs module `{self._name_}`" + if self._name_.casefold() != self.mod.casefold().replace("-", "_"): + reason = f"{reason} (`pip install {self.mod}`)" + return reason diff --git a/tests/test_datasets.py b/tests/test_datasets.py index 7e69821ac9..88f8fc9423 100644 --- a/tests/test_datasets.py +++ b/tests/test_datasets.py @@ -173,7 +173,7 @@ def test_download_failure(): *DS_MARKS[ds], ], ) - for ds in set(sc.datasets.__all__) - DS_DYNAMIC + for ds in sorted(set(sc.datasets.__all__) - DS_DYNAMIC) ], ) def test_doc_shape(ds_name): From ee1e3d9aa6a29cdaa88a32ba1648ffb26d680633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michaela=20M=C3=BCller?= <51025211+mumichae@users.noreply.github.com> Date: Thu, 4 Jul 2024 16:02:52 +0200 Subject: [PATCH 007/118] Bugfix: Gene score edge case where gene_list gene is chosen as control gene (#2875) Co-authored-by: Philipp A --- docs/release-notes/1.10.3.md | 1 + src/scanpy/preprocessing/_simple.py | 2 +- src/scanpy/tools/_score_genes.py | 27 +++++++++++++++++++++++---- tests/test_score_genes.py | 23 +++++++++++++++++++++++ 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/docs/release-notes/1.10.3.md b/docs/release-notes/1.10.3.md index 23fe2d8341..2ccef7ad05 100644 --- a/docs/release-notes/1.10.3.md +++ b/docs/release-notes/1.10.3.md @@ -9,6 +9,7 @@ ```{rubric} Bug fixes ``` +* Prevent empty control gene set in {func}`~scanpy.tl.score_genes` {pr}`2875` {smaller}`M Müller` * Fix `subset=True` of {func}`~scanpy.pp.highly_variable_genes` when `flavor` is `seurat` or `cell_ranger`, and `batch_key!=None` {pr}`3042` {smaller}`E Roellin` * Add compatibility with {mod}`numpy` 2.0 {pr}`3065` and {pr}`3115` {smaller}`P Angerer` diff --git a/src/scanpy/preprocessing/_simple.py b/src/scanpy/preprocessing/_simple.py index c691abfedb..c22313827f 100644 --- a/src/scanpy/preprocessing/_simple.py +++ b/src/scanpy/preprocessing/_simple.py @@ -656,7 +656,7 @@ def normalize_per_cell( # noqa: PLR0917 adata.layers[layer] = temp logg.info( - " finished ({time_passed}): normalized adata.X and added" + " finished ({time_passed}): normalized adata.X and added\n" f" {key_n_counts!r}, counts per cell before normalization (adata.obs)", time=start, ) diff --git a/src/scanpy/tools/_score_genes.py b/src/scanpy/tools/_score_genes.py index a743abff37..d4f03686aa 100644 --- a/src/scanpy/tools/_score_genes.py +++ b/src/scanpy/tools/_score_genes.py @@ -59,6 +59,7 @@ def score_genes( adata: AnnData, gene_list: Sequence[str] | pd.Index[str], *, + ctrl_as_ref: bool = True, ctrl_size: int = 50, gene_pool: Sequence[str] | pd.Index[str] | None = None, n_bins: int = 25, @@ -84,6 +85,9 @@ def score_genes( The annotated data matrix. gene_list The list of gene names used for score calculation. + ctrl_as_ref + Allow the algorithm to use the control genes as reference. + Will be changed to `False` in scanpy 2.0. ctrl_size Number of reference genes to be sampled from each bin. If `len(gene_list)` is not too low, you can set `ctrl_size=len(gene_list)`. @@ -137,7 +141,7 @@ def score_genes( raise ValueError("No valid genes were passed for scoring.") if gene_pool is None: - gene_pool = pd.Index(var_names, dtype="string") + gene_pool = var_names.astype("string") else: gene_pool = pd.Index(gene_pool, dtype="string").intersection(var_names) if len(gene_pool) == 0: @@ -161,14 +165,29 @@ def get_subset(genes: pd.Index[str]): n_items = int(np.round(len(obs_avg) / (n_bins - 1))) obs_cut = obs_avg.rank(method="min") // n_items - control_genes = pd.Index([], dtype="string") + keep_ctrl_in_obs_cut = False if ctrl_as_ref else obs_cut.index.isin(gene_list) # now pick `ctrl_size` genes from every cut + control_genes = pd.Index([], dtype="string") for cut in np.unique(obs_cut.loc[gene_list]): - r_genes: pd.Index[str] = obs_cut[obs_cut == cut].index + r_genes: pd.Index[str] = obs_cut[(obs_cut == cut) & ~keep_ctrl_in_obs_cut].index + if len(r_genes) == 0: + msg = ( + f"No control genes for {cut=}. You might want to increase " + f"gene_pool size (current size: {len(gene_pool)})" + ) + logg.warning(msg) if ctrl_size < len(r_genes): r_genes = r_genes.to_series().sample(ctrl_size).index - control_genes = control_genes.union(r_genes.difference(gene_list)) + if ctrl_as_ref: # otherwise `r_genes` is already filtered + r_genes = r_genes.difference(gene_list) + control_genes = control_genes.union(r_genes) + + if len(control_genes) == 0: + msg = "No control genes found in any cut." + if ctrl_as_ref: + msg += " Try setting `ctrl_as_ref=False`." + raise RuntimeError(msg) means_list, means_control = ( _nan_means(get_subset(genes), axis=1, dtype="float64") diff --git a/tests/test_score_genes.py b/tests/test_score_genes.py index 4db68ed53d..60c49c2a5b 100644 --- a/tests/test_score_genes.py +++ b/tests/test_score_genes.py @@ -1,6 +1,7 @@ from __future__ import annotations import pickle +from contextlib import nullcontext from pathlib import Path from typing import TYPE_CHECKING @@ -262,3 +263,25 @@ def test_invalid_gene_pool(gene_pool): with pytest.raises(ValueError, match="reference set"): sc.tl.score_genes(adata, adata.var_names[:3], gene_pool=gene_pool) + + +def test_no_control_gene(): + np.random.seed(0) + adata = _create_adata(100, 1, p_zero=0, p_nan=0) + + with pytest.raises(RuntimeError, match="No control genes found"): + sc.tl.score_genes(adata, adata.var_names[:1], ctrl_size=1) + + +@pytest.mark.parametrize("ctrl_as_ref", [True, False]) +def test_gene_list_is_control(ctrl_as_ref: bool): + np.random.seed(0) + adata = sc.datasets.blobs(n_variables=10, n_observations=100, n_centers=20) + with ( + pytest.raises(RuntimeError, match=r"No control genes found in any cut") + if ctrl_as_ref + else nullcontext() + ): + sc.tl.score_genes( + adata, gene_list="3", ctrl_size=1, n_bins=5, ctrl_as_ref=ctrl_as_ref + ) From 48f75b2bb6aebf9b7405fbd903c747abade0881b Mon Sep 17 00:00:00 2001 From: Philipp A Date: Mon, 8 Jul 2024 11:47:55 +0200 Subject: [PATCH 008/118] =?UTF-8?q?Use=20version=20guards=20instead=20of?= =?UTF-8?q?=20=E2=80=9Cexcept=20ImportError=E2=80=9D=20(#3145)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/scanpy/_compat.py | 15 ++++----------- src/testing/scanpy/_helpers/data.py | 11 +---------- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/src/scanpy/_compat.py b/src/scanpy/_compat.py index 07292dddd9..4af24fd6a9 100644 --- a/src/scanpy/_compat.py +++ b/src/scanpy/_compat.py @@ -1,19 +1,13 @@ from __future__ import annotations +import sys from dataclasses import dataclass, field -from functools import partial +from functools import cache, partial from pathlib import Path from legacy_api_wrap import legacy_api from packaging.version import Version -try: - from functools import cache -except ImportError: # Python < 3.9 - from functools import lru_cache - - cache = lru_cache(maxsize=None) - try: from dask.array import Array as DaskArray except ImportError: @@ -31,7 +25,6 @@ class ZappyArray: __all__ = [ - "cache", "DaskArray", "ZappyArray", "fullname", @@ -48,9 +41,9 @@ def fullname(typ: type) -> str: return f"{module}.{name}" -try: +if sys.version_info >= (3, 11): from contextlib import chdir -except ImportError: # Python < 3.11 +else: import os from contextlib import AbstractContextManager diff --git a/src/testing/scanpy/_helpers/data.py b/src/testing/scanpy/_helpers/data.py index 8b3fd491f1..d98f4e36c0 100644 --- a/src/testing/scanpy/_helpers/data.py +++ b/src/testing/scanpy/_helpers/data.py @@ -6,16 +6,7 @@ from __future__ import annotations import warnings - -try: - from functools import cache -except ImportError: # Python < 3.9 - from functools import lru_cache - - def cache(func): - return lru_cache(maxsize=None)(func) - - +from functools import cache from typing import TYPE_CHECKING import scanpy as sc From 3b6983ddae76a7aa558bfe5a1ae6506a89562ddc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:11:55 +0200 Subject: [PATCH 009/118] [pre-commit.ci] pre-commit autoupdate (#3148) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fb2f57fbd6..4e0bdbe1d0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.5.0 + rev: v0.5.1 hooks: - id: ruff types_or: [python, pyi, jupyter] From 2a1f001d640f542946a7b0c59489436a653fef2d Mon Sep 17 00:00:00 2001 From: Severin Dicks <37635888+Intron7@users.noreply.github.com> Date: Fri, 12 Jul 2024 17:02:45 +0200 Subject: [PATCH 010/118] fix layer use_raw (#3150) * fix layer use_raw * add test * adds release note * adds default --- docs/release-notes/1.10.3.md | 1 + src/scanpy/_utils/__init__.py | 6 +++++- src/scanpy/tools/_score_genes.py | 2 +- tests/test_score_genes.py | 18 ++++++++++++++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/docs/release-notes/1.10.3.md b/docs/release-notes/1.10.3.md index 2ccef7ad05..6f312e552f 100644 --- a/docs/release-notes/1.10.3.md +++ b/docs/release-notes/1.10.3.md @@ -10,6 +10,7 @@ ``` * Prevent empty control gene set in {func}`~scanpy.tl.score_genes` {pr}`2875` {smaller}`M Müller` +* Prevent `raw` conflict with `layer` in {func}`~scanpy.tl.score_genes` {pr}`3150` {smaller}`S Dicks` * Fix `subset=True` of {func}`~scanpy.pp.highly_variable_genes` when `flavor` is `seurat` or `cell_ranger`, and `batch_key!=None` {pr}`3042` {smaller}`E Roellin` * Add compatibility with {mod}`numpy` 2.0 {pr}`3065` and {pr}`3115` {smaller}`P Angerer` diff --git a/src/scanpy/_utils/__init__.py b/src/scanpy/_utils/__init__.py index 0cb0be0e11..caaba91f9a 100644 --- a/src/scanpy/_utils/__init__.py +++ b/src/scanpy/_utils/__init__.py @@ -247,7 +247,9 @@ def _check_array_function_arguments(**kwargs): ) -def _check_use_raw(adata: AnnData, use_raw: None | bool) -> bool: +def _check_use_raw( + adata: AnnData, use_raw: None | bool, layer: str | None = None +) -> bool: """ Normalize checking `use_raw`. @@ -255,6 +257,8 @@ def _check_use_raw(adata: AnnData, use_raw: None | bool) -> bool: """ if use_raw is not None: return use_raw + if layer is not None: + return False return adata.raw is not None diff --git a/src/scanpy/tools/_score_genes.py b/src/scanpy/tools/_score_genes.py index d4f03686aa..1172c405ba 100644 --- a/src/scanpy/tools/_score_genes.py +++ b/src/scanpy/tools/_score_genes.py @@ -122,7 +122,7 @@ def score_genes( """ start = logg.info(f"computing score {score_name!r}") adata = adata.copy() if copy else adata - use_raw = _check_use_raw(adata, use_raw) + use_raw = _check_use_raw(adata, use_raw, layer) if is_backed_type(adata.X) and not use_raw: raise NotImplementedError( f"score_genes is not implemented for matrices of type {type(adata.X)}" diff --git a/tests/test_score_genes.py b/tests/test_score_genes.py index 60c49c2a5b..90d813a825 100644 --- a/tests/test_score_genes.py +++ b/tests/test_score_genes.py @@ -257,6 +257,24 @@ def test_layer(): np.testing.assert_array_equal(adata.obs["X_score"], adata.obs["test_score"]) +def test_layer_with_raw(): + adata = _create_adata(100, 1000, p_zero=0, p_nan=0) + + sc.pp.normalize_per_cell(adata, counts_per_cell_after=1e4) + sc.pp.log1p(adata) + + # score X + gene_set = adata.var_names[:10] + sc.tl.score_genes(adata, gene_set, score_name="X_score") + # score layer (`del` makes sure it actually uses the layer) + adata.layers["test"] = adata.X.copy() + adata.raw = adata + del adata.X + sc.tl.score_genes(adata, gene_set, score_name="test_score", layer="test") + + np.testing.assert_array_equal(adata.obs["X_score"], adata.obs["test_score"]) + + @pytest.mark.parametrize("gene_pool", [[], ["foo", "bar"]]) def test_invalid_gene_pool(gene_pool): adata = _create_adata(100, 1000, p_zero=0, p_nan=0) From 57fd1d7b17c8650a69c2e8035f07167f1f0477e0 Mon Sep 17 00:00:00 2001 From: Severin Dicks <37635888+Intron7@users.noreply.github.com> Date: Fri, 12 Jul 2024 18:08:30 +0200 Subject: [PATCH 011/118] Revert "fix layer use_raw (#3150)" (#3154) This reverts commit 284c987dedfcf2fc28dd79e682ef721ccd3ff40d. --- docs/release-notes/1.10.3.md | 1 - src/scanpy/_utils/__init__.py | 6 +----- src/scanpy/tools/_score_genes.py | 2 +- tests/test_score_genes.py | 18 ------------------ 4 files changed, 2 insertions(+), 25 deletions(-) diff --git a/docs/release-notes/1.10.3.md b/docs/release-notes/1.10.3.md index 6f312e552f..2ccef7ad05 100644 --- a/docs/release-notes/1.10.3.md +++ b/docs/release-notes/1.10.3.md @@ -10,7 +10,6 @@ ``` * Prevent empty control gene set in {func}`~scanpy.tl.score_genes` {pr}`2875` {smaller}`M Müller` -* Prevent `raw` conflict with `layer` in {func}`~scanpy.tl.score_genes` {pr}`3150` {smaller}`S Dicks` * Fix `subset=True` of {func}`~scanpy.pp.highly_variable_genes` when `flavor` is `seurat` or `cell_ranger`, and `batch_key!=None` {pr}`3042` {smaller}`E Roellin` * Add compatibility with {mod}`numpy` 2.0 {pr}`3065` and {pr}`3115` {smaller}`P Angerer` diff --git a/src/scanpy/_utils/__init__.py b/src/scanpy/_utils/__init__.py index caaba91f9a..0cb0be0e11 100644 --- a/src/scanpy/_utils/__init__.py +++ b/src/scanpy/_utils/__init__.py @@ -247,9 +247,7 @@ def _check_array_function_arguments(**kwargs): ) -def _check_use_raw( - adata: AnnData, use_raw: None | bool, layer: str | None = None -) -> bool: +def _check_use_raw(adata: AnnData, use_raw: None | bool) -> bool: """ Normalize checking `use_raw`. @@ -257,8 +255,6 @@ def _check_use_raw( """ if use_raw is not None: return use_raw - if layer is not None: - return False return adata.raw is not None diff --git a/src/scanpy/tools/_score_genes.py b/src/scanpy/tools/_score_genes.py index 1172c405ba..d4f03686aa 100644 --- a/src/scanpy/tools/_score_genes.py +++ b/src/scanpy/tools/_score_genes.py @@ -122,7 +122,7 @@ def score_genes( """ start = logg.info(f"computing score {score_name!r}") adata = adata.copy() if copy else adata - use_raw = _check_use_raw(adata, use_raw, layer) + use_raw = _check_use_raw(adata, use_raw) if is_backed_type(adata.X) and not use_raw: raise NotImplementedError( f"score_genes is not implemented for matrices of type {type(adata.X)}" diff --git a/tests/test_score_genes.py b/tests/test_score_genes.py index 90d813a825..60c49c2a5b 100644 --- a/tests/test_score_genes.py +++ b/tests/test_score_genes.py @@ -257,24 +257,6 @@ def test_layer(): np.testing.assert_array_equal(adata.obs["X_score"], adata.obs["test_score"]) -def test_layer_with_raw(): - adata = _create_adata(100, 1000, p_zero=0, p_nan=0) - - sc.pp.normalize_per_cell(adata, counts_per_cell_after=1e4) - sc.pp.log1p(adata) - - # score X - gene_set = adata.var_names[:10] - sc.tl.score_genes(adata, gene_set, score_name="X_score") - # score layer (`del` makes sure it actually uses the layer) - adata.layers["test"] = adata.X.copy() - adata.raw = adata - del adata.X - sc.tl.score_genes(adata, gene_set, score_name="test_score", layer="test") - - np.testing.assert_array_equal(adata.obs["X_score"], adata.obs["test_score"]) - - @pytest.mark.parametrize("gene_pool", [[], ["foo", "bar"]]) def test_invalid_gene_pool(gene_pool): adata = _create_adata(100, 1000, p_zero=0, p_nan=0) From 30350ec15b43fea40b00b5363ea10bfea9e2e9c8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 09:33:05 +0200 Subject: [PATCH 012/118] [pre-commit.ci] pre-commit autoupdate (#3156) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Philipp A. --- .pre-commit-config.yaml | 2 +- docs/_templates/autosummary/class.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4e0bdbe1d0..476797fd48 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.5.1 + rev: v0.5.4 hooks: - id: ruff types_or: [python, pyi, jupyter] diff --git a/docs/_templates/autosummary/class.rst b/docs/_templates/autosummary/class.rst index 618976e3ae..ea2d44832c 100644 --- a/docs/_templates/autosummary/class.rst +++ b/docs/_templates/autosummary/class.rst @@ -14,7 +14,7 @@ :toctree: . {% for item in attributes %} {% if has_member(fullname, item) %} - ~{{ fullname }}.{{ item }} + ~{{ name }}.{{ item }} {% endif %} {%- endfor %} {% endif %} @@ -28,7 +28,7 @@ :toctree: . {% for item in methods %} {%- if item != '__init__' %} - ~{{ fullname }}.{{ item }} + ~{{ name }}.{{ item }} {%- endif -%} {%- endfor %} {% endif %} From 1474a90d1b9fe1e0584aa96cb9a72d6ea4a74f65 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 25 Jul 2024 11:41:24 +0200 Subject: [PATCH 013/118] Allow all valid legend_loc options (#3163) --- docs/release-notes/1.10.3.md | 1 + docs/release-notes/1.9.7.md | 1 + docs/release-notes/1.9.8.md | 1 + src/scanpy/plotting/_anndata.py | 30 ++++------------ src/scanpy/plotting/_docs.py | 4 +-- src/scanpy/plotting/_tools/paga.py | 4 +-- src/scanpy/plotting/_tools/scatterplots.py | 32 ++++++++++-------- src/scanpy/plotting/_utils.py | 17 ++++++++++ .../expected.png | Bin 0 -> 22306 bytes .../expected.png | Bin 0 -> 24396 bytes .../expected.png | Bin 0 -> 22476 bytes .../expected.png | Bin 0 -> 25153 bytes .../expected.png | Bin 0 -> 19018 bytes .../expected.png | Bin 0 -> 23486 bytes .../expected.png | Bin 0 -> 19216 bytes .../expected.png | Bin 0 -> 24135 bytes .../expected.png | Bin 0 -> 37955 bytes .../expected.png | Bin 0 -> 39224 bytes .../expected.png | Bin 0 -> 37843 bytes .../expected.png | Bin 0 -> 40000 bytes .../expected.png | Bin 0 -> 21327 bytes .../expected.png | Bin 0 -> 37046 bytes .../expected.png | Bin 0 -> 21340 bytes .../expected.png | Bin 0 -> 37706 bytes .../expected.png | Bin 25472 -> 0 bytes .../expected.png | Bin 23781 -> 0 bytes .../expected.png | Bin 23781 -> 0 bytes .../expected.png | Bin 25776 -> 0 bytes .../expected.png | Bin 24608 -> 0 bytes .../expected.png | Bin 25472 -> 0 bytes .../expected.png | Bin 23781 -> 0 bytes .../expected.png | Bin 23781 -> 0 bytes .../expected.png | Bin 25776 -> 0 bytes .../expected.png | Bin 24608 -> 0 bytes .../expected.png | Bin .../expected.png | Bin .../expected.png | Bin .../expected.png | Bin .../expected.png | Bin .../expected.png | Bin 24760 -> 0 bytes .../expected.png | Bin 23194 -> 0 bytes .../expected.png | Bin 23196 -> 0 bytes .../expected.png | Bin 25115 -> 0 bytes .../expected.png | Bin 23970 -> 0 bytes .../expected.png | Bin 24760 -> 0 bytes .../expected.png | Bin 23194 -> 0 bytes .../expected.png | Bin 23196 -> 0 bytes .../expected.png | Bin 25115 -> 0 bytes .../expected.png | Bin 23970 -> 0 bytes .../expected.png | Bin .../expected.png | Bin .../expected.png | Bin .../expected.png | Bin .../expected.png | Bin .../expected.png | Bin 40161 -> 0 bytes .../expected.png | Bin 39676 -> 0 bytes .../expected.png | Bin 39676 -> 0 bytes .../expected.png | Bin 40601 -> 0 bytes .../expected.png | Bin 40153 -> 0 bytes .../expected.png | Bin 40161 -> 0 bytes .../expected.png | Bin 39676 -> 0 bytes .../expected.png | Bin 39676 -> 0 bytes .../expected.png | Bin 40601 -> 0 bytes .../expected.png | Bin 40153 -> 0 bytes .../expected.png | Bin .../expected.png | Bin .../expected.png | Bin .../expected.png | Bin .../expected.png | Bin .../expected.png | Bin 36158 -> 0 bytes .../expected.png | Bin 35595 -> 0 bytes .../expected.png | Bin 35595 -> 0 bytes .../expected.png | Bin 36544 -> 0 bytes .../expected.png | Bin 36119 -> 0 bytes .../expected.png | Bin 36158 -> 0 bytes .../expected.png | Bin 35595 -> 0 bytes .../expected.png | Bin 35595 -> 0 bytes .../expected.png | Bin 36544 -> 0 bytes .../expected.png | Bin 36119 -> 0 bytes .../expected.png | Bin .../expected.png | Bin .../expected.png | Bin .../expected.png | Bin .../expected.png | Bin tests/test_embedding_plots.py | 22 ++++++++---- 85 files changed, 65 insertions(+), 47 deletions(-) create mode 100644 tests/_images/embedding-missing-values/test_missing_values_categorical[pca-na_color.black_tup-na_in_legend.False-legend.on_bottom-groups.3]/expected.png create mode 100644 tests/_images/embedding-missing-values/test_missing_values_categorical[pca-na_color.black_tup-na_in_legend.False-legend.on_bottom-groups.all]/expected.png create mode 100644 tests/_images/embedding-missing-values/test_missing_values_categorical[pca-na_color.black_tup-na_in_legend.True-legend.on_bottom-groups.3]/expected.png create mode 100644 tests/_images/embedding-missing-values/test_missing_values_categorical[pca-na_color.black_tup-na_in_legend.True-legend.on_bottom-groups.all]/expected.png create mode 100644 tests/_images/embedding-missing-values/test_missing_values_categorical[pca-na_color.default-na_in_legend.False-legend.on_bottom-groups.3]/expected.png create mode 100644 tests/_images/embedding-missing-values/test_missing_values_categorical[pca-na_color.default-na_in_legend.False-legend.on_bottom-groups.all]/expected.png create mode 100644 tests/_images/embedding-missing-values/test_missing_values_categorical[pca-na_color.default-na_in_legend.True-legend.on_bottom-groups.3]/expected.png create mode 100644 tests/_images/embedding-missing-values/test_missing_values_categorical[pca-na_color.default-na_in_legend.True-legend.on_bottom-groups.all]/expected.png create mode 100644 tests/_images/embedding-missing-values/test_missing_values_categorical[spatial-na_color.black_tup-na_in_legend.False-legend.on_bottom-groups.3]/expected.png create mode 100644 tests/_images/embedding-missing-values/test_missing_values_categorical[spatial-na_color.black_tup-na_in_legend.False-legend.on_bottom-groups.all]/expected.png create mode 100644 tests/_images/embedding-missing-values/test_missing_values_categorical[spatial-na_color.black_tup-na_in_legend.True-legend.on_bottom-groups.3]/expected.png create mode 100644 tests/_images/embedding-missing-values/test_missing_values_categorical[spatial-na_color.black_tup-na_in_legend.True-legend.on_bottom-groups.all]/expected.png create mode 100644 tests/_images/embedding-missing-values/test_missing_values_categorical[spatial-na_color.default-na_in_legend.False-legend.on_bottom-groups.3]/expected.png create mode 100644 tests/_images/embedding-missing-values/test_missing_values_categorical[spatial-na_color.default-na_in_legend.False-legend.on_bottom-groups.all]/expected.png create mode 100644 tests/_images/embedding-missing-values/test_missing_values_categorical[spatial-na_color.default-na_in_legend.True-legend.on_bottom-groups.3]/expected.png create mode 100644 tests/_images/embedding-missing-values/test_missing_values_categorical[spatial-na_color.default-na_in_legend.True-legend.on_bottom-groups.all]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.black_tup-legend.on_data-vbounds.default]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.black_tup-legend.on_data-vbounds.norm]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.black_tup-legend.on_data-vbounds.numbers]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.black_tup-legend.on_data-vbounds.percentile]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.black_tup-legend.on_data-vbounds.vcenter]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.black_tup-legend.on_right-vbounds.default]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.black_tup-legend.on_right-vbounds.norm]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.black_tup-legend.on_right-vbounds.numbers]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.black_tup-legend.on_right-vbounds.percentile]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.black_tup-legend.on_right-vbounds.vcenter]/expected.png rename tests/_images/embedding-missing-values/{test_missing_values_continuous[pca-na_color.black_tup-legend.off-vbounds.default] => test_missing_values_continuous[pca-na_color.black_tup-vbounds.default]}/expected.png (100%) rename tests/_images/embedding-missing-values/{test_missing_values_continuous[pca-na_color.black_tup-legend.off-vbounds.norm] => test_missing_values_continuous[pca-na_color.black_tup-vbounds.norm]}/expected.png (100%) rename tests/_images/embedding-missing-values/{test_missing_values_continuous[pca-na_color.black_tup-legend.off-vbounds.numbers] => test_missing_values_continuous[pca-na_color.black_tup-vbounds.numbers]}/expected.png (100%) rename tests/_images/embedding-missing-values/{test_missing_values_continuous[pca-na_color.black_tup-legend.off-vbounds.percentile] => test_missing_values_continuous[pca-na_color.black_tup-vbounds.percentile]}/expected.png (100%) rename tests/_images/embedding-missing-values/{test_missing_values_continuous[pca-na_color.black_tup-legend.off-vbounds.vcenter] => test_missing_values_continuous[pca-na_color.black_tup-vbounds.vcenter]}/expected.png (100%) delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.default-legend.on_data-vbounds.default]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.default-legend.on_data-vbounds.norm]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.default-legend.on_data-vbounds.numbers]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.default-legend.on_data-vbounds.percentile]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.default-legend.on_data-vbounds.vcenter]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.default-legend.on_right-vbounds.default]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.default-legend.on_right-vbounds.norm]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.default-legend.on_right-vbounds.numbers]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.default-legend.on_right-vbounds.percentile]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.default-legend.on_right-vbounds.vcenter]/expected.png rename tests/_images/embedding-missing-values/{test_missing_values_continuous[pca-na_color.default-legend.off-vbounds.default] => test_missing_values_continuous[pca-na_color.default-vbounds.default]}/expected.png (100%) rename tests/_images/embedding-missing-values/{test_missing_values_continuous[pca-na_color.default-legend.off-vbounds.norm] => test_missing_values_continuous[pca-na_color.default-vbounds.norm]}/expected.png (100%) rename tests/_images/embedding-missing-values/{test_missing_values_continuous[pca-na_color.default-legend.off-vbounds.numbers] => test_missing_values_continuous[pca-na_color.default-vbounds.numbers]}/expected.png (100%) rename tests/_images/embedding-missing-values/{test_missing_values_continuous[pca-na_color.default-legend.off-vbounds.percentile] => test_missing_values_continuous[pca-na_color.default-vbounds.percentile]}/expected.png (100%) rename tests/_images/embedding-missing-values/{test_missing_values_continuous[pca-na_color.default-legend.off-vbounds.vcenter] => test_missing_values_continuous[pca-na_color.default-vbounds.vcenter]}/expected.png (100%) delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.on_data-vbounds.default]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.on_data-vbounds.norm]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.on_data-vbounds.numbers]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.on_data-vbounds.percentile]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.on_data-vbounds.vcenter]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.on_right-vbounds.default]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.on_right-vbounds.norm]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.on_right-vbounds.numbers]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.on_right-vbounds.percentile]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.on_right-vbounds.vcenter]/expected.png rename tests/_images/embedding-missing-values/{test_missing_values_continuous[spatial-na_color.black_tup-legend.off-vbounds.default] => test_missing_values_continuous[spatial-na_color.black_tup-vbounds.default]}/expected.png (100%) rename tests/_images/embedding-missing-values/{test_missing_values_continuous[spatial-na_color.black_tup-legend.off-vbounds.norm] => test_missing_values_continuous[spatial-na_color.black_tup-vbounds.norm]}/expected.png (100%) rename tests/_images/embedding-missing-values/{test_missing_values_continuous[spatial-na_color.black_tup-legend.off-vbounds.numbers] => test_missing_values_continuous[spatial-na_color.black_tup-vbounds.numbers]}/expected.png (100%) rename tests/_images/embedding-missing-values/{test_missing_values_continuous[spatial-na_color.black_tup-legend.off-vbounds.percentile] => test_missing_values_continuous[spatial-na_color.black_tup-vbounds.percentile]}/expected.png (100%) rename tests/_images/embedding-missing-values/{test_missing_values_continuous[spatial-na_color.black_tup-legend.off-vbounds.vcenter] => test_missing_values_continuous[spatial-na_color.black_tup-vbounds.vcenter]}/expected.png (100%) delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_data-vbounds.default]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_data-vbounds.norm]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_data-vbounds.numbers]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_data-vbounds.percentile]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_data-vbounds.vcenter]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_right-vbounds.default]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_right-vbounds.norm]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_right-vbounds.numbers]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_right-vbounds.percentile]/expected.png delete mode 100644 tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_right-vbounds.vcenter]/expected.png rename tests/_images/embedding-missing-values/{test_missing_values_continuous[spatial-na_color.default-legend.off-vbounds.default] => test_missing_values_continuous[spatial-na_color.default-vbounds.default]}/expected.png (100%) rename tests/_images/embedding-missing-values/{test_missing_values_continuous[spatial-na_color.default-legend.off-vbounds.norm] => test_missing_values_continuous[spatial-na_color.default-vbounds.norm]}/expected.png (100%) rename tests/_images/embedding-missing-values/{test_missing_values_continuous[spatial-na_color.default-legend.off-vbounds.numbers] => test_missing_values_continuous[spatial-na_color.default-vbounds.numbers]}/expected.png (100%) rename tests/_images/embedding-missing-values/{test_missing_values_continuous[spatial-na_color.default-legend.off-vbounds.percentile] => test_missing_values_continuous[spatial-na_color.default-vbounds.percentile]}/expected.png (100%) rename tests/_images/embedding-missing-values/{test_missing_values_continuous[spatial-na_color.default-legend.off-vbounds.vcenter] => test_missing_values_continuous[spatial-na_color.default-vbounds.vcenter]}/expected.png (100%) diff --git a/docs/release-notes/1.10.3.md b/docs/release-notes/1.10.3.md index 2ccef7ad05..29ff234af5 100644 --- a/docs/release-notes/1.10.3.md +++ b/docs/release-notes/1.10.3.md @@ -12,6 +12,7 @@ * Prevent empty control gene set in {func}`~scanpy.tl.score_genes` {pr}`2875` {smaller}`M Müller` * Fix `subset=True` of {func}`~scanpy.pp.highly_variable_genes` when `flavor` is `seurat` or `cell_ranger`, and `batch_key!=None` {pr}`3042` {smaller}`E Roellin` * Add compatibility with {mod}`numpy` 2.0 {pr}`3065` and {pr}`3115` {smaller}`P Angerer` +* Fix `legend_loc` argument in {func}`scanpy.pl.embedding` not accepting matplotlib parameters {pr}`3163` {smaller}`P Angerer` ```{rubric} Performance ``` diff --git a/docs/release-notes/1.9.7.md b/docs/release-notes/1.9.7.md index 26486a1739..927a57dcf7 100644 --- a/docs/release-notes/1.9.7.md +++ b/docs/release-notes/1.9.7.md @@ -2,6 +2,7 @@ ```{rubric} Bug fixes ``` + - Fix handling of numpy array palettes (e.g. after write-read cycle) {pr}`2734` {smaller}`P Angerer` - Specify correct version of `matplotlib` dependency {pr}`2733` {smaller}`P Fisher` - Fix {func}`scanpy.pl.violin` usage of `seaborn.catplot` {pr}`2739` {smaller}`E Roellin` diff --git a/docs/release-notes/1.9.8.md b/docs/release-notes/1.9.8.md index 4c954a878c..c2289144a6 100644 --- a/docs/release-notes/1.9.8.md +++ b/docs/release-notes/1.9.8.md @@ -2,4 +2,5 @@ ```{rubric} Bug fixes ``` + - Fix handling of numpy array palettes for old numpy versions {pr}`2832` {smaller}`P Angerer` diff --git a/src/scanpy/plotting/_anndata.py b/src/scanpy/plotting/_anndata.py index 29435a0826..9a80f2b65e 100755 --- a/src/scanpy/plotting/_anndata.py +++ b/src/scanpy/plotting/_anndata.py @@ -5,7 +5,7 @@ import collections.abc as cabc from collections import OrderedDict from itertools import product -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, get_args import matplotlib as mpl import numpy as np @@ -47,30 +47,14 @@ from seaborn import FacetGrid from seaborn.matrix import ClusterGrid - from ._utils import ColorLike, _FontSize, _FontWeight + from ._utils import ColorLike, _FontSize, _FontWeight, _LegendLoc # TODO: is that all? _Basis = Literal["pca", "tsne", "umap", "diffmap", "draw_graph_fr"] _VarNames = Union[str, Sequence[str]] -VALID_LEGENDLOCS = { - "none", - "right margin", - "on data", - "on data export", - "best", - "upper right", - "upper left", - "lower left", - "lower right", - "right", - "center left", - "center right", - "lower center", - "upper center", - "center", -} +VALID_LEGENDLOCS = frozenset(get_args(_utils._LegendLoc)) @old_positionals( @@ -105,7 +89,7 @@ def scatter( groups: str | Iterable[str] | None = None, components: str | Collection[str] | None = None, projection: Literal["2d", "3d"] = "2d", - legend_loc: str = "right margin", + legend_loc: _LegendLoc | None = "right margin", legend_fontsize: int | float | _FontSize | None = None, legend_fontweight: int | _FontWeight | None = None, legend_fontoutline: float | None = None, @@ -202,7 +186,7 @@ def _scatter_obs( groups=None, components=None, projection: Literal["2d", "3d"] = "2d", - legend_loc="right margin", + legend_loc: _LegendLoc | None = "right margin", legend_fontsize=None, legend_fontweight=None, legend_fontoutline=None, @@ -211,7 +195,7 @@ def _scatter_obs( frameon=None, right_margin=None, left_margin=None, - size=None, + size: int | float | None = None, marker=".", title=None, show=None, @@ -379,7 +363,7 @@ def _scatter_obs( key.replace("_", " ") if not is_color_like(key) else "" for key in keys ] - axs = scatter_base( + axs: list[Axes] = scatter_base( Y, title=title, alpha=alpha, diff --git a/src/scanpy/plotting/_docs.py b/src/scanpy/plotting/_docs.py index 0bf363237e..61f0baa420 100644 --- a/src/scanpy/plotting/_docs.py +++ b/src/scanpy/plotting/_docs.py @@ -80,8 +80,8 @@ projection Projection of plot (default: `'2d'`). legend_loc - Location of legend, either `'on data'`, `'right margin'` or a valid keyword - for the `loc` parameter of :class:`~matplotlib.legend.Legend`. + Location of legend, either `'on data'`, `'right margin'`, `None`, + or a valid keyword for the `loc` parameter of :class:`~matplotlib.legend.Legend`. legend_fontsize Numeric size in pt or string describing the size. See :meth:`~matplotlib.text.Text.set_fontsize`. diff --git a/src/scanpy/plotting/_tools/paga.py b/src/scanpy/plotting/_tools/paga.py index 188221a060..56feead5a6 100644 --- a/src/scanpy/plotting/_tools/paga.py +++ b/src/scanpy/plotting/_tools/paga.py @@ -31,7 +31,7 @@ from matplotlib.axes import Axes from matplotlib.colors import Colormap - from .._utils import _FontSize, _FontWeight, _IGraphLayout + from .._utils import _FontSize, _FontWeight, _IGraphLayout, _LegendLoc @old_positionals( @@ -67,7 +67,7 @@ def paga_compare( groups=None, components=None, projection: Literal["2d", "3d"] = "2d", - legend_loc="on data", + legend_loc: _LegendLoc | None = "on data", legend_fontsize: int | float | _FontSize | None = None, legend_fontweight: int | _FontWeight = "bold", legend_fontoutline=None, diff --git a/src/scanpy/plotting/_tools/scatterplots.py b/src/scanpy/plotting/_tools/scatterplots.py index 51959f66e7..4bdb3a0080 100644 --- a/src/scanpy/plotting/_tools/scatterplots.py +++ b/src/scanpy/plotting/_tools/scatterplots.py @@ -52,6 +52,7 @@ _FontSize, # noqa: TCH001 _FontWeight, # noqa: TCH001 _IGraphLayout, # noqa: TCH001 + _LegendLoc, # noqa: TCH001 check_colornorm, check_projection, circles, @@ -97,7 +98,7 @@ def embedding( frameon: bool | None = None, legend_fontsize: int | float | _FontSize | None = None, legend_fontweight: int | _FontWeight = "bold", - legend_loc: str = "right margin", + legend_loc: _LegendLoc | None = "right margin", legend_fontoutline: int | None = None, colorbar_loc: str | None = "right", vmax: VBound | Sequence[VBound] | None = None, @@ -1091,11 +1092,11 @@ def _components_to_dimensions( def _add_categorical_legend( - ax, + ax: Axes, color_source_vector, *, palette: dict, - legend_loc: str, + legend_loc: _LegendLoc | None, legend_fontweight, legend_fontsize, legend_fontoutline, @@ -1124,17 +1125,7 @@ def _add_categorical_legend( box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.91, box.height]) - if legend_loc == "right margin": - for label in cats: - ax.scatter([], [], c=palette[label], label=label) - ax.legend( - frameon=False, - loc="center left", - bbox_to_anchor=(1, 0.5), - ncol=(1 if len(cats) <= 14 else 2 if len(cats) <= 30 else 3), - fontsize=legend_fontsize, - ) - elif legend_loc == "on data": + if legend_loc == "on data": # identify centroids to put labels all_pos = ( @@ -1158,6 +1149,19 @@ def _add_categorical_legend( fontsize=legend_fontsize, path_effects=legend_fontoutline, ) + elif legend_loc not in {None, "none"}: + for label in cats: + ax.scatter([], [], c=palette[label], label=label) + if legend_loc == "right margin": + ax.legend( + frameon=False, + loc="center left", + bbox_to_anchor=(1, 0.5), + ncol=(1 if len(cats) <= 14 else 2 if len(cats) <= 30 else 3), + fontsize=legend_fontsize, + ) + else: + ax.legend(loc=legend_loc, fontsize=legend_fontsize) def _get_basis(adata: AnnData, basis: str) -> np.ndarray: diff --git a/src/scanpy/plotting/_utils.py b/src/scanpy/plotting/_utils.py index ce46b27e85..57c4887681 100644 --- a/src/scanpy/plotting/_utils.py +++ b/src/scanpy/plotting/_utils.py @@ -42,6 +42,23 @@ _FontSize = Literal[ "xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large" ] +_LegendLoc = Literal[ + "none", + "right margin", + "on data", + "on data export", + "best", + "upper right", + "upper left", + "lower left", + "lower right", + "right", + "center left", + "center right", + "lower center", + "upper center", + "center", +] ColorLike = Union[str, tuple[float, ...]] diff --git a/tests/_images/embedding-missing-values/test_missing_values_categorical[pca-na_color.black_tup-na_in_legend.False-legend.on_bottom-groups.3]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_categorical[pca-na_color.black_tup-na_in_legend.False-legend.on_bottom-groups.3]/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..11588cba72b7a99a08f61e7a6139355ddb649bb7 GIT binary patch literal 22306 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 N>-A^Pa_NQx{{c`vX!!sD literal 0 HcmV?d00001 diff --git a/tests/_images/embedding-missing-values/test_missing_values_categorical[pca-na_color.black_tup-na_in_legend.False-legend.on_bottom-groups.all]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_categorical[pca-na_color.black_tup-na_in_legend.False-legend.on_bottom-groups.all]/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..bf12e84957b4f293dba65b10c7f5663db14f53c4 GIT binary patch literal 24396 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 literal 0 HcmV?d00001 diff --git a/tests/_images/embedding-missing-values/test_missing_values_categorical[pca-na_color.black_tup-na_in_legend.True-legend.on_bottom-groups.all]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_categorical[pca-na_color.black_tup-na_in_legend.True-legend.on_bottom-groups.all]/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..b4f67503506673c9596893ac58bd18e5bfcedef3 GIT binary patch literal 25153 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 literal 0 HcmV?d00001 diff --git a/tests/_images/embedding-missing-values/test_missing_values_categorical[pca-na_color.default-na_in_legend.False-legend.on_bottom-groups.3]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_categorical[pca-na_color.default-na_in_legend.False-legend.on_bottom-groups.3]/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..248aab23bf8a8674d8655f5ce34e76762e910cd4 GIT binary patch literal 19018 zcmb@ubySpX^frn~hk$g5Qc6lUiV`9q4bt7+jf!*$h)9lrhzunl-7QiAQW68w9Rt#E zHt+BI&VOgEZ=G}2dVQUR%slhl_rCYO_O-9;30GE<#mAw-!N9=4ewSG3YzhyLXXC-UjO+AH)no2zT*DE2c|1JR)OR{RezeJ z{z$RrT<6Rwc$r2drTW7}imbcB&K8w4evs_iw?$~JR4^99r2Fs3Ao_@9#Hug(fYm29 z1KrSnQWs%NaZ?J5;VseC@)3NZ%U9ZLjNHWkyb;WH&H4ia0$P#p^W_tcjp^0Z)d_UGLP9@iJtv(jQkmOAJUQv~GQ9p` zE0s_Do{N=iSVvUWKa9Jy?bQw| z%5OYo+pI(PQB`V&MbGJpRVgSbW$cQRkdSmsAc&UYFK>BmC_~&=$ZeVEV9Jx8P~z|o zMseWT+IY1qi{O+SiKyr1=gP_?`-zI3{o=s%gNB28euokw>dxtU-=m$_K!v+;Gi8V~ z_HWxW#F6b@qqWo0FJ2JRpKph%kOn6;?BzVo9+>Nk>tFI-5=A}p^%a#s5Vmq(UJiBG zAvjj)Nbmb^eRf3GQF_#!v+>l0ikkXpQLr%_wY5ZoIJ_P!am+fZ?@8}LW70uT zGe1#2M~XS&VdME4{P*8-nD=Lh@BRB1-@lY3R^_+y-0*L=;W-cLc%*W9V`JfXt$3+o z!a;Oam`|~F#cdaEHO>Fz-_H3#Bf_?*I;4|6FfBYB8?V*K$mo^iX{+RXd9gpo$-&mr z-$<^-C-lceaLt_^XAHd78B_Wbig7zK#UZb~0okKA7Kz8O4o80HX=e&=ze41s-3~F{ zp4tjXf-Oxc_TSGpTv$wXTnwRhnBj2r#`QheTzHL1XM}3-=eNrvqVBg5uX-!RfU&x^ zR-#iVl&%!fo^^D_6|fVzK2aH)>e!G>?N}E#J#8@kuc9*f@j%Jaw}}nXNNIHq{zkGa zGP4JY1vQn8XB%~A8;&fgy?=MSFudB?46d-_HP-5JVl=>y6XY1NZU$kj|0&NW>%DE# znkP}Ux4*wrQCW|#?d3G!o=)vh^*UYD^D+Q=goU3m5*r_EPUY?k(_b8RVh2mTZ8Z+q z4x)G3TUJ^35LL=WzunT(NGvMioQ41@3A_j}*o{w0`^S&tTthmi{u~pIP=RQtM3p-2 z$;?%DZzo~e9My2C%vY!_%sX_ka|b6S+UzXi7Dh%GN!{%nm6I(?5(mO)ZHB%?{96=? z3JSkQM?EJMAB9CfNbN24Kk-OOO|_kR&wJPZWHL|vfgd^*#n;%dip(FYu%AE%_PxG_ z+2i+lb8}Ne^1`Rm;Mjx1J}mEhLxaT4n>VYrTX1csNEt@nzJ7h>75aSfK70tQa~(Q; zOKc5M1}CA6*vX!BEyr7gk&sn-K_3m43>A}iiqI^Zood4&~EBP*t~6tSWQtvuSIz0+&tP_L{v06BZHYZoITI}?pvWoh+mxGt7>X$Ztm`J za*R$wG{1+3hij~*3WSL%?48<8;$~-!S65e+NrSt(p0ShRdeo-FPa@jyawg#>bxTVi zI#=AXSmg^-Io^7ag&1@5@x4VN`S|%C3JHZ}v5wgZbaZy!CyT6_a)3`^C5zN99I@o6 zVQrJS`+DG})`LXWMERcn{-NRF_Vso4MEM(ysQ$e@KBe3Q1?He(8*@85ywKLys4bRs zB@%+rUjLZ4M7E*E6pM6Lii(O}VsxeB?3v18$;p&yN-T-;!G03`1KF~$nb)sgf$u1g z8a*;HLS^`xsQeyWZV7#4Wo`Xfg%s`sF7;|<#ToMcx_Cf{@^xtd|L=3d|M60Z$$)^t-G29tPxTC?ev>;Wb2ab(rM((~WYJ9Bm z;5ItXi75s@<0d91_Vufl-%l!tO!n1J(DEnyCCn@=B@-L4Yz3O$9%R(9rz4Ksu$??S zCO3t0Yg>9|ornlR&8v%vY}?k?3xpR6*N&|bxkW`WM%=9ax^~(;Cf}QvYm}H1gsuCU zUHAnB6Z)5uQ&Z<=nuE-El85cS5Saw4=8@*8Vhf!G-`d~bhtODDTom#<{8o+iBrN*r z)olDP%B)5dH<3urE?VubA1d4wZ6+lju_vX%{;-invPQW4Is0Q#28-|!fe_UC`Ygw; zohAR%6n|hW`8a?{X2^cE6XGXCfcK zPl7NBQ}TZzv*mJCIg^q9apU8+Fw@>XEU_4R25Qt>0(-*hizH8f;= z`0(L2lTL@pLq7?G-R-+=RI})#Z7(qluX+PN33`2feXsgybJ}9$gDx}T;?YRdmSn2p zZ4m~xH-p$Qz#-p}h#Wt9zd-%^Ed0AOZ z$m_5$Y7%=-vsGGVxiO-nqZb>4$HE}5e*C$>6Jkt+ck@~9P$!ecgq;BIM`Eco`Ui;- z)x9sO^#t+_wC+c|>0g41qH1X9s98;Jk_`pmBZMb*XzSj=fhomJe0+RHVr(iZs_m0A zmsZlhV)Gug;}!PQkOV%f-hb142lgnm^|7hxTs(4rurv5wlN?QUjiHVZjfI89&B*q< zw+n-{G2sZs$+b<=ea_F%A5kPW>4nSCun>nEmFqxkl{-WbnIsC)5d8V`$1IYNLFw_; zd(Jc(8ab4&bc8X6xKvhf2vO$xTba`#<9$Dn@H*={pR6)7J zE1?rubTk@G5%L)J0y1MOHx%Bl$hHotv{-cwrljsTrQDVEb;x8N^f*JO96D_hb!&-o zpZoOR%w)xZz=>>^%TdMnJvwSyHjeSbj7LFH(YSKL+Sc}o%6lCFEvyo};eeE0i{$il z$R#ucm;sISuOOKm9tuHjt*8*7A&})rWoz?(d^Ou$e$-t?Mh5HpRe%bRkE8+vB^O-A z{ayeFA`zV15&FhWYM7_q^U7KnDY&q>XtC~bvT6`UWD*Wp7s9x(un^AULt){rnVC;V z{;k{;R8%c%`#k*o<_#IW7Fwhf)+rrhV-%UnKk&Z49m6uCGp8Noi*^%H>frBzg=9rDJk(GX4aTFdhK`fDUZ-0*hWV9w?d^ zU9zOqAyE_@YSnr&8XD|m&kIvs65z4*I%{II(=FbX>DzV znqVhD4F%}v$Qud)B|UwvHhap_bLIq$|0#;ka#R5w%4Y;=quumnhrZvAem5d7kZNva z6;@Lt0_99LmM%yA0Y~k|@VSt-Qj#pT_31sQrqdH2bE1!p~@me2gXb^{A zH#If=UQt1ece8(l38#elhhdTVFZcA;P{KKvYB=cEufFC#la-{vOA(eH{*XK720M{QcFu#-_zQQalQxrGx9UmU;&pJH}q=4<(! zH|-`bUBiC{OTC7@wzXx;QSH);tI%6;NzTi=@8j#+o2$~w{V_TDr7CYuaj|2UbLYr2 z$ZlEM?0@%ttnKX+haF86DJdvmogld(kvswdA&}B*YbR(PzO;Sp57ihz>b}p)=H}w^ zK=$IbUoO3{uY-e9fTAO^U^_MQhtoK(QBYF8bm@b5kvQ$?>3P>>=2Wfs{rmSBHxaF^ ztHIj$7`a8lO-kg%=sHEtgxc+}EGIZEm^-aR{iyRYEsk5sm3PZ$4^EtGrvPCUhD)9& zD}?+9@VOm*zHvu2#N$-c#bRoE{lp8FdY+-2Rft}d#sqg9Qqw_p1yP@MzOABdU0+FlCDrdwv!h{`_@p$Nau*wJ2*~ibhsT+;Q zu5OV*nUaTM0_`$0U4hMnRs!^)2LGPylFWUs<2Ves;HNop45i+>;W>3*a>;JMowk*G zd3m|Xp)xgmm~BenPHHcYn3zJQauYWmWG;fxAP5vAif=TR&=fl6-*P96%|YvTf^)2sk;=H3^%lu9qAAbD==l8C>a974 z7Ie)zN<-(rP&4U1VR^O^;o_3lY&HVZ0vZvtq8=C@@9`s%S!>77Vuk;mz(qZ3VWk(5 zR<-a+>}!0fK*@b=pd-co?bSA9Q(o%6rir%IAANCX zH)S7>mE3nJK0zz#d|-)E&{Dl()_r4Si8u938NFFO~U?F=_VclMT)M+pXL^)Fnl0wjyyFcI*IY ze*NmlqCaDJ9e(oBcmF`yDARE1%W~ZXmr8l?4V>4rqT!W|q_P&Iwy4qB4arbNt%v;l z&|Fx;NAvfy0jSQkYvq*gf-*r-Qey_1EDi+A&yooC#+n`|~Xk%p49TZg&Lcsy`?U zr!6kjWJ?uvT-=^*wRq%KnraB>k1lrUZF5h_(c|GjNwnB-*1O@<63AT(E-HEIAJfxw zii#W*=WW8GSrGluKZNO@F0m%wZCF7KZf}jMmYfV|P{*8-A~hcwXCkP{MCXzMD0DrD znM#vq`cb%AjiD~vrRK#Lq7wr4f7+l13TOH97!)Tdv%YPe^%{Bf)27^{Tqjny-iD$h z-qu4T9m=dxCVSYF0}ByW+Uzh^NrjxudX}3=@2_7(rhE^NCkYe&99yW@zr|Th$hq>~ z{)N^n{1{Y_<7vR3i<2`_Ugy0wZlvbtva*DycbzATM$3)L#-Vz%6o?OwjakL)9r{VQ zCjR6d-|+D9@mb#7wCMi8(Rt$qd?gOu3Zn3*7*@8n+4c2PdK)~Fl7V`0atwVp^hbq# z_E_Pxy(eW+OY#rP!*y)Yd}hklH`ntb&c5pH6RvYkb6=usw|y20^ty{_Gm%dfG%e))y1_-f{T$s&V+ za&UdiPKq-yJ{~@?A)uAl*WX`!T#l_`OH9GxV$r#Lv>>{pASs31zY(?JMUJ-TYJT+6 zD?-l?QFyvX@8uhC({dLpg;#;SE;XL_jq?o4S7eQafQve5@W_ZJwDgw*P(uS9Kz_hZ zTL(iE6VE+81tD)i$IF|CP6nz0${&rm&wDvW6NA(&R=Ypn!?oEvpxGh_y#~n?Fwnhw z_h2Ox{)x4f{73@Y@j$0ogTo7R@;$>EQK z64JT(^;_|Z{ZCLAh^CgH4xRCT(53$x9Blc(p$kjTE9(z6mX?;*Zn`eHqeG^nqXQ6= z$n1}JBoYcT0lfs?xB1N6{QO9%%%od%A>@i1}TkixV_ z!)&a_Qn#miQw2viO_ZcGGyv3E+1O+iZLTD`0vGTKARZdU0+~-mW0)obfk5O!g`G6` zbgZ6-d=SuxQuy^=@16?VaQy|TbY@{;G@y?MMLr#z7ovaYz37YD80^}GZhrc}qhRlg z$>fL|tjtv}+4$OT^!a^iDr5sU|1|9W1g^-H+NnN>c%@v|X8}g#7yJSOS=N7^;@~0B50f8E+`r3fmz?G|BxAN9uv*IBk zDn_SERq)W1_YP9RQFvDkPwb-m?acrw^wve3of&!JayyiOj_{10B|eOj`9+V>0e4vxvSzj+!8$NDh$WH<%_)W4{H8JF8;7OQX zgaa!EjKUqFJAlK&pY~uNbzUij>Fj!m0pvUlkWBgVP*gP1n4)LD?v||snN}&n&WVl5 zkQ$lw&Y{M}IPWHn~)T5@Rw$`(#RgJaHBTL2gb{L1#7;?2p6SJ5W~`~u8*NceLod^AS7pRO61VTiUmw_5 zbGw(?Ij8ciIT%0Ume34aPk;D8_Sczyj_VkQK>W#Jb7SjQQsvbeWp%a)BxeJQ!{VU* z_fJNJ8zd}k)r^6|N}uZM0Y*8Aq(c^=;gI-A=pS^C>+mLiNvM-!;}zOdUyj=ezNZWXcgir4AiptTk4c=6XY_Yva+(hiK)XTVNzky zk3Xy-UJb3ZEx2T|{*+QuM8$p+KV?dJPkA*qFnzMPv1+?RQLD9E0zc`z|Brw+ma{xr zr1>*{1oVNx(8Vb8#;6SHO+w7`A62z5`FD zaEo>AoK~XC?I%Ru%jbl3&H?a!C@3iF>RQH*PnO>YoY(MhaO>=+!;q~wMHVbBrQmMX zfmOCdc?AUpV4K3*O;|X@*q#;^rZ#=m3lM3{t#RE$mWX_slgGF!`mbQxyB&K0?ah;n z2ekphwp!1Cm|~?SU@)i4{Pg(8)T2&(dCpgxrMY0+?ruoobhAg$Idu)0N;C zWOD}PV{=loThY1y{WYGmtg%?UUUhta(ge_56G=|Ms@_X>heOgz8|0O zO`IHRT(JA1T=9b=`p&~iO?UhXQ{6}8P!boteSO5Soz`}CZBW~O{W8)VjOm<b3u4mTaW`$YMBhc;29L)6%u>BBx#~cW(Z6cfaRgI*N5}W)=H|2uHGxkCuy0Zl)@#u^>-3An&O}R} zh0C`7W1XgnY*ln?__NZ)y9mF%(6&g*2R^~-_xrES`Ipz!@oEmZ9W$$0g)|$Y&V@Y1 z%DK(S++H62bCfwO?qoTvMbOPeHj1?f28cJkKz#h_9I1ua+d!-3sqMl5lvTG6~B@}vXUh@`SU5WjAot_>QIdW$ItaboH6pHOX6MQ)FhV9 zeiSMw;tP6A?&{Pl#CbpzCSeS3@&n$K!NW7Fc+q2v!%k5GXILCK6ujc%{w?^g+Q-W{ zuV%~AdB26ZO^RVYvc}Aiu|yy`D(V*s)xW*X?eFgovm^j9{{eKE2`tLpVrO)$nQ|ad zihg(B;%H@C0>fd<@5TlC4f!?hj~{1;C66T+hei|+{DRX_$G9#FE!B-pw~u@DL#xhl z36)uGCyx;?Tvj?aGxY{Agt!wI^-{+jxKp< za2R{=kgR`rTV6937ODUAR1DA&kYJY+qcYTLjZ&UE+>jb8`$lX{(UX!E^r?OnqlMQf zN##SGD0IS_q@9DR_Y|STRgs<#s;67B4ZZD^Q#}L8C9Z+5+4fMfOI3>rjq?ZD*qfWF zUk+M5xs$b*5v@CS>5m5jM8wSI;Hr-~*^GW&BUv>Zd)rJQo5?;?|ui4zKxz5<) z#!y7L6&$8f17D6UU(|`$a%Sk^cz;00j~`*|TL!Iwxjv?)!SS6#A3=)1~^@lz%^-r(`l3QIwj!7Og<*?O8j zYUL*>|Cjh1o70lLbJ^J3cqY{(j)$VjdR}+?6W!?$a<1+#-WFfPPR+|x<@qH?R7hlS z=QtuHp_4tj=v+c4KN}goZPl+nz%L>AE$L*D0Op)W?T1@Ox!Im^$oVSv-_rGezi{80 z+f^0}h>X;}->U5KAwJVst#H1a2UB+B{D(?O7BAv{=|K};j$TSeSVFHvZyGDL!uz92 z6wBd>VedBAiHY9moc`D-mzv4l4>}(uG&va2<~U4+Uq(w+3L=|WfnVU~Zy(k&RLoR< zm&j(T2T3|k?vh^x5;Dnj$winKF|VC{L~#=TgyyHhPVS3Ina74$8FmpjXoKQ+_Im$5 zE!&OWobisc+?!6?<4NG$CBN9AIAKw3bLqqkXHjEaqe+t=5{&yB(^wax7`I-sC5b?TqyeG~hxjpR&fX$Ws33b6MI`6Jz<+tm()r=xG?KU$R|t zjxbTG!^~3V_0>7b>Y>22NB?WtyWj>`KE^H z3JziH?ZesEe4cx`a%A`^b($%D1nL^?Dhk_c7yh@4QByi)Yh!YxrnCwMmo;QDE0WX1 z$%!a;s4FMQKwf`p2s^LwsMisr>Td*_&G1v_D4V{=`!Xrr3%~gAH8hgunQ7PzeyaZJ zK5b7xU1`eHxxae*+^nk&B!dL?(T}+zWiFH<7srx3#c@Kz)@WzIOL%MIZm?w1*LhdP~*fZNqJocq&~L}#*f zHPBrQQA~j9^ay0b=IHFlq!(U!Xb_pO{!s9@uPkD|TpU+0vRKlY#UnDYa>HvN+3=V3 zS1Xaxz}d$lYg2BczR60rKRzd?3{O8FJjr&Y#Nb@PDrH*LE&MX_9wG)x9=ys}AiOj~L2&nInUE_bUhSU2GC`TT_y2mIU^HrY@SFw!&{k>+}sT!=P3V7SUjS1T+yb=YNc0$$U zuxnRlFS2TH&j_LYUcGvF)I+kDV?w&0fT>PtKfCB>-^oce#ZY83-jO**aj{oRKO`vl zrhgOp(#Wj*tKas*gpg43-`d!yqMyQRlLAH4gH4k4#-qqIM~-(5{^vgyTmVC)4!0$t zo75J{M2_}i1c^$0w_m3F?fnW&Mh(3WK6#SQE0@6gBT#Yuo5Qhhj4t8U2J4aGOhQ(IPUiXuP&??8hXXmr4 zl{=V)L(^;=>yrLz9zHopTI`{y8@hVVC(I_v!r>pHpt8ivFg6Y3AHGFFYV&tIni12{USX3 zj!d1Svl#{n_jv+&AIcjyVuv4Blzw}E5?$XvH$A{|R2FIIa8nwic(oylEu}(ri=bd} zAwxh~rOL)t+!uw$Tt8h-&-Krs?UnfV;`8{(eD?is9)VnKU4Zssmkf$MdpF7d^}m>I zCl9#b4RAZdjHQlKA#GnD9Zn1a^sGOcoG$LHgx_?AKJ)WDWzb1u;4EIV@bgQ{Rh`2# zU;6fd?EKqNHBDEKQ|Eeu9x4F)poiAT^;;KS1P0aQmCcjZ*x9n$Z^#eBjoU*or~qE* zFB&z~sm9A>_u##jfYH+*_Bp-zPA_X6pY_EH)iQD;Gqu@eMAEdA#`4;+=>}*^$E||;P+N|uJnZ6j9At)^`O58NM7c3usA+k%P;`y#S z^~L#TpcAbe93;$l8XA}XJjqIHwRfF4I63NMX^@sK{>K0Nr}TbmRsF>kDFUt?lMu;< z867x`eTdC7VuSnya(6L(T+71i(w!;KZp$sQX_MaA;2U|ej*vtD-B4*bmQ5-cmqb!a zXDS;3D*y6@8MFyCMI_MfZ}r1mLq6x*xE+klk_0>^OD~m9 zrK}7hU8&x$w}Xz3j?^m3U^Wi=3!}`NiAD7ElzO914EnEG$*WRe>ICim9~uTuLPra& zZVM0P{^2--4EmLY6b^Fqhv!A+{e%)dD6vD@^G#&s$0h8-%;4LdK1xA9gXnOzDuj;) zn%7HX@|cZ7(;i49MNc@?4YCKY^)HL6Cp;L;BY8R{q}Fv6 zl4x4so?!j2TZCG(?bjK>7jrj)H>1$igB7W|t!A7EsF-hd_D*vmGFw z=U$3pS7c{r`^}G{X8SkKa9qb3$wgC+PB@Ag#QFP|4=Iw@hXR-JTeVC5UnGKNhK2yK zT?3OB_XdpGYpGbFt6z(YbL;EVBXtB_=Zcbc6InKAnp?OZBM`mQ!HC!?lZ7{Om{ZLi zWdUdTv+i0B3mKkBh8bhh12;H6gy1lpOf}fDF%yZieDl=ej?9HyNaRG&x;Xa}%eL0UsW?k< z%>oHfB!Q}n8!rgPnpvzgB5qh38oi~Y!x9<&OEA{$guxn4Fs!V;gMtR?l+`fsuaZN< zjEGAfsn+$H>aPJLXj3%>a}vMZAN}6mL!1uu{$WkVf?Vs9?X?~TviA+mTwLOTU@)B< zdK@{l@;NWhI@4-){ZiJXn)ejQ#;pTTZ^0Pm>0KC2Lk;+3O{H5vc8*+YUtgJ4Y|{z_ zGRL7Zn-vG;wPW~uo8>#t@cU3)-Lohr9M)IeI83xPQXV+BqvPgx{KfPI!m2nE($LFxgjr1ZJ`F>Od=4ALqv>y7OUYBza^n@D@IWvUVSnO{+thtH5rQe;<` zE?uHU+b-hWaPPo8scZsnwt;k^LL85Oaxn3~ScQF8Zh@cZ3C@|}RIVimrT%aa#C9EL zQg>Z4NI`gwR$;>05#zyWwX(SSfwsLP|{&cZ6jg6yS!%{@bG)A(p5d$>6U|zfahOS84c){Le(0dNE>q^ zvZgdTtt9%A=r3*r{_?pZks1l(0AAXeWOlMhN^XsO(^jcF*tphLVO;4Y)(5GDgM*{) zNZ7Y0Ex(*E-a};C*ZrR3a>=b7?Z+xd6TZwVc;iP4zlNmkQ~foW2XWbs){!kt9CW4T zHzGCK4U|A_IQn$EZu*&#y6JH5?O6P`N*Z16Ha0*G$njCN+lYH!;O3TLJ9y9NPI}Eg zugdafGxVCh_`BhGZb+9R8KG8wtNi36XL^-IxW#f?spb!qemE3nv|WCvAJN z#tkWqY43qZZ-Z`+inl2*PEtm)8vTa}EQW5J&&{e#`@Iy!%vE&@uJ_w%xObQ?P@2QD zqZcev8J)Blw)?{=?L}h%x#+|jydDcLGu96JO@{=%Y${$n(`U_tYK49BIjS&RPDx4W zVcJ^yiAjGbz%k7&xZy(?_nCIN}2 zu=k6k~Oa+>3NT0v&RRK3Tonq)W2R8)H|G4F&ui~)W@Mfw{ z(`ORDCz0onouE|b7OmF<@tBxCT@i%rkIgUBluh(lzh))T19+*uGJHO}C%=x6BE;w0 zMp0Z--fv^;7p1ZssDn%U{3_bq1&O>Y=!E~z{di+SS`jLG_#v@=+6S~A0 zD$_qrC?S=<@UJgz8TvXGrn0|0shpYcQ;OBH@L1h*%}_!T~K*_WLXONCca`OBp%uM zcc#;{QP*WN%b@v<6u;iF@kJmyhb2HMsI|Wqabn}(KO-Q4#tdxfuJJ$&@E2%ZoK`HU zj<~TycA<3_JC95H4IJ`I8eQEUD3fxGJ*QcT+J$~8W;{ToGf?2g%Q3Phb-Q_T&F@2T zPUv2+vbUFpsn|)BzglQ@;Nl(8HPNGmA0&7Si(aN{=D%Nxw>@~dtCNgrDm%8~c+bim zT|R55BEa{%voZ8_^ECB&M$-AVqxZ{E2MO<9dc+QYfvjUAGGWcLoM@N*v}fxG6{tK% z7H%2ev`kZ`&A!-+ol*a3whI{McM8m)Q~>Y>oDsZ$G0cdlPLTq0>+j#BAT#hgJ_;-~ zvnejHo)r8?n(Wey7lk3OL#d(i3oo6X?g-ywSU$bA+iLR=qnL_Rf5MN!>ZV%ob?^Ef zrU8edt%j&{{Qd@pzcLn;$gx6Il{vqG$y2u?-4boRogJt}lgu!$=jG;paEYHtPOiYQ3Ly3BsL`*$sWyOBtp!a1886w95Kx)lG5IYTZg{wq5p zmhG|B`P^Kd3g=$Alk;cX+lPI>0@WV!wKzyRj``qg@jL47>^m|JgUCaXm|}QrMU3)` z>U}_b8yg!?m_V@gpI{$ggXF@tuRFFMh+UV^1E2tvzrPbte~MomEfGpyxyeX@XQH9L z>3wz)+FHstYWyH|rX(3~KOvV*%{woq&a=4_Yv&LOt~P8@zaH`-?c0eFnIzw8t7{x^ zyHsQR!x=C{PVxQzrc@Rm{s|VMPg9!JfI0QuxKA)vhfW1R6d+HS&IF%(MKs9`k*!Wv z>2ZSEBUQk@#io3>Q}To*t>!1fy&+7F5rkNo<>kXP?h+%72dI8O&UVyR)s=Spdpa(= zLE*CALc%}TQn?nJ$6K|dd5~E=I$>x++9cPdAExWpwPA))VjXd9jPwns_-qXx3?szY zQ8qug@qiZxf$JsdVB6Xbvoa8v=y5_%4r(lBvPck2sc7uK49Z%y34?(#NV-?tsB(v% zy&Ukq$iC>)laQ{9zo*%=y-4r>W^I*gru3Mu!tQ0t%;aYA5=-$Bw>(l#A~7?sF!=S( zt&Z=c8~ciryG{16Q0jQ;WR4%Hx%?iUg+DtlypWjG#5}fE_aOW07cZX!%@=c=+`H}t zr6ZVJH=2n?!|)e`-%7b88XC?b=`7+EHMd+JB=Vq>q5hkXGB1eH7t;Mt+T!O?H*%D&niCM2zc|swKhd5tPF&fR6m!{KvCbqyP0&I4}@u;-^#M4g8C+9Y@Bom zQ!1&MYxngF!*bh#`{&7PUqeGgq{>-^Yy% zW=>A`k819ne`xHo{uU~KWdoU;e~F4jz@cTG=@7r$QC8Gv@_#Z^{XOV7lwVSycUP|+ zfxynVzhuWdjd_!FYI=HE4Gm~?DJi7y-U2-*sGch)>>D;+s;wLyF||t-8mU;*e{OGo z6OJ~R8VCTPtEfc=coeF>=Fz4-*>#u~oaJS2;x72KbmAyD4hO>oA9gg_(a zMf8en_;u@4i#t9!kMhSQWt%sI5~o{!p8bY9f=P{W*Ld&kwRe8~cDmXpRiFU}?A^r1 z7nq#F{2$s{D=RE*xu}AeL93Jy7*_Z6h^?v3<$+KL2Bjd{!y_b2EzW)59Uva~QAYMv zvPt~ZIp=1YH_o*ntqKXu@4*WVEb_ac;Rk8AoBq;n%tl=Wk8J6?xrVOXD(j{0kI*G{ zHMQ=A=#0^B%>G=opZvCf9BR19&_@naC)Nm1kFX>wm{8mVHtlk54`>n;o+_l!-Sx!N4 ztJalI@%nPt_mBL*m%%G3>B#J=nTM2j)Fr34UHdDIx**b&UWiyM6ss%=4Xj$UfBwf< z_nxRBuCsuKYydL50o3Cf8lY?ka1%o(Zo{npLO}seQjbb@BF^=z6d}!RZEufsezNXn zaul2K(a%YC(0>`AoG%*BJsge0Jp6W2zW)8va0Ze_)x0*4dO*xuBpxA^S)a0!{+%Fc zoUNEOEXglDX`Jz%HzWT2LqUKMs`$(El^DJbM&f7E1B#RGkWEWq7|dJ~SeM2&9kMEGlk5b#!6o!HKmUowFw;HF zlrM3;7QjQYMzmbiE$6HwxBdpFC#8)OJ`F>^x-Mg@;QkY-ng{L(cXxNt55w3!i5*jd zwx1o}DYG%Ld6FiyY^di04=~A9Ep?w~ufn!kSaj$un3QPCF%mj8q-ZalRr>c$)58sNG=|9S_mnygco(`Ejq|cx}@1Yv%9273>;z$R=8wvcaTAA_sw} z&0+;|3u0_VH6vHml(k8=q9H{giQYzJrsAH-+2SPB(RdHMc`_w4-t7?jdZbj_UYn@XnMMBby2EE(Iw0ZlfQ6q|w z}1&>t^6rdE>$24H~t88bRgk^zy#LOj0fcJ%_b$kMn){A)v2ke zU(_zA5&fN9TV1_+2WItP`QuD#1*N6dfAq$N$MZ(Azoc-NpODWtb#-+?#K4Cupi`)c z_KnwNY&*&ksnOMctiwU_i8Vr4iV>_9mMpRO)M;6)&ym`=3?rd7%8YNdDgR&DZ2u39 zBc&Kv?$z(%n_5 zyLx>Bb~&`wSyNIrEb(2_*AU2IfDZLXdz%0t85z5d0yG8>MorP&ju%u{LzjY~m4X$e zakzpNpO2D51|)f6ig2_PjIUFBRUagNxGpmsP-IO7k_0G$NFqfTV7qfdC`5n+*6}fJX84BMd};=WJ`}4hY=-e9!YBZ>nCKKq51evKLJJ6Hq^> zR4Q1}F2ipD`deQf(SK|3uV7^We;DK>@XG)f2WBvSQLaX~vS`B*7NUNM zd+TuVUT$4D0Y1L-PCGel2sAUlg>7<(EVbNy3RcGgXv3d^`7kp(I|$r`pb`ZC0*Dl^ zzHX{^SS>C1ZWy#@?;H@H_nk^jW4MRyO|bBRDYR)&fC*m#wo!ioB@uLhOW)JkoIO!| zLo2~~Z&uvm>M0@?>%6igY_ z#;t6sl(e*Y@H%t{1ac-lQ6W7IxOizdoLuYS`~It=F(2Ei>o-f?*0P3+#9}`t`qLTA zWRPaMAsf3j=gANLXYFxj*3ThTmczb;QYLoN7Rt>n|cSURS=%d@TYW~N&M}BO_ zX(UW)R3Xhkn}He-$O&!=y~MZOv>aE?7dHCMw_a2Jv$GXiP+LgUGU(czss$6G<>|Q8 z@06mo#jNl|2t_uW7`)ad?kEywuFg4UFnmH;2UX$Z_vsaF>&BZa6Ms)Zq$m8o*8T4wod{P3*R@3m8EV623vRIVEA#h5%oe>mwJ1TcpNGZ z_!Ml)Q`jsf9S)FsYcU_1N*&TPT;@oZ@KY(Bh0X@l9T5MS%8=5OIg`R=vh!UE*)~S+`0J(x0^bq} z$zsPV%}J=It*tFWHj-4jdBYFt&O$T*xxj&zber^kgvlZujG_J$9sR`n4(+CHg`F_x zH*ii`y0{R7%NaD+kg^Hr#H!{e{}V5(48_xdkBqT%nI=Le`%+~L=C({_4DQh8q_UO* zk$p0(>sEGl*FS+N=lJ-TqyYuiAaKoWY_xB9kVLkBfPqs6Z=Bq3H{lHs)>NVbM630R zEbNK?x&e+BaGZ|nwSYVT>@`{B!uz4YPG++gFJAmF@1{*T@qZk8Cs;!~)4;8=;#O)s z#0>l`OpAeXU#@Z`$GH*T^?A>hK~wH(wyT_m#(xm!CTxknfBnlI=V~@pWVYlmmCUTu zM@w{hif<&VRL7TiRVlas+2 zHaIjC^u<~zz0aK9v0UeJy_NrYiLn%lr7PuviwV*fIJkT6mnR7O9d1X+=4wUm**Z(W zsdWW|>@Sd|x6U@1l)%UkEOh*hj*u((?7P%5K&+0a0zLbObh($b!8(14T}$Y~WtjkZ zk{3;xh{s#qnMYY_4fW8I_x1G+pZGEKmBhplK-625m3X5qc#?bKU$sG+y4U`V8(;G* z;K`HLQe08ZEozW<<))S9E9DmIWW?^-mRylDQoq(Yat9Q|`x?ww zi`O`0-C3u&qs+xQz6@EH-QA*Ou~8Dcg7O#toIB%*dLua1P>}kSXsOIJw>4df1?X<* z`N4!VWDR2T4|Re$EN$a_t z-0!#8BcU6{-(gZR<5CS8SkTP@+=j`L1vdDbYO)$?2IKVgM`0&A?H_(O`R{`F0335u z08avS58P|O3W90)$gP?fun6?c9BW;r&^vI0uaI*?lB1r>&?`&f#hYU6in{gpp_lEM z=w{X2o}^kBKWyPQSZ#P712-N}v2b{E6Hn9(4PRs`YdcG!x3{;k1zq$7Rz^*N!1x`F zT)Ylg2Lih;i{>@V>mDTP{Bt_tO?T$VUW_CQ89xbZa6-SI^rJlLa_6kYl7(0A($1PUnLC1D@vrn%VT1x7QaV=R5AV zm1$c`xp5|$!hlej)ohWP^PsuYq(u2Ygl1XsL+ZGE41=-Liq^);>QiAMK4e=);!M>% zcDB$=sz)4xVc-=O1^+X|78D>@pZD@i=;ozyXehvJrPADvUh%qc$ zFcJw)b}*MF${Uwxe_+(oB6&pppWOI;_rmRs)(Rc4;#4nX_+CEYp?PNJ4)hRng^vDf z*axqPP3|Ez8|dliWK>9jDM$|0E(|zRfR%uIN*0b-s*!xwNVatEXhSa-`2R~cu_5R* zfrx-q{Xc9IjFzEBW(}~$$z9JKsy2e!I~$gAf=%+clvWx0ZcPGCL`Y!P)}TEH{VI?+i+dBv@c|qHm-m~i zu8~tx5(gJ^(}%GsFyB29)x#XpeIX4;x6a+Rl0Z~Z4FmUv(j{h?@FMm#~rw-8(J+A}_@O@PQy^F!<#$dp|ah>2H3?tbvxQCsFNNAEWQfDOviM#gjou?2+tbn!eK#w;yHFY_<8~v1< zYuP?rl4R;zm0rAF9c~yS(S`emQ*6OWl*SON2!Q_dxsp_YDGXX*w*li}KxMQvHw7VU-X(Ly=LB!xJ<>vRM6I1MA8Qi6chv>4OTJGNFN^P4$02VFLtE25Zb%C0_t0 z7e)q@&=oxn8~%Rz)QnIHfxjn-FJR=G7e9asrA@sncH!K=h>9`9yna; zr}RCi+Rc;nWq?dAOuheB`wAop@dSACibmsMJJ(p5B_aJ`6DGhCzug4H{7xr5JQrmU zg^C?rOQeR3OZmTl-90EMXwrRDe=_jm3~btEmi=@XoHff?RFw+<*EkAyEs5{`>cwT# zwfP)yVhnViON36?>t!5@VV%J6i#ypd(c-n<-Y-E;3kBX+p05Tqn|H1I+*iJ*x&HU| zdgsv4vbVQfRfJZS8n+5)EBuXG6TV5ycTOS6BUYVGL2!OX|Z%J|jF&CSV`pM}N#{~o~X=wivj z2_pl9EQ07H18{|cf}{EGfmYO58HIwPF*xt;Y9&b= z^6^FTZTuP@C^wlJrWu>mhmly3c7X3JMDGwUF=Q z#eUE0g}`4)ER%l%BINJ|LkpU52i=`g~^p@AT#N%=fu&S*WH(|=Mw``?YNQq z5(Dligzt*buLqD>Fk*+F{!|DLSBSh@U-W`M5SeQ+7Dtc0oQ^Lpgb&yZ3=ICyLjJ|b zUuP6fmugK9XYvFeR!r?y8lZz(d*9C)0Zn0$6-)kW`CJcJ9XA96o+piN+GqV8LgX2T z?*8}vWdlz(cJ_hCUanZ?~&m-W(7) zt^gI~<&iJFMg_bk^)?0|>ZAj-BQScN(4KS8o0(C9vI8BwoYvDM$^6KsCgO3}>jl5| zR@K&0rOD+1XCf^qae)q5Tde3K^iIU>*Z zyOHI#|Hm0jg=6wUP!FHs#EbG>Ru-|NZr7u8+>G5+1U#-BFi@_T^E5;w+#e}?M}9Ds zHORHB&ykKz;)hnTC`+9ps`F-eB<>e&yfYa7)O>Sp?q zG!Z^1$FV0XDd`Im5)zb7hug6Pwsw@YB{)=GT^(y#-xc*|pi?7bY-`Vb?SI;FTGyFy zap4dX8w+SO8J0CT)Z2W)-FC_>F8=1wdCvWCwi>#4Jaq0s_TZ(dX>Dh>cUu4!1Oe@L zZzfqpj(xFr%;+8(%hCQj61&82TTPq&=*)fO=*%<}In&8X6^L-5P>^GUg#tIvc^-9X zZEfAZdwo^L;vY@+aTRHLiL>LDg&VD^t&OLss90YO6P8(r84YuLI9t)wVTp;NRgI+27xOX1$%aZzj(nZ17~8+R^OPx-@KDRrygv_rwB8x%>G!TD zcpXUuxE^U$S^BzY5uRDi?_no?|Ae1FV`XP&W@ZMHF)3+mye)yJ7$qx>Sz^t+VeJYI z6zrQ?#xdsW^xkU~q1iKxt}o6W?fEBlyS1A-o2dvGMDfw{P}kjzDwY#3!AQxnUlqJ3 z)?l|lvlSQ5;8KRbJP*=M-neQQ;Cu-`v6l2w^p2o z)y0V9^6g;RYnx^E2O2y8c!y>84Eu*U5Sc_#;3^#X`4#;mCt@K{#nl70TbU1V6#>iH zrIbubPE9l!)Dyo&z^!w2!ODSaC_0L4@1=m3r9j*YiZ{kDRigt6Eey|nHrHVE+!1L- zj#RJc=Yi2Ss`T11 zT3+=rS(dT92~J{BLpaz+dx9`5S!LtOtC$jnzkA*)%>>*Ev^_?EsVdxdZl2j(0Z z7`}1CB9Lj^??;&2e4=*f{jgmD4#W4b)Jlsf{07$MtiHc-RAx(kyJ2?~vuyT#M1Cgw z$Bm{P6!M}A=W*UQG9~iIEPYpRNl_UrB*ER*J94~eK_>44J;0#K9pNe!+I5CwEHbeP{?p09W`gAcS1 z{)F~7-iD|!$ULiy^=^y2Rt9R=9hI^3?Vhn`F9xv_k9-JP0Bkki+Jg<{Xv~%;uqM&$ zIhSW6Iy=*^wos^pf-3wu$asS8dnt+F{QWjIah~7nGws~Xn);Kx4Z#Hc%F14@fD=G|tm6AYaOM(9L%;Fgk_fo= zt!#8GJtNT}rQ0{;0@H&DSDn|HN2N7IL^f#1(X{Az;QXRaHgJ5cirbT$@6VF#dNzEF z_ET{*=GC@$UE5cisEexj9E&)DQ#u77FN3@1ozNxB_@F$Z&%naxpC z4{1m5T#RoWp^75CIYq%0-yKJ+U&sDMi|^>VdeNP{GIB9|o)Qw6@)v0mZEcieWIU$E zTl`5WwW#nn_gVjC7A!WnfJ1vMcJbCnSbWjD&|t*|0wL=-GJTXe`&qnw5luS}IAT8HYhLkug#ymvMC0+i zkxC;R(jlF6M=Hh+r;QFUrb9(uxbuTV+Xe)nJ--g^ePxnb%w#BSxUhU}g{IwV;sNK<1ibU)6FpHOm7HR( z60R_#m}6kKJ>cDA212^DP-TY{?q~e@1&M$ z;7mINRyDpxOM5*$h^T2`6jxSSeT!ilD*XyUo+&4=j(bSBhJPnFn3R9wtA6LYF4g*Z z^NU7DEe1rkMb>*SWG6p@jmU;m3Qx|XGPc7YEX6&iz%LZJk`kZ#vaIT>BoI@KfdHfP zp6=OngX$>d$xqWUCZ+&E#6y|h;8NDpbESa$s{71#V!WQ$-Lq~z%VFu6a+`A+XI^yO zBSn7W@JvjI@bvvNCMbA#ns?{ny#_Nr@_PDVpK7on7qI8pL1QvDA_QskMitZYb~U`+ zJMKh-JHHI49oYAF*c8W7g?Ysj3x~H{e$aHeb2vo|t&N zs{j9h_W!>wAv_O@p{^}RN<*4hLOVg%onQ}odJlLD07JSM-!9!oJa~ym_FeK8P7$2H zK_DUx6KSHlmexZygYqKh^B~zrUknaIrbysNO@IT4ySuv^;*vOL=hm$N8Dlp#4C(3V z4Hw|-X9C8~6J&yxCXQyBh`5PM(x!~F zoZV^M)jParV=afvl&PMc9smMnn=Ph`D=H2-Q#ENf}Q%bRkdrcG0=Nw9rSqqaTIQ$4v$SF>z@_ z!&PdkY!t`zch1q~&TnTY3dA=rX3_s=F_fNsIKm0RwmkaqfYBA(>2*Y4D@~i1GkL({ z(+8nGe{Y;#zHJFldJ*H6$$Hm932CpzG@;fno#4e|;$;^EXKDr%ULBp&il#ZC2VMR= zi`jf34GoPr-)}C(&Zw9m6Px5AD?%qLdS73)6>iRSZ|_E`5aWMO>x3QrAEDWJ8sSgV zuUa>A55h~+4CbPmN12yNG3rrRB~?hwrayZeQX(SYUS3}b;>;Vl&^v@bG+)PuxMb{N ztNuf8Vybp2-LTu&=y`$(R{MNg(xRq0 zMgOWu`3&6KKKak3&G2wG57Hc^dJ5l-jf{|pqNq{XBf>#NB#$jq5}!(X$)wGxss%}q zoaO9oV^e0b7z@4>mzPIm=$YC%5W?LU>=RPwc-*U#E)blY!rY)sMN902VN!sA;}*?F z9SP+mf&O2IG-yKWXTL{S&kH0Qvu0ByPbE!dnz>M~{LqDmvp^d`(S2R`oj@%Km5$my zxY}r1{J0^1HZP6N7ie?Jty|ZTt?$SJ<-s41lW2PAvXUO2HtkXj2M^zVzoZ9IDw=>n zF$Jt^uiPS?^k6HrMb7bk7c*Df=LZ9#f^0KdM0;`E+4JeSWZGgT0#e`00EqV)92_hT zX9H>{_Py*axVX4@dj!Ut19Y@LjBUWZG-5lt3X;kABo%i*7T1kxNb(T#Z4(;W zHk4-?ytam+^H&MTlf3Ug*+ydB*<_|qN1PA31)LMzeJlqiIoK4R$}bzEpw8d6)F-XB zAPb~@>Wh;SRaGHIbIHpy%g$*OFbtCJg*9LyTjna6rzPUHgZQpTrI&h9SmprScKwSL zc%@I#5+O@VT7-iD`T-^Gi=&;g@@|yT=9QHou?3g@BU7c|^uA9`z=;blHi9mwyN8D+ z$4y}$A0L^-xViVg^+{e2d=U;E(RVZ=k~h&bPz}YZR+mtNeXJ<#Stt=hEtzno4ClO= zfE?dVTUB1X>RIi|p6~sdtlrutbxaS1^hkVI|KM+Sql?G=_8nI}0yIG-UEt?~FBTe4 z__BLf?}v$2l`LOBj!GmxUbOF;)S85ZwjOsYtNP`r8=CN-1u<1XEK}x9(uP z>gXau&|n%Huc`=8%ak@;OF?Tk{uqhY;mu9+1;0+o!Bgxv&8vY& z`-io(z;E*CAf1CfTgezoSCmoLKe(NlfP5p3X<~a=?ZhPPRiNTG(_0tYTzB~x9iLVD zwPwp*0kEG6HeBEb@~E|qrtOjt<3DLX8VV^@9fiWl7@#m^qGIGAPI@ zg=y~0LP})kKkzrf^+GR!vAl46E@1|6RHE>MgM((x0H5Ax#i=@GyH+CK@nk<5efqS- zTMZ;MLTxjxU&9Y+&_A9h8!cq@V>wdX%DTn49a4_M;=wrPW(A3SEt?d0Easz3mjm4H z{5dC$OsERqTaLY8_(_Am-_>hSetZ_bL-3+;2-hBLYP8S!>xz8U!KwSY2vyotU$=Ez zf{E7BD^w+tTymZRmh)JYvIB{+Fb;58G7poz(*o<}KW03Oy!`8#gQ|-)m?%8A!NtEt z5&|ANRjX(DE!rW0wn_iTbz@ zBs~5T?a>P3!c8N8Zt%fqfi(D};@ba#qtY@joFlFHZjfvQ2d(+gF>nwGrm*s;FC1Es z^eQj>8kl1|8(Mj5m}uB?mbstahO3@LDOKO_Jc?WUD6Tl(9k=3WX$h*}n`^Kz{r8#@ zOpGQZ$xKw*5D;~fjQTVCDX|%H#q3wV$+bmT7gZslp}Is`udNnfTb~5iaT|mW1f?we zOxbF;#ot(tvBx*_xCqM=u=c%?O;tg#BNE8+x|d}_X2_C2ocgZUOk7sH^JlFRgQn0` zNbnssHrt$K@pY%{?nbyT!~=N_aq7g(xgT%!_p`v$X$QWQF!Fky*$1F?5Dk^u3*IY3 ze1D=@Zlq_H5LY-u?whIe))&h_6SG|{RJ&w#<)rHIkb(z;g?OWi;8e8(i2dF2D9L9eu)rC9$<~$K zsGf=p(F!Dz`vO&6bMcMa=x0`7N^Yfw$H!fPIfKEyCeaAp!9Bwc^uy&G)@JTg5o0x= zn(>D(4UnBnAxC1QbnLQ_Cz%Ys)H?DZsA?~zIMW_eg;UHhujTe;(YO6USFWx*-Ax`j zW-+VYqj|M))e2r+pSj^z#u^_?L+f;?%TC^OhC{t_F9wme5ZdZ+T^X&7e)Zjydt zc}v(fuWKu{JGpIEE!wD;g3Y1papgUu<}*L!Ec?);$waPCeNuGHV(2gsKip}MRcZ7b z$yrx6cD}NXX1l5$@JGKZ?%|#ZTf6l~f?Y}b?K`n>;FL&Xa7cCO%Il8Fi|eJyHAr3m zsh1u-VC9>NIoqi{)*4KGjRtOqvlS9kcU9w>BsA{Qi}i(4@(e&9pb=zGcBCed+1wG6 zg}#=^CKy-pEAFB`Anl0)9@k&vGc+*{j!q+f`vqxk3)l0~H_c%=N>(^{(PdS6IYa*& z)zHvT!MCfy{{q54E;qXE{{4=A>^c;x#99j{FXx_YT4}aKH>}SfS!U_eeBdC|dP|xS znJw;lv-mdu#!Ik>^a-i)&o>Xd9OS;aa$Vg4@b~S9FE+D;r538F=>9{cG(Vg_JgGgX ztRz(t;6AtM19sM}zwx1x@ee2P-kS?|>@d4f$bQhB^<6qAbD{O}?#6AtWoyuf*PZU= zZ^{T1{%+YPbBT#@PQwnhPl=YACq^SKkxlwvpsc!DdObt&KPYzt;;Sz7VoB3f-g3YA ztY=*44>#DTS;`(CBqjWX->dB=xT60150<>?*p=0nFTZL7rCmdMKk36(ymK2$YT{^3 zp){6~kA))-PSxCOyU=>A)8m9YFdJ!2NyZ`}db#EQV;e~KZyd}YRaF&TJ`|qaXzk4# zctkkryg0m295#2KFM7S56MKy{s>%!; z{q{7Ks5rmmSZ#W=)d77V1=Z{K>v8jSBtc^ERn^sd#ltvV4i5N<;=`v}5Qz0F(_kn( zR-TrH#dP-qfe46B)--V+P+g4~J8b3P5E0?i#h`r#hOTQ;JJZOvn>55$6ur`=$^g&h9>+&irI>D1|dh@)m@&+D*CT5rXQ=d2fm873< zg>PBRq!;HUo*3TU28<;_V#+_fULg?k||lfrvD(aI-BumDa^w85JsCC#Fr{pV+c z=O?DTKuoCNwEf)G%Tc!01byysoBhr>tw7ToA$k5hB`ICKEbYD0o{v707zfV)%#q>_ zD1t%$oi>Pr6~1{ns&1$>ULhmB}pn~YGnxSBq>FWaD?mO2BUH#6qL%k zLtMWo>A$Z054!-P@*cA=X;3S%CjpKmd6t3+K)P-$oY#*i+;(g~gf;=27B~D5{rXS3$XtQ1P|{?b`O$P>ZeJ&FhXS=YcaG4GS3&a6 zl#_3dUp7TJIVA*1rB$)JCNnrrvntqpeAyx*8$(4?Lq1JerA7ipBm?P@WFW9B2cjs| z1{GUOu*y0`CI)OmzKV9!LldNHHz}8L&1X<`4Iz^bRQzg@_CzR`Gc?%UMD_#CG?rT# zIK0u6s3&qlG;fBrg+UXSengh0yDPR@--6Soi(x~pwpo3g*?`7QN!i;EMdx>Arl~&S z`WnqgnTMOb82Wm8L}-zrEP>CH`tE-~} zWYmY9bCJ&0rw9Koqm{J-O~z<$mR;y=20f7HzYa)6P~57<*hc?;rUUS+dOF!jLetb7 z@+SIkeF@um8WHdD)Y95vrWfP$x+(mY;k6ubw5O@mY_8!*Ta@5$9po(y)w`ZVhe5QEVSNpPpW&jUw3x5=ysmJ+&C6hzyD+3Bhl7_$3Nj=)@NRFfdjH$n zd`hXv#%H+LKNwSBnsEII#nm&1+#cHCB9W4IVvPb0e*cyeMlJuRFGqntH)6m=$68K! zN;6Bv>XLi|ajDOeEu)&wq|qArCS5IW(-zCM{0s~e_zpn2T(+sV*0so&qdZzILZdSD zzez?@&KpFZQwu=SbE;F5o0_y%nT923*pa&p28Ni+Cj38#j#!u8I%BeeLjWr6y5w8a ztaq)W-cO!JMIPIeW+$3mP`+f5()E$9B8sd3FwAXfI`+h(D6$?&!xzesaB6U3@cy;M z4xl9HPjK{l!4q1~bYD3m{=BeLKmD&DKSZ`#h5FILUF=`l2(zjx8sXpL zKPh@*Y`jWp^|*fS7MS!pJ1tTFdpaAs?2o7QemjKwgu=?pJ67AeA;+GzS5=X}19`HK zzD0Ayar{({fqF|ripVR0n129StjgBvSm>rN$vp7w$9Z-(Aw2^FO;ejCOtdW<4g@1y z>%6njw$xPB>xCX~#9|T}RI0f4Rii7~t!3 z@dF)Nb4Es_^l$Z1UJo$*JYbBx13n)Wp22c6qa~cW@lWS@Zj7&57Cp#uQ^}SdP zlBKl#$;#MNuah~$*}Q9@&la6GvGU;4ZIvx`olTD$*nu$3*FA!eU%8CAjHmAe9aH?1 zTd_DI+MJ}rF3NfztrMXPqXI;bgf9e1sO$TlxA^T~6%rX5%)XE#jgDd zqBc+YM+vpKE&1M0$4NYb8ONP=Hzih@XZauO8iYJ(&)?02w~ z@ibxpqVB+7Tq2lHc;1O+xp4$PI6`6-*LjzIk(T-17R9lgwZmlI*v<9mP|fv;PbG;v zSt8)dOGpF@z7_mV3Ork#T<~`FdO5aiJ6f%1zZyV>K8m})dY!R+dVAvv6X$5NH{$T0 z7I+$M#|!!7id@r({_p;E5d9;JK9Jl<@BKpEyQX4Y+F@g8xAVpOh~qGYn-SUBDb+V!c8csoy z+_X$g!>lNug8Rsw-$AwL&X*gCZwE2TJD$Ye^AlATW@cd!mcqou1T8ajc@=|P@Z%Av zHcI_4P9|>SuAC=Hfg1X0?NE3WLX@CslUU3F@5JKw+-pts2>)JCd&4tun|hqe6Uf+H zbH=lt9QY*smXz4QkVI{Iki;?Zlq9rAn{A3*0)}7_bcG>F>vM%Mc>C$Sy-~d2^_Ees->W z6V7npq-6j}eBb_WXO+0?E_+@bUYg)OmruWnynT6T=7V#E3t(hVmy%e&+6Rd&RBm zc7iMD^ke1`UYwx-`9A-VWOnGbWFZr*Cxty;%A>WEF!?h--#<2naDRUfb++1UX@bl- z?R_v?abU@V5qPKipKyjM0FJ(jWJDtqBCa(+tznkD#6BE)0V_1`PXeY(uqG$aH$Hi7eJww`+wv#C&j_#l4}N`MW2lwC|t2vIm4muKUJz|FHhj ze)DEz8S0eO^z;cW`igl1juETzZb7T zI!*u+`~G`58Wb@dzZ6zt&k%0m5k%{G>{F`yxK1f`rCxq_N3N+0%*-|Z)X+^c(h}&E zl%$c6lp5@Mmo##!a!e$9vkvcZ6MN6}c0Y{9{82D^gs-Hul@~`AeLlYLwe#&cPYD%$T8P2&Wz$>p*Y*6Kf`vugKcvTy?lXIPi_e_U>n*7-kE>tc33f&Lmz zUk<_OdxLoTLO$$LXN3bfCLLa2d|&vLCjEPHmCp&b-W)|H2)a_`Cugx3f9YD=I)%&R=Y{&XE1C{p|A#lAz3 zk}s1D-+JHF?hj*^Q?$3u19zUVXL&&7iks7ElFL(*Y4ov(lnh9*qK`DrCusJi1XlbP zn>S;pjR}E-Sb)KZ`03*fwQ*9VikLhPN1>C2#vDJRudXlfd4To@2MOnQ6}o`E7KA-1 zuVQzo#QLP50}EQB3a)wOC2r?RemaiP1mO5)NG2O2+%5s>zYTeA0#mKVoGfV9UnO>z zG6|c#oCAS^8>5cgsLuP0BIVW#WU~ug*wdb5HH45|cU#Jx^UY$OiK_c8@l8}&8T~NN zleBfsC3Z?bYtKarb8(jwv4loST|4zv*jsow zn1jOm=Sn_=<3^Yh;;8Fymi7>%-C$i@GP0U8kt z{9=idHx2TWELBV+J9`!w1jg!4OHT>To#b#fcU4%RHY3-tDRT7ApHsTe=c=VI;a=@Z zdo1F6+zc*j&ykMbfbgV7PO1|!MWv^<_!eM@F(yUBjViuviD_!;XMM?kI@1-*$J&I_ z&u!x<9zH6|Fx-JK)ee{R9ET5YA+$dBdCBaDh#V&1x)s}+UH6Hlup>c$5e^?k_&Gun zo85-bzW3T)=-~UjdV?k&pE5~A1>x|7c0xz-XKJuxe_154f15{g{vLve@3W!Q!fsd3 zU)$f^0&<6A!35@{6(gf8!tMRT%ADv|)4g2Rk(MCd*O$oWzgSGWnp22WjY93jOm*%C zqx&xVqXSlkjMLKGIol!2z4@CTm%%GQXyh~uI!;TBLCuitSd+tuRYI~oqRxx$%jj-D zn^PvYQ4sCK@A(`O!987W?q0{h7_i^72S1#T(!G7b&kr5y%^lyLv-a=o>wW=x+~v4mz6?O9sA>IKB``E9-gQ7bdC643@(U z-%FC$9tc{Q^*i9e(kVW+Z(H3NXIU+UFWSF!y12*P2Ee;GL9${5h?vL5|LCZBJ#nth zkQ`aV62hG`{noX(?4*Otwx6FOmawigcN!MgnjfDj(g*9?WiyW(&5n~En7YiDY@h<3 zZ{B&i@@#SS+3Owyx=hr>J z7n8M9CLN8j9cv{dh!FKfTL7Y8u5ta8#bQK=CrxrZh0O^-nq!5AT~vpr#rBdze5$_M z{%UPLy5Vy5c^2Mgwq%813(TK?khP8bVF}uNHUjYlU+wP+QY+(7; z-YE)!m$qI1+tsNnM4DF($bp8@%bQz6>IRAch>E456sk&+VSJ~ z_|0p?Z)*)MT?1CN$@vA|bZC)JOQT~|s82Pecu*Cp0?tTRdsIMsc3@YSqhpMwlcShH zQGq$lw%;HX{LcU-%@*yweUf14oO$4ou54g;pGD*iZT`Z4&3o5zrC^B`UWlSvCnzNU z;#=-NrRd(UkrU+SM0sIx;G4UbJ5NV(LXYEJhwg_p+tJlknWp36W+4d3&V}pgw!=2pA$0Zi~q(3t%=E8kb-W$41A*gj<5|TqjE{tr!@@ zp?mi1cO8*yRO#!!9x;tnojl#Y`ACu+e}QY3g^Q=;MmpqV+)H7ovrya@{I*JoehyLy zumAbF`QnI`jt%`QOLb~=dD?g;m#@oGl8>j$9hYQ&t#Q)}-!O83hoxpG2OW5wGO9P) zTDTK66NOuHJOs2`07cFr8SpYtALiR{1L#qWE-at;XpmXZx~kg^G~M-Q{InC*?;&Yi zzdSdKC`M-8QQcYe-^75uikA*)Zp_&`mv~qB*gt6ez~iS^eM+X!u&@Oe-;DPvTzYM1 z+65PS!V{T%h0;DgBY!pI+O^Zto+=w6GGSN24sYR*_d4RhYuMYo5IMeOtVC(3Wfx}?7Mtap5U?_Xx6~>W0C?z5Z^K*VdT3Xg~3Uxj&O&s_eRX~^t@5o z*=08?F%r4#!OQAZQrgeqs7%4kBpm`a=VuxHX=eN#gzNe}lRqEDj0n(cHwkQv`oHV7 zb$IZhquW_ph{9$pF_Cn7RPhX%Ubf{2Er!-9B?PZ1Rir>X#sIfTYT$#pbLCHgMmUNA z!#u*?fz=l1^gr0S$u2S45C-C>7I$H#%`FSuX@9a;eo|_E)|})4SSTI3&>|z{24orbzdDB*QW!8!Nd{f>^%C@JIOu{>-Ut# z83o%4xsNPesgTqDJSHwOT;JJVdeNuLn?gm$uVciiNNHY3hjbuoSK1Ddv-$1h)3a}e z@`OnBqAY)2c}-1hObk*4#k84AH|HPXOv<_CWob^r;cX`sb@kBd>J^|6(92v>5>`@D z5=-+-%_2Gh9z{&-|z84Q+$#f09~#W*i+lA!xG`emJZMoG|lpk#B@qcXiJ4@Mb%V6viu#Ii(zK?FUCOUFKiHSE+nO- zm(P;$_wb7>0YI=L)+X@FxISFsMJWS+P%-TkLlu#Lur1+GGu^<2ctKp=%-6DXQFhy8 zAeWm0iiVp464#Y)j1E4xHK%T6Z6HH|CL#37TuYvwr_gwBofjmC@+^E3QkMFRgs(7~ zX{5nHhgGCakJ|CP>N{g16X8)$hKI1s6&58l|B7pMdmI^t0K=q23Pg!*xD>!eo+?@{m-l({BVL>rC+DRigLo*{!$ZHK9fE*6p(jXIl8M`xGs0 zL1p58SeN~@{>E<`YVD7`_T7L)Yw@|NhBBT(u)~q1R?dXw()2gncnEdQiI*CDL!q7p z*(a;*+(*{HC4u7;-~76bL#I~U#>4T~vp(axy z4d2wdZ@x72hTtvnT6Rhy!)6S3Z)Jo??{zHJD|ucJ1Fja-mb*=9Gc_)To2|s6w9y|$ z&Az7X<8*S5`w@VaUY|JV)r$6^(PHG!8n-b$GF<3X4i7pA*qB}N)S}xF&=Y@WLuSD_ zUg!c3aK*@FK-QP1Ti<%oo9hdHh(gtaqO&;0vfu{i zMFkB-#HEm!N-&*#=&s=!nR4`*BkN90qv!h@yUoTiH3okGLE+XmdvTO#2I8(K_)-BB znjjz~|1rR+XmLtd;LsK4&Y`73Obe+!*mdJq#SS+zc(_LVNKM%MXo zX~N}<$SXxn0gly}3Z^&HJ=h2?;vNRx4&Qx?o`+Gx#!+-t z)nJ9Mpy(?Mgny4UEN}AU>W0l}82fT&MX9^^2`F~EApqs%8A&H>yJLCcHUjUA^K>oQ z46^`tERjskATq{EEU*4^D#^`;a-Dx%Kl^tQ)z+QL*2C_+f!DoXtTrqDp1q?l(SIqS z_T%y#Cu@FYCU8xaH5xG*8C!RTZ~AgF8=+T+F*RflxBf*2Or#hnt~uXp%N#6Vdxvyc zeuQJ)JI4_viVyx~WRFlB+ojB&QQqF%?CKHu@^7}Oi1BC$2zmX-uk+iE;mciQ_3kh& z&v~zcQ8QCfqLzctOhliWjB2!j)K*eO~xodGmJ26z*PATU}F=YukXD$Tz1E z%NjH3%UU!HA|9mz>Y#D5!bl~7g2@mEZ)~U;Q|O0A802oLrsXA05T5`~tZZy96jd7% zqp|!{CVps5Z(nzah>V2PBb8TI#{}})uCHX)jQ>gYU>Ei@FI=ezExx&r?6gJ@ z@cw<@_aKx8omZz5P+qI9sbjcLk)%H7hGWSr#fqPcJ${>|gjs@U0peyBGh1ZSFc{WS z;AhC60;>dDxg*<*gzrxkX7cw36YA!W6&ry@;=HxD-12+wZG5mO{Eo*ruZtuznmb&W zC*_F7j|lTbb58UV7G$zZ)d$sZiqFr_{&j@+-I()Qazp+2hdVuJKpQi#HgM8-o1T{D z{C>X-5sCX0dz%|P-V)=dtlHDYOCrQANOeHSFE!!rOJb$H(@WuE(8(HRH`~ z%BTmHn}Cd&D+&!NQa4(ij>^dGYsB*fD5I&gJShExceWMnIsu1^eaR|h6&Ro9p6r3z zU^(nx`gu?%fpLXZZAtV#-Ss%HB`cREqT1`|#6P<~N>==Q6+6r#cd04hc|51;2Jd>l ztbVuqmU(CRz}}5tF=ir`R$wv1LKYON{)nM;jY4AXh5=w9V+>7=Y}R)*O|i zfsrWVqR&6`obSIHGvU|OS<>a8nRl(USqshQvy`60@snz*XNlS0b{-EyPnWIC+wI-r zl+D!FasAl@;aw}Z+p}bV!MFu+_+0MvCu_#6+)$N@P&0N}?woL%NSU4$`QhB#>$tWf z+cm!*y@arg+Hnbz%IZ69xo&>ws`(QIU*VE;7;Loz9M(pX%$irlJ6a9Lf%e>P4i$}G z$zD4>FR2ULuRHvn7N~tFWAqTeoL>IeWeHH?#_YdcxMh4klFs6@h3+UWt|81WC-FGV z!-}_$925nt+Uj+futTVGUV^0gAb}y}%gyO~M?;CMWl?@hw#+dXb7!{nr2T4h_by-e zUGhtaj;f)Ki7d*RxMgQuGYWy5qk#m87zF=DlW)*V!u7q@&4+4%pJnGo)2ssawO#F! z@>MK9&);wtXZhQ$I#a|R`fqV%oF0@*KQFnqUKikXrPZ9wju!R!{9Tb8b{Bj_-yFWY za~gf=Wd~L5I<>J*y&=`|)x&dSm^2C zefwXQl<~Q>wK%mOss>u(V_yRPvc(iTZR+&~m)mfn0&m|99q~}khGbBJM-?j; zOCR^A%_zP=sm;?y$Fmf3&WJC%cPa5WfWphG&8CSvs*C8WhaQYM-6g&Jv_;mFu#M|e zKGmmK@k_g_{senXHbpb%f5$9YRGQZ$rXocWcXh_YWmoHrT=GZXIj0OumGaV6RplJQGKz(nHFX^^I*d|Zohlw^$d6)|zDXWq> zr1dszirx>j01=okd_;&)wIxlo62)~3fMYg)8MitxK?ln$PX!_SBsGke< zuw)dTmWWWQ*-pO)iYgXwvC()?M}O8nb6SR8PD|U^jV5PxTP{1Y6QSKtL*9;T>2-3)HJpy$o<xb z2Hg!6lxuyXGpe=Iey3vs^OMW9GA6_x6laD>8zVP$NsXbrJChY=W2577-g4)-D)t-_ zZf0XsDYJUShb*r;c0ycu-(dKPX^UTm2&t^u}YgN|<$TXUe#p(VQmJrO2JN05| z(ui+vZcg)O#{__Tetr(I2NqMA{U=4p&iL@@kC0O}wCl_`$#2&1J7PkQA$>6q|C<>O zyBhXT5|_*=Ms=0(a|>CS=j3E6vwoDp`u87hBY#z>gX81tY{J%|-x5Bbrpwy({`)AE zQBZ=g{u_`UU0$+{OiG(zwFM=9`xyz76Z-4?F%3X5`owfN;$~L4(v3O$Am;K;H$avt zxwUE&cQ5Os}6#@_r9KWZ01HiOo{)1CwP@c!dt=_Gqiq*9BKvGzbUQ+@C3Fpbgt zcKf}>>*;)R=sw2zvrzOG!!z6M^P*=B3v5h7njVR`u+i~`&G0%ah_GoZtHuvKVq$1g z;1*4cyfK1YrbXSqmnTDLpOgCoWV*p@>>)Io!4y?V*ZUcp4f+5i&_UrUa|f=|8J%RE{X6mZ&K-Z%-5(Vrqr|$?F7PEd z7Nqv9Gf1^Jz{jar($N8_elX(td;#{TwPYpO&qJ-Ly2smv6oWM*j!_}-by>Bvz}Qwp zhnJeDAKYP0QzP;VNi@l_OI`d-I|$E=ffQ|h2U@56W0M%XS-w^~sqpeard#p$9x=M4(hAW9~1p2&n5g<;T@%*U{A)6sSQb8Pp(R+;(*Qp#O&q zx<-*k#QkI1hSm0NNGN8^ZyIVUU?QNAhpGHCieplRKO$sWmhp^nC>1ka$~v<(M#z3z zBE$f@Ar~;)6&yz+H(BjVP`wepnnC`>u0lVM2B(?mdX`C??K{i0i`Kg|J|W@2xkpJg zy~AUYc0%G_M5A5GTGa5%)4Q1|!NyhqPq{TjZNg_lLpyJSppJDjYpFb*C$GDl0-RW z)I%E75S%{YF%q@59%Abbt($~3{D=0)`s-Ud;I0B_q6?^QK1^O^Qvkh zq5dtwYAbv}(B}P`Omr}lua|kQ_r0hjDvY3l2PCWA5en~l*J#TcEUvz~A{;h~I2}5e z8XiMHM`*?hl1{pvQzWp&)tKX$>?1%6wKlF$8)8F4FHc4^(-Hip!RkF+1=`z{nzV5CS|TGCWk@3{HQ7bDfJ0|XuQf@qS+e>`p@!(IbLYax?5^NzBmI=V@6m55_PF7A`>ea2Sc ztU07DO`=AA(BbrmEl8!OCT%&*3PS2$s*@l=pLUy2?C$@olCzA9vg_JDAt5ac2;!g! zQj!AFAl)Dh;vglVfOL0vH#2ni5JQ(VNP~bw3?MBbNXY>2>3v_<`@SEZFVE-s%|6e) zX3ySh9eW*rH}UaS49g4e>;Nx>KMtH(Sm;7)72|1|vZ*0cgB0BCQ1ShX+%SD$*DM+* zxLvu}hRWssA1T;n&&p$l&#@M)r>-eY11Z(e(0QDaq8}N!h*aiG%QGI5 z{iqlGj@XLQ$XT^yDC0?+_8MscU2(qxV20wKJ{0N^C5)UztG#)B_G9owaKxJ>Qc4-w zA=HI@aAN=(^vEH#A0HvcE&y>MMG0p*2@DkBRt}4(C4@h1ILX>D+@n2 z_7z20dvbfyh9+k*}TKi*dwmd4YBXmDqcU);G4cx;Lz@fv-YQ1i8Qs!FL2npHM zxzxh>QOSOjL1$-k{lJS{neoE$ z^Xh@w>T12y6ClO4DwjgqM@A>8hg0d|!fmpYKGS@PoUh|QeS(@#Rkxa19;iOPEN|;LWN|5 z`K>M^67|ozb{OKniw~jRyOOtB;Y#`utCdgyO&^}>;?*3Z>xbWv;V&LQ5n0Ry$YvlC z6?+8TnjWL;Y>y)&CyGppAYU(1cuRaqz`MG>Gw0Y;IH?OU(u9rSg_($%P?$tOvamoy$X%bsfRy5mnU6}ofBQWV8LDq zKl=2A?$5e`XFiQ74FwL%xsbjlrHlqBo7N++3jUDQNf)Il_EW*e#CGkudjqx?)#i7R z+BzChLMlMDX`XzTny@VBPdS>83vJ#8`}BXKwQI)ocNgWPED>Z7f?e${@*rjUm8-4~ zl0lnIH|Y|0jR#%}S%>+C%XkPWSp;2)(HBHMV{Zie7`CD->A;W$rFf?&NgfRiqI7?8 z?&h&hwJ`dvKL=b@yKTShlx`uEvEGeq(Vp7UM=WzSPI`_-U%RKfIBz5NU$bA*EL3?# z$=aMJ1jlLM09ubGT*&%3P;jZRc;6!JPX=Ufn|c2tk>A$l1OkbuRAl_{MhC@YJ+M3C z91quIC#lX|@v?F()=M^{9iXofsz8IfK4b141T}9{f=|mFyN&>K$A(LVl!{WoRgu-% zEnLQ0G}&`xYH|t$^Em`3Tl2pYIE_KiXNzDen5z=aFv&&VVuqBP;?anx>XpOz6fLf) zxJUi09JeZ~2i7j)8t?TE5B|rZCre(SsHEc(`Q>!r49cJFnTo5Yv0J?vGQ>+{iDyL{ zo4{|&hqKaFmsvY8e3WyPE0Mja{E)L`0n(j6X&|WcaPv^_^S!bw()U8b6=-H{2Lc{Q zd#YW1FYscGvJVULAE@`g34@tCzB))iJI)^Izg5dy?f+IyO?vbQWyZ_7HuAmb65Chv zklJO1rsmO;LeGw!u*H4|(CCZ@WMmAjd#ImZ&?l$-E4XwAU16{eBnG!_cp))?4`;qL zc2l*fwPH1kpG0Op_@F^5{QfJhTE;tBj8Jf|&Ea>+Z?*dGXmS^h2CCdM3{3M1z1c}; zH4NSgW#%egq>|Mz0yg*L#=5^LaR0a_XLU~RmpUnJWN-O8C11Z03OxE!yO|ANCu*zOgP*jHN1iDLO>MeVBY(M!a;`wqqNyMJch zjHpaz+7v%;NlN{pMzD<2UUhE!^>_kTwrJtV+|`6QXi?lzcPlx~5^&8dxo^aXUZMa1 z$6G1raQ+kv1n%m}gb1{#Ep*0t5&11QTK7!6CJwV8ES$&j?Fhr)eaD(7GgK;;`>3pi zia3TjjLuZu6i<;?Qo+U1dYD!*oreJY9189v3)>Uix*}mFUzT4*DJN5LJO@>Z?7`#2 z|F8h}yd?<4d13YQ;Gs`8HiZdtfr=99MB)mci=)W(gif)Qfow}_t9LtR}W(8re)7>IRy_Wtgyu$nd4*ruodDxhfA^U<&UD-Jo3Y~B)VRd^^5>aFSg z>>pQZb%V8<&Mdsps{J={rwo$_)@vpaDPSIececEudOd3u&E(_bv+Yp7b3Sbl!$tqg|Z=m9OFRk8xI==|`5+IY90^V2Z8huhld>#*|)w`fRM0zG*Lf+s6 zRhsp$tJ7WR2mdV`0R{dJ|I@Sk^h_%e1ONG>D3SyCo!~$hpu_W!nG#5CR{!}xe&GKh zlT-*UR=l|U&>K&fTdAeO9hiV$>d~$e1;ydG$Wb4k>bGhLAb~%Sie>;dN}vZaLGU?3 zCdu3Fvw&g#uo+#O?~NzIZh3@QV9DPWS(4{06`thqZ!r24qT4v87>|~xzqlECc^svt zn(5|e7XRuY^^JeSA|o$9Xw6ncwl4Gk&+72D2VZOv-TGY2AP5ha0SE#3$Q@4ty+*p& z;Uz#xNm)`5E)`DU{I3m|N6vH!Vgy>hfCT+ECmw+br%{H)dZK|&bp3XB9+EI@Sq(KU z)(|r0b(xKS)&daes6Zn-quC+spa+~U2;eL`Vq0F&@g!uIBEEwsROLT0_5|ty1xQwI z*L|u^!iFSdtxMfo&~G}x^xK!g2veI`URL$+5Tc8-%#Y%&{>R`e6WP!^X~)fr2l#KX zkhnSpFXqMzurG`kgxHoF-@OII8AH669Uvj)B9FJ>icA1fM}cw3qCSjCE)}y}ZD7RS zZ6fEmgwTq6YkFZJ9MIQ~=J<$JXP8QVOW`XUTAh;Fl@4u)c~yksG1q z5sK%;{rU4JqBF*U-r;W^!2wfy4LU2kz z-q`WUSTZZ-)}M!3n?i80D7BIVnb?B^2RZVV4PoDbXqtEKYax~IyNuY>c{Z&x2eLc7 zE|o8i+@HBh&}j9((f&SW_g$02YR6rbc6l5{XD79I`*8NQ3PefyfFz8$^->;a?Jvd# z_7-E#xghKqb}9@Z9qC3}6(SoIDm=Y6o7ID5!uBN;OKZMRo$?->{xo&_;W!({gpFM= zL!lE@l@F`#1V?VS+ixCifRp4dI*z_NRR>m#U?bmL{?q;3XT-%X?tRDTgvvoi)N?<+ zGAen}(VprrZDN&1p;eXJ-tL_rA^%M*nI1OE?70h-y|CX(r)25Qx&6)j7p(=`Tfgt{ zR%YFhn!uc8L?!~M_|m+VGDO$yo^2^1VT{Kj;gEZhJD3s_JMh)~IWT>~zl)>Vi#y+z zMV4S8-f>5pnMfGz>5K8oxQxI!sA@9Bwl^Y5ZuMsb#|4izsMYE~IbqzO8O%m$GVjn) zQ&14Jx3{PDPMBV;3ecb2+yt(%Xh5`?L7a~$UPYG0&)L>RlT;!&fK+3cg{pZ?b?rjM zrYBAkIPx9>M;;@?SkfW&xg^D?us7bAoJKPI-hG_MOy-S5%e!hHJBSDUz@r$lw4Wj# znIUU8)a=8$DT5Y)QSv|XySuKr`YxryH(Iw-ckuu& z_hzz|$NHBANnegFHUSF(&0M~?1(}mxLUi#{d#s0bRp`4pJ-rRUhssF7!i@n`J_1qnu7CGY}@6hXme*BjcO=~r>cg(cgWrwKGE_xuWLIq z#yVPm1-tb02V!U(Tf$Z&|G`^g#Ih&Kg_p4HFf>LYEITdtRLH88IDexlO(S5Ur~Tud zgI>0jicYA>pqUu{!)3U8Rytsj8i+wYPl|v^j%F>OVp9eob`C$1+ zXB11!c=dg=#{0Hjf>pTL#qzhZtc&Jhd9FY!h5G4Dttpe= z!L69l*n~*=%H1Aer#nOR&rv<-$~yX!kKx*;L^QZ=t}QlWoMee|^eM~OvJ|uwXhR3O zXF1cNwAp0+{3LkCWPiFGKFyPda|6D4b{s>vgFcDlM-n_?A!N6viV`#=Sr!!8b{H~J z@6L82*hY?Ycbf~t7bYNSSwW$mE-x>GC|+NP*t4;@z8db1a?_+<4Y06;J9!;@66Sfc z&Q@o{PsoOsDFJG%mCmK;*5$*gOdAV9k?@cZJ%_|uN09Y%qDMEzNI~`}XmyM@1gjV) zQ|Y@3nW_uCPmEM=>KTSE6*NjqOzM4C6L**W4`{{HDNj3M=UolksPmODdz{fmV@zEPl`c-M^

05PG^I<3Z_IyD7~ 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 LnoPBnap3;}knI^v literal 0 HcmV?d00001 diff --git a/tests/_images/embedding-missing-values/test_missing_values_categorical[pca-na_color.default-na_in_legend.True-legend.on_bottom-groups.3]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_categorical[pca-na_color.default-na_in_legend.True-legend.on_bottom-groups.3]/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..4b943bcd27462b662fc7b8b69ccaf27a07a74392 GIT binary patch literal 19216 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 literal 0 HcmV?d00001 diff --git a/tests/_images/embedding-missing-values/test_missing_values_categorical[pca-na_color.default-na_in_legend.True-legend.on_bottom-groups.all]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_categorical[pca-na_color.default-na_in_legend.True-legend.on_bottom-groups.all]/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..ce64b590542a4632f085b7209eaf00739ada850a GIT binary patch literal 24135 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 literal 0 HcmV?d00001 diff --git a/tests/_images/embedding-missing-values/test_missing_values_categorical[spatial-na_color.black_tup-na_in_legend.False-legend.on_bottom-groups.3]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_categorical[spatial-na_color.black_tup-na_in_legend.False-legend.on_bottom-groups.3]/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..dc315339482812c0d045667dd38e3a70a1509b56 GIT binary patch literal 37955 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 literal 0 HcmV?d00001 diff --git a/tests/_images/embedding-missing-values/test_missing_values_categorical[spatial-na_color.black_tup-na_in_legend.True-legend.on_bottom-groups.3]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_categorical[spatial-na_color.black_tup-na_in_legend.True-legend.on_bottom-groups.3]/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..75485fcf1e7b01df7f12ae9f928091454b0062a8 GIT binary patch literal 37843 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 F1OVI{ujl{( literal 0 HcmV?d00001 diff --git a/tests/_images/embedding-missing-values/test_missing_values_categorical[spatial-na_color.black_tup-na_in_legend.True-legend.on_bottom-groups.all]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_categorical[spatial-na_color.black_tup-na_in_legend.True-legend.on_bottom-groups.all]/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..26af76bb5a7699a4801d7940e9a560408874f3c1 GIT binary patch literal 40000 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 P$2iH-6n?E9>Yn@`W2kbw literal 0 HcmV?d00001 diff --git a/tests/_images/embedding-missing-values/test_missing_values_categorical[spatial-na_color.default-na_in_legend.True-legend.on_bottom-groups.3]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_categorical[spatial-na_color.default-na_in_legend.True-legend.on_bottom-groups.3]/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..ebe3016322a0a790216f1127a00c420006c43459 GIT binary patch literal 21340 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 literal 0 HcmV?d00001 diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.black_tup-legend.on_data-vbounds.default]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.black_tup-legend.on_data-vbounds.default]/expected.png deleted file mode 100644 index 4a15aff0879620139638441bae4fc086107e9d02..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25472 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 diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.black_tup-legend.on_data-vbounds.norm]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.black_tup-legend.on_data-vbounds.norm]/expected.png deleted file mode 100644 index 79701cba60ac06f8712a51e749e052b1d90bb396..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23781 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 diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.black_tup-legend.on_right-vbounds.norm]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.black_tup-legend.on_right-vbounds.norm]/expected.png deleted file mode 100644 index 79701cba60ac06f8712a51e749e052b1d90bb396..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23781 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 e|G#|LIj|I@+$A?R^#!zkGa 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 diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.default-legend.on_data-vbounds.norm]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.default-legend.on_data-vbounds.norm]/expected.png deleted file mode 100644 index 8de704a9080dcbb6e14ea8c64edf4a4f4b8ab23f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23194 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

@!XFqnTrkG@pP|1ZoJg%l_1c*O;GEwN@0eOWT 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 diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.default-legend.on_data-vbounds.vcenter]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.default-legend.on_data-vbounds.vcenter]/expected.png deleted file mode 100644 index 4705e7ff2e7d2ef29cd4a4a4d319071df252416d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23970 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 diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.default-legend.on_right-vbounds.norm]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.default-legend.on_right-vbounds.norm]/expected.png deleted file mode 100644 index 8de704a9080dcbb6e14ea8c64edf4a4f4b8ab23f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23194 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

@!XFqnTrkG@pP|1ZoJg%l_1c*O;GEwN@0eOWT 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 diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.default-legend.on_right-vbounds.vcenter]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[pca-na_color.default-legend.on_right-vbounds.vcenter]/expected.png deleted file mode 100644 index 4705e7ff2e7d2ef29cd4a4a4d319071df252416d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23970 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

dCK|&<`+r#Okq$Idw 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 AegFUf diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.on_data-vbounds.numbers]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.on_data-vbounds.numbers]/expected.png deleted file mode 100644 index 9f09b085b41e82865d76e598b2146703aef0e3d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39676 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 t@O(5;wP$eW@u;>wUFhwEeJ!=DYzgKm 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 AMF0Q* diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.on_data-vbounds.percentile]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.on_data-vbounds.percentile]/expected.png deleted file mode 100644 index fdef79fbfcf17b0ae2e884b9124ba8efa361df66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40601 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 Y(uzQ*5;R3GTt&-61%^-66QUySu*RoO9)O|AG5q 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 X*d@_!vzSu^2Kc}pt1Fhtn}+-gntN*G diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.on_right-vbounds.default]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.on_right-vbounds.default]/expected.png deleted file mode 100644 index 7cf84b81c956c8fae8751d42b28509ddc3133856..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40161 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

dCK|&<`+r#Okq$Idw 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 AegFUf diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.on_right-vbounds.numbers]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.on_right-vbounds.numbers]/expected.png deleted file mode 100644 index 9f09b085b41e82865d76e598b2146703aef0e3d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39676 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 t@O(5;wP$eW@u;>wUFhwEeJ!=DYzgKm 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 AMF0Q* diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.on_right-vbounds.percentile]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.on_right-vbounds.percentile]/expected.png deleted file mode 100644 index fdef79fbfcf17b0ae2e884b9124ba8efa361df66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40601 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 Y(uzQ*5;R3GTt&-61%^-66QUySu*RoO9)O|AG5q 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 X*d@_!vzSu^2Kc}pt1Fhtn}+-gntN*G diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.off-vbounds.default]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-vbounds.default]/expected.png similarity index 100% rename from tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.off-vbounds.default]/expected.png rename to tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-vbounds.default]/expected.png diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.off-vbounds.norm]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-vbounds.norm]/expected.png similarity index 100% rename from tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.off-vbounds.norm]/expected.png rename to tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-vbounds.norm]/expected.png diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.off-vbounds.numbers]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-vbounds.numbers]/expected.png similarity index 100% rename from tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.off-vbounds.numbers]/expected.png rename to tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-vbounds.numbers]/expected.png diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.off-vbounds.percentile]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-vbounds.percentile]/expected.png similarity index 100% rename from tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.off-vbounds.percentile]/expected.png rename to tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-vbounds.percentile]/expected.png diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.off-vbounds.vcenter]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-vbounds.vcenter]/expected.png similarity index 100% rename from tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-legend.off-vbounds.vcenter]/expected.png rename to tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.black_tup-vbounds.vcenter]/expected.png diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_data-vbounds.default]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_data-vbounds.default]/expected.png deleted file mode 100644 index d308779f926ced410b3458f2af8d6a36e0cb2710..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36158 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 diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_data-vbounds.norm]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_data-vbounds.norm]/expected.png deleted file mode 100644 index 3696ba3d28c8381876a1181a12fd6d8502194a7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35595 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 YWDu8!6XHMlN63K7$IIWd5{k(B8 diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_data-vbounds.numbers]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_data-vbounds.numbers]/expected.png deleted file mode 100644 index 96352358d166003b205a3c34ce91b884d150b3d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35595 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®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 WygU*g_t7s*23+2rejZg&SjInO!x3iy diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_data-vbounds.percentile]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_data-vbounds.percentile]/expected.png deleted file mode 100644 index 96384f44bf564c1052e52fafd00f1eaf4a554efb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36544 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 Uxj&E?7489-y{)rNCB`S=KiR+nR{#J2 diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_data-vbounds.vcenter]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_data-vbounds.vcenter]/expected.png deleted file mode 100644 index c97398776db739b36421e3c06045ede896ed369c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36119 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

YYVb1x4y@#=O^O7UE6~p>CZhQ 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®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 WygU*g_t7s*23+2rejZg&SjInO!x3iy diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_right-vbounds.percentile]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_right-vbounds.percentile]/expected.png deleted file mode 100644 index 96384f44bf564c1052e52fafd00f1eaf4a554efb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36544 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 Uxj&E?7489-y{)rNCB`S=KiR+nR{#J2 diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_right-vbounds.vcenter]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_right-vbounds.vcenter]/expected.png deleted file mode 100644 index c97398776db739b36421e3c06045ede896ed369c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36119 zcmc$_gLfTK7dRR;wyhgCc4MnaZfrKTZ8U0Z+iDv-jcw=Me&6?dzxDotch{Ob zvu4gdvpxHqy?4YHB^eY%LPQ7%2ozbMq$&gilr;Fd7akV;zg<}s06y`7q_jb5jus$y zV`p;+MPtx6J4cY6wF#Mt!0hO3$%3vv*$$or z;TurL1p)$==HCISsJ=7;0TCS{D=DV#k$t-E>SJ*C_IR~ecY?V{ZN0+j>Q4Vf&WV)U zOd){$Wh#Tilz9_{dw7`JtkpIUis{Ru`g}2od&jwqpMNn^aVBD8!e2{jG6s=u;5@}@}G;OvBsBAiY7PV26uCizZ82u}w;rlrbEXt%KPE8e+ zzTuKI4zE`8i$(etK%iE-unFSA?j_eu2FOy5c{QtO>vyY4niWa_5 zq+YPhBUqIgsnXy8Pwf3;Rpj}gmuKeu+#%QdoUd?>RzpMM^}_!{VsVP*OVW|q@69Fd zJ998=7p#?dkQ?K=K)c}KMy#Xt<`ajfr+Wq8NlXUAFgpnj>gW(8Q7abK)SSa4PlIJ8%=cgHZr9(?h2QzH#n8j0 ziw@gk$>8%;>A=V)94p&pDek@emtAG1`M#$mrmSAKhi}w@tL?4~jy-SO{%o?XK(zJALnnpY@Y$VT;bNQd**{LF2K4+gs5co;Loj2d!| zuLi#*!YzNPrm6~N>1E3$pZfYB&;Naa`B-)cOavHG$#G;duIB=cgAObU2N}#&3#=!Z z$-z-G{;8weYAXINZ@hGcve(o{DM7XM=|mr@QqwQcvAoW2;&*+AL#q! z^x}UN6`~>H^CTfy4;sse@(Fx5vlL2ag#WK}8{!hiKsM~AFNgnBAC$R(F^m4($&;aw z=L=R1;{U2f`&>)pdX)oDh7!vEy}7Se^8bZ2&dVwT^8_co&KCs6{I()ex~Tj|e^`f?w_*t_^fkU=~`3TakK8&rcqdEX?P^rGddOUVJZN1G_x+k(6yCc>eET3 z`=v(H&Re=ZdF-~ZU0hZMZPc&~R8}6bXh;A8?)^TL{hzT63=H&LrnnR`*h8}%+9SNr z+rCRh;hwdib*w81l5D=Xy4cq!$Nn>HJ2?(to9mk!&%Fd0B@mm!%PjgFazpzYsO6x~ z9E@5t0Y}(LZBO@R-ul98YDUIbBo2ee!@Bz%=UIG_@{Gub&w2X^^Uf7-gT)m8{&m*< zKgWWBJW!<%b{JX=npH-=CtT6lMw>59KO*sWZ}LpROr`m0Ryu>JxBw3u>}?ww)JLXS ziBtL8Yj%c{i;H}M9Zm2OLhGw1)$T~#M`NV7E-P54Gr0cau8()Y&PD)C9)v4RL%G+vT-9+>gZ(--pPOX%^bnpfyOn7eBNA*R7IETK@mm&ujB^C_&>({UBLz8p` znwZQ?!XK5DkY7*|lF83}D~2r(nvI5=$9^qVV6M{4TdSDvf%pl8yc(BlY}kndx@Yuh zo-GeO$D-|%j<$p+z%yoOfxkC*@&L^3&5!q%3m1@pLPfGqtTyFNN(8ftE%7PS7K zh{f2Sq7vhNIE*;tM3d3dJaeM{_&@%*G?+CSTiQ-o#T91#EYA2r0|Uj4LfW*|4ndVX z&_IrQP$FCthpQx>I>2f!Vu&fE3yQn|LN72%Qkq!y0tOk<`BXyrw&JdU^1i}k5u*a^ zFAo>zzhkLo_*AEP%n3Cc_FL7NaGfGEQ`Qp9JG31w*#fkv`% zv->W)py4?zb|+af3W4~uW$hbc$@#^t>1PU*E0kpKX~DU&rab7O=A+AhK6XXM_fpE4 zQO(N!9f{9AYx(G;FI82g80IurS0rH;!z`WolXapb=8s?nu_1ali7iuN52XBF$*W(Op?wh`^+i3n|pHX+6+k~qrG8IOu z7@8rOZ~(vSFqK!mf5CM`03_!b#Ttu)XyE}U&`@zR zp+7(XM16M*^-D+bHBDXD;7t6aymDr1*!z$hSTicha!r1ft5_Iztxw+0nXOE*B4@rT z=QmfG42;j1sxunNG!oF+peHk0wL`Rr4;7LRoAI9^j>SjMn2^hJ0F%h+%i}}r%EGzq z3KkstNHj(p5j-e~i|sv0jmKJm>Vkm<6*SMufkG3o;ogS){g48jXe5H^J@0q5oZQ?b z&O5^3kGKgwY~UemJK?+hO=KSW(k(zh;w+pzM=1-X5c3BPBOwq!L=x#LU7_Q5BnJgM zD^nn0QuqYjJPc$D^G*^Iym4q1Cyu3Mc=kTe7u@%#!+pbCPA3$&*t7BRap5-@QjaZ2 zYUSKX|Bn~L$){Xzuw|Dne5I|!Fue7xH<7i|GnB?y{n^NSh+m$hM`^-@Iy-kvWv4X@ zgW>+g*d;89T#@c{pva@SbS}HPXb4$-U3{|I*wIB)2kuGZiFd+xkZ3);hSxp<^h*hH z;MyOMyQc8iX@TgH$6IhvOIb+tz1E@UX+JAs$YjZ`IqA4!$&4R;V0L-U2~OgdJdpDZ z-(3$o4Q3sc!J#L-j5naspwu`&v7H?18r*JyR!f_nVmsy&q% z^mi(;(#@a_UQru8YH3frF=9_n%i~sV7BUq*c^@w}0&5-<^+Qt#2oI5SZEEqHGCzYhW zlwV{^t99l^Xm@eCJ!K&g)kl!eHV z9Cf;8C%*tsCxS2&L3=Oc1B5i&vI#%Nifus1Gdm`)9J-_H#}+POSpI7<7|j%x>I-}y z2ZzUF3sr8c|B2m7ITy+bJAQvBLk#i7aF(zCxuR?bL9ME%J@;%$?dVXl{5x`Xo2*Kk z*7@mM6J2qbbe+0cJmHyTKWf4=h=}qRL`89s2u-N1JZ$wYbg`zl5s>F^wF9Uu43d_K z#4UAbOg|@%zbUXU>-vj46#hC%7y_iYCx4B-wPY!`>5~!fs!Y$o;n}VeTF+jHK9YSN zYGx*1@!~J#mwQ>hxuyu&rclK*G!CO(RNZ;KQA0;_0~P89{*`dA-b74RFS|il0B=ik z5}HgYhp#t`u@SzEH=%4)z&5AV#$Qp=<*7#$0@i}4Q+pkFPx2r!9&x$ALXt4eGAxlI zjDsJT6cPgI^QWb&4*5X(u@%8g`9G8w9+_3!JUKs4=JJ-fvqm2*sllP6zKk!@g~%;$ zi0zfDEp{C7*jk4}-!U&+QD)Fpill@xdsRE4o-W>o8)OHKf|wiyK@x%odB^flm`Mgk z6KbL-`St58_3}}_qMLiRsMzO|Sdf?80B_d3Y>8C3RL&qM;q{hxSWWl#+BG7_sJcS0uhV&%qfxj)mg0flQ$nmT?I-eS&MbRBJUN4ARIFmk6(YvBVj!CQsRGC7?bt1^)NS~8MylAtC=hHljQ*EBWtB7w z%2i7$2jwj}*JB7jMOOoD8wokt8nxFft| zM2TKN&aEXUokonpgvKz!6er2biI~Y?sQj+C7<)-s!NlypE8Yc~;Z1_AyUq7cdQ~_u z=*X<-=u*&Jv%??nn{m7!L@o92Z)baGTU?iPF(LJeW^4jE$t%2g)wo!gvt zwlbQ4dZaG9uPOuCw$#_h!Sbz#3>?}|7F5tO`&ei+m+oN%+-)ILwRU?hn_ZY4BdcW! zVFd|R+A+A`RbGN59>94JTTDZGk*X6FuKC(?aE;lFGE1@$Lu(55wA-r+6F*F}p}+_p z_LFKjHoJ~VG%qSLSph?F{3zal)u=}(FFl3WRM6@dHgwvAqpTn6xkqF+7fB+8IC%M|!4o`;H|m^@0bgUG(n4j~{S+W$a_ zn+kM)wBwwC=#{142(7pMm#EBh6gEmk1J;87o0#H6)Lr-1B?#=lELBRCWmx{P!All?*m0WTO+;EXGNy}R9uoG zbxUN^KigRu#hw_-p(U0qXp@CKU$m%xrGH69L(u) z&@VxS60`G0AoP}#*nndRGc4OK<-_lRuB|IMk{l{ih6WF%JApFQ(UBqS5~?2!662e zQiyyGRH?Y)4lWD&>41(oB~JMvdNe_D5r%d22OaKS@PdpusGyLiOJ=j!>VjwP#89f% zzuLcp-R(nufo<0F!~jkgG1u3?0%)E6z5DVrWtgOgV_VQ-2^9Nkl;hyOvkH45Shk?r zzWKH=0In*+=>2hVyVTwq;D}hM-ZDEh;oTF|7bXwFYUaTt{1fUcG$<);huI z89Qi5C6bXcZbU%T3@;f z0wEEVohEUXMp=c9$zC|GeCl$#5Qq4XG{X>dB1~{R5Z}zQw0y(H_;?VVl+lIF50q}u zgh*nEiJTLw6hS^@tm#P5E7fB7i-ry{goL`;7g8_VLC}7S7*NE8xK#h?wp;Z<%J88eahiPWUePxaSo!m zdy4N^2vymL)X!65!xBJL>mTcbNht|;@Q|Rtl;ikUW*MG2b6L}Il#$17EMB8 zF@}i8LG!YtZC}PpqXb|?Z^2e$Ee=@=Bt;30qxo@U^U8FFA;9)qsaY$4nVx^-9&oO%MlX0t}Ip~F#Pz4{`DyH6o?qZevouU=iRqf}*@VpNi zA2DWzwO?T-4y8?B;_iUTMTxCd{HcM%uYL%VURd0epF_RNrUgb|>l_ZGeZF}yDDd}v zU~{Y47>=8H`xF5@#mds2`+secJ$G+xvwL{5jilM3!Kmr5b)7#Yiz(YzGsH6Y!Fj5Q zZbK(=B>w6XXyoRK=7vC!KTc}mruAOlQ}D?|_&`5(B+UNF>#?q#q;V6 zQr}-5*U{(8;8KNWV`wChHWV9m%+&L@XwCEV-{{;s71x*4-WR*G<6`E&ML#*h{KJ(z zpl^|*FdgH67FT+NM4=B(3LlWeBSzl&v@@9^(6UD|hkD~0s#IfuOK)FKZ7Z1z zqgkxTp8V)%w2WOc+t1?nFdnY=GOF`z;DZ5xp z&6XHbC}MK`L}}rvkC)Xmg%%b>N*5RRBx-70By9)QupZ`q-M2c^V-DLtJ~ouAYM!uU zWB;==td@C%W!$9q)c5gD`q6sBqCmVMCtn$ki;K@gJ^k9Uwst*47AGi@De(UOk^V8; zfh^R3thlgTR}o9};lus$zOnmy`CH&=WRY}x-Z6V*zeKNYUpL*$f&4BHC9kzL!NS-^BfDsIlOI z1KmN*$KG9B!oJ;9xXXXHQWLT<0CT9yZq<`UR*N1{Py+We8oly0( zF2ob1{;;e~-pW%$8ey$Z+Qro~EGV@r)6nUD;Sg`Nsp5>&bYhwL+g6v=rgqXxe{j#2 zTGOmT{7Mx{v>p=XM&9fZq34=;#$115)+mc&#zGR{VnKAADfr_W1<{nPI6m6<3)=7x z3c_hS^R*qQy^1?P%isCGvh&7HiFF(?xnon&Q*R>JCFqA|UoTfgHu`d-Rjy9Og++$@ zkmSXEdMpJ*UT)ByHnMuiy!Y~p+8s)F|v z<}H`XrA+o;~5NO_jz%m9xNdQy=FL& zX=N?vE^^KOe96Eo!*lM-y5oF7IgJcwU`dkCeI}?;xGcIAIMQDeCwZNq_ZM&a6m!1P>ov3MxOl-+bz*zcX}^QiI?Xg=v2LATyKx zW}Yj5UY^6tP9lzu{imxVLGi+#?5fXXeh8a1*Kkq_=gg;-dGa*St$DE8=lzP5&B$X8 zOyI0i%93ybIJdAs{ipOy7qm{^T(cqj-fBJgIv_jr zmWF0g!?~Xd+?y9YjUYmm6~CKqQ_NI^7RpQxv1_6`7bGxL7#X^;aWv z90!rTmI}uZXkQ+5i;AIT^eKouAyO~g19Tc=-3kXsYkP}68i8?kZPGN10r=vhS@@)~ zlpCl2C$MWyo`M7DHYf-DE!$e;k!f&Bm~5nA1W>f(9eeO|arFGY$rfYYvOe>uuid~k z?74o&34_djMnN~#yZLK~fu*z0+^`ez!707skLck7-NNTKXD{B=F@jHGqKs|$b>C2> zTMHg+YfR#E@^kK!wKVRJh~WRQnm7l4@1L{&OQFP>eZ zm9R5pq61$wPl|RiZr)xdQR6i-M&F6dKmrGG{ym87cH_Xg47;HF9g~|$R%X!XJ`2U} zP&Gr}%2-||5vpbSRmSk3>cU`ZcJg%BIrM+oI(}M1it#7`hMzrksY|$|s`@ng`brY= z+<6^Oon2?Ia7hVi(>R7b@rqHEbi^9bv=NP`cDtFjBk`%ew@t({a#T6x=Ts#t-+=TP zV*pofnj%VmjPHS5%vk6!Yhi&69igcjXbnSmBu~@mx^Rz}!T8mA~=7QA;%*r1uxjx>ht5 zxHPF=QjSqq*~agn`cuq=;@CeMKuZ8<4U_VJNgPz#Ou6f=_P^M_rey5Phc|4IETPb&K#{-6a8O5tJX10UHy_~&*~v9j9s zgu0*O3)E8BK+v+Wg)NH(WuH{Uty^-)Fl|UEu`OmW#@3J? zB%`~H6(%}7rapX_rSG7d`lGAF_*b=^nX=n*9T{`GG`ek13q{`5PWN@-9u-E-$ z(72MOJh~SxBQGi%zt)I!v=jp)D*-S>*ka{W#l%MtWdjaU9h(tZSHPHPp|pRN0rHQ6 z1`~>)bfy8sP7Ik4sA3XOK}(}Rg1xpkcrgZ4Jt!vYPby>*2w0JNR&0XBG-}~)IONQx zqx{RBM`pQf7?lT@fVLJ#6=lxxfy%V_hd;WX5mIIwkw51k@JG%Q{45QYw8X5{Aj^fK zB&3|1gB}_wt4;Wq_yT8J;mk0o!l+y7$O%jA>WO-WBJT#6>l-*zmE72A)F&SBy85*Y zhN}F^2uGTNoq+699~FDqGs@e_Qv$8t*V-f-I#X-eCdWZy*%vMBRv_{yL*1F*o0$_u zJs!cfJwkCqEVVQzH$|+-!8r*K2RJxa#}6A@`-P70~P0S6<9e$(&mOJ(IpWAivPsO!7S?qY!Fay&pX{| z1F?rNh)%6C2vtQXO7M$UIe*2Ab25bgGO+~8hTOw4baTc;hlsV;%$cQqyW=fqQP`1F~qQSBMs2`GuPz6-uys>;+;&!pY$eHF2oQ(MSJ`Sp`k| z1Wqy&cgPO`1Cz07r^0s~>*jT_i(1E|HQnN4&yjcPMHMg-pb=B}=&6{P+aupbr;b4F zFgq%6ZU$wn4N0fC0z$zZPIe4r>e%L@(^ia>uqLjCk$^Oac!gq*%Tzdm^bIjf?IBwn zr$%ac*J9cxndP}mBk|_Y<5+CyE<}TBHaDT3u-kwX1Q!|7n-cE-X5Wtjb_(Ea{cjtlU1YdJ<&x8B#v)TW_hW7LlovZEG_*oIPl=)koRU%$iP9+XSw*8SCm#l~c?3pD zSzhDYHZeR4Y695jWQrVq?!J>yPtQNDwp8o;Dbakq&c8(WXqrD2qB+Hrsl{E7FCehL zKg+`^WI_gvu!oDE@ZT0BeVYY#QpNJK2C1G&5)zEmFGOS~kzr%ZnNp0M(oXa9)Tsyo ziCiL5Lr1M$$=X#9ic5Kp#w(Yh_xv5*%MndFtpxnQ=cr56QV$sCqXfF(F8D5(X zHSB?eP>CnV@S{rD_9yqQhVI~q5XlfnouGZ9b9UoR7;(c|O_weNME|juNN@$k$u$m1 zd0U69jdS8JM$|DuTe`&?4aQJa%_f?DQQtM1I)qW<-v1&3kd@7f-M>{aE#9@6mL^<@ z?lOUhSSB|6>yv})&QT<|NGbc|J@YbA+cU`YM+vukd34DqBQ`#^hc^du1AkTI&}3Sa zq1HZ%%~G106jjdhHHfBL{njoX!_{szGM^~N*0b|mJf$DVW2gKxB*$7%7~ zf#%u^ZQX%kIZelt+7Ua=@M3rF;HLGk%8k2=mfgb>#rmS@ONj-?dk~D_W@pI#w+kx* zoyMf|_ORk1MYBV^3ZgyfN;%WTN9+hiC0+TQa$yXqx#jX=EZb2EwsyFYOuJ}VVp;+A zrDO-nWK7mV_M>2mWXC2oHnyQ9M52{)TQD@5sxg`V>y-i=1fOWT4O}P zm%HgMP!%?z63WobYLyklos+Mm4@v967FJO{F%`qUjIQn(AHhWYdj1>~{8|iGovdBh z=m9_^#O}w+%4lB+vXrL$)KLYpEc=3-b1fNPWn5jn7)#-$5pX+))*xG9A~|d@+L2VK z%{z=zD>$H4Y2)#Hr(2qRWWN0*wPY5!_WSG?T64>1cXgDOUmE3lsw&)NuW7lgA{$J24;H5{|1RN`{d&-`QssFe&u*9eq%XCF^!f26kysy^x88LcRgu*#E`S3B6WrA#(RC5C z-XzN(RMW6UjPKh$DR5DIRl-8$dA-bD)5$wl?~Vl$>1v+;da(ne^a*{@f&%59qirI{3PaWmU?fABv+Jv1kTR252RqPW zxsXgcfP+I9B{N2x3TWky%W2@JeKaB~s53C*z_apUJzavoXv;)UVG!*f;*^ zEZN&EWSiT<_b)n@6$#}3g5-NseAthdWu(cc8x+QkYwCfS^L&}G*y5ae7Msq8@Lqe7 z&qG1q8}M(o`0N~y^FglYf009*Oc{M@%pe@s-uMl>T$mk^3>2>T5ggB?wYb83IMNn} z$PT)A(?9Gt`~ONrR;>Pnd_j?rEus6>Ss%09g2(ZZ@_X(1MBbyr9FC*G*^1S~jOmE% z;a;D9V}00Mgm}nbsCw=35d&%9eP&#yL zdXblLD1|jsy*#u*Wm8hK=2RR8fmNQPSS!GpS00qW%`d5MOCvQ7j-Jg`D}BCa46SCO z=~NS5_?%2RVT?3<7cHuL36J0OsV$E#huc{>sJ(R97?Yfs5O(N-Ys!aPKQl!A;bas3 zEW+#?4Qe3mw-y&Ayf<%5ala7ZqokOBB&ER3^%a+cWo_xqkP&EMby4EK`M4L>67(Ri zB=O9ujV)=wXDmwPJXXmmQ9lx zsz6-wRq79An{W22ARsCQb)@aTVxQ-7wqp}#6IKv17)VfJI|40N@nibtFv=G`FR_2$ zx=mh4ssb$DF<|o{89A!{(p{ZS%1VpBurnIcW6Bm;nNIrqq_3NoU#cgOk@P7{^zFq! zfuZqwul%#{Vy>CFX;1+HqJau=$Ix(Uiaar5

YYVb1x4y@#=O^O7UE6~p>CZhQ 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 By37Co literal 8440 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 LFv()^_x}G6B7pK# literal 9478 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 diff --git a/tests/test_plotting.py b/tests/test_plotting.py index b2d14b52a7..60f1a774af 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -167,9 +167,9 @@ def test_clustermap(image_comparer, obs_keys, name): save_and_compare_images(name) -@pytest.mark.parametrize( - ("id", "fn"), - [ +params_dotplot_matrixplot_stacked_violin = [ + pytest.param(id, fn, id=id) + for id, fn in [ ( "dotplot", partial( @@ -317,10 +317,13 @@ def test_clustermap(image_comparer, obs_keys, name): figsize=(8, 2.5), ), ), - ], -) + ] +] + + +@pytest.mark.parametrize(("id", "fn"), params_dotplot_matrixplot_stacked_violin) def test_dotplot_matrixplot_stacked_violin(image_comparer, id, fn): - save_and_compare_images = partial(image_comparer, ROOT, tol=15) + save_and_compare_images = partial(image_comparer, ROOT, tol=5) adata = krumsiek11() adata.obs["numeric_column"] = adata.X[:, 0] From 06a7cd115023287e2488d20fc9e44a898b6edd0c Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 20 Sep 2024 12:34:57 +0200 Subject: [PATCH 045/118] =?UTF-8?q?Finish=20`scale`=E2=86=92`density=5Fnor?= =?UTF-8?q?m`=20deprecation=20(#3244)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/release-notes/3244.bugfix.md | 1 + src/scanpy/plotting/_anndata.py | 24 ++++++++++++++----- src/scanpy/plotting/_stacked_violin.py | 21 +++++++++------- src/scanpy/plotting/_tools/__init__.py | 9 ++++--- src/scanpy/plotting/_utils.py | 33 ++++++++++++++++++++++---- 5 files changed, 66 insertions(+), 22 deletions(-) create mode 100644 docs/release-notes/3244.bugfix.md diff --git a/docs/release-notes/3244.bugfix.md b/docs/release-notes/3244.bugfix.md new file mode 100644 index 0000000000..e918765588 --- /dev/null +++ b/docs/release-notes/3244.bugfix.md @@ -0,0 +1 @@ +Use `density_norm` instead of of `scale` (cont. from {pr}`2844`) in {func}`~scanpy.pl.violin` and {func}`~scanpy.pl.stacked_violin` {smaller}`P Angerer` diff --git a/src/scanpy/plotting/_anndata.py b/src/scanpy/plotting/_anndata.py index b164f30c7c..ddd639f62d 100755 --- a/src/scanpy/plotting/_anndata.py +++ b/src/scanpy/plotting/_anndata.py @@ -21,7 +21,7 @@ from .. import logging as logg from .._compat import old_positionals from .._settings import settings -from .._utils import _check_use_raw, _doc_params, sanitize_anndata +from .._utils import _check_use_raw, _doc_params, _empty, sanitize_anndata from . import _utils from ._docs import ( doc_common_plot_args, @@ -30,6 +30,7 @@ doc_vboundnorm, ) from ._utils import ( + _deprecated_scale, check_colornorm, scatter_base, scatter_group, @@ -47,7 +48,14 @@ from seaborn import FacetGrid from seaborn.matrix import ClusterGrid - from ._utils import ColorLike, _FontSize, _FontWeight, _LegendLoc + from .._utils import Empty + from ._utils import ( + ColorLike, + DensityNorm, + _FontSize, + _FontWeight, + _LegendLoc, + ) # TODO: is that all? _Basis = Literal["pca", "tsne", "umap", "diffmap", "draw_graph_fr"] @@ -688,7 +696,7 @@ def violin( jitter: float | bool = True, size: int = 1, layer: str | None = None, - scale: Literal["area", "count", "width"] = "width", + density_norm: DensityNorm = "width", order: Sequence[str] | None = None, multi_panel: bool | None = None, xlabel: str = "", @@ -697,6 +705,8 @@ def violin( show: bool | None = None, save: bool | str | None = None, ax: Axes | None = None, + # deprecatd + scale: DensityNorm | Empty = _empty, **kwds, ) -> Axes | FacetGrid | None: """\ @@ -729,7 +739,7 @@ def violin( default adata.raw.X is plotted. If `use_raw=False` is set, then `adata.X` is plotted. If `layer` is set to a valid layer name, then the layer is plotted. `layer` takes precedence over `use_raw`. - scale + density_norm The method used to scale the width of each violin. If 'width' (the default), each violin will have the same width. If 'area', each violin will have the same area. @@ -808,6 +818,8 @@ def violin( if isinstance(keys, str): keys = [keys] keys = list(OrderedDict.fromkeys(keys)) # remove duplicates, preserving the order + density_norm = _deprecated_scale(density_norm, scale, default="width") + del scale if isinstance(ylabel, (str, type(None))): ylabel = [ylabel] * (1 if groupby is None else len(keys)) @@ -855,7 +867,7 @@ def violin( y=y, data=obs_tidy, kind="violin", - density_norm=scale, + density_norm=density_norm, col=x, col_order=keys, sharey=False, @@ -903,7 +915,7 @@ def violin( data=obs_tidy, order=order, orient="vertical", - density_norm=scale, + density_norm=density_norm, ax=ax, **kwds, ) diff --git a/src/scanpy/plotting/_stacked_violin.py b/src/scanpy/plotting/_stacked_violin.py index f2b4a1696b..3dcbbf067a 100644 --- a/src/scanpy/plotting/_stacked_violin.py +++ b/src/scanpy/plotting/_stacked_violin.py @@ -12,7 +12,7 @@ from .. import logging as logg from .._compat import old_positionals from .._settings import settings -from .._utils import _doc_params +from .._utils import _doc_params, _empty from ._baseplot_class import BasePlot, doc_common_groupby_plot_args from ._docs import doc_common_plot_args, doc_show_save_ax, doc_vboundnorm from ._utils import ( @@ -30,8 +30,9 @@ from matplotlib.axes import Axes from matplotlib.colors import Normalize + from .._utils import Empty from ._baseplot_class import _VarNames - from ._utils import _AxesSubplot + from ._utils import DensityNorm, _AxesSubplot @_doc_params(common_plot_args=doc_common_plot_args) @@ -118,7 +119,7 @@ class StackedViolin(BasePlot): DEFAULT_JITTER_SIZE = 1 DEFAULT_LINE_WIDTH = 0.2 DEFAULT_ROW_PALETTE = None - DEFAULT_DENSITY_NORM: Literal["area", "count", "width"] = "width" + DEFAULT_DENSITY_NORM: DensityNorm = "width" DEFAULT_PLOT_YTICKLABELS = False DEFAULT_YLIM = None DEFAULT_PLOT_X_PADDING = 0.5 # a unit is the distance between two x-axis ticks @@ -274,13 +275,13 @@ def style( jitter_size: int | None = DEFAULT_JITTER_SIZE, linewidth: float | None = DEFAULT_LINE_WIDTH, row_palette: str | None = DEFAULT_ROW_PALETTE, - density_norm: Literal["area", "count", "width"] = DEFAULT_DENSITY_NORM, + density_norm: DensityNorm = DEFAULT_DENSITY_NORM, yticklabels: bool | None = DEFAULT_PLOT_YTICKLABELS, ylim: tuple[float, float] | None = DEFAULT_YLIM, x_padding: float | None = DEFAULT_PLOT_X_PADDING, y_padding: float | None = DEFAULT_PLOT_Y_PADDING, # deprecated - scale: Literal["area", "count", "width"] | None = None, + scale: DensityNorm | Empty = _empty, ) -> Self: r"""\ Modifies plot visual parameters @@ -690,7 +691,7 @@ def stacked_violin( stripplot: bool = StackedViolin.DEFAULT_STRIPPLOT, jitter: float | bool = StackedViolin.DEFAULT_JITTER, size: int = StackedViolin.DEFAULT_JITTER_SIZE, - scale: Literal["area", "count", "width"] = StackedViolin.DEFAULT_DENSITY_NORM, + density_norm: DensityNorm = StackedViolin.DEFAULT_DENSITY_NORM, yticklabels: bool | None = StackedViolin.DEFAULT_PLOT_YTICKLABELS, order: Sequence[str] | None = None, swap_axes: bool = False, @@ -704,6 +705,8 @@ def stacked_violin( vmax: float | None = None, vcenter: float | None = None, norm: Normalize | None = None, + # deprecated + scale: DensityNorm | Empty = _empty, **kwds, ) -> StackedViolin | dict | None: """\ @@ -735,7 +738,7 @@ def stacked_violin( Order in which to show the categories. Note: if `dendrogram=True` the categories order will be given by the dendrogram and `order` will be ignored. - scale + density_norm The method used to scale the width of each violin. If 'width' (the default), each violin will have the same width. If 'area', each violin will have the same area. @@ -839,7 +842,9 @@ def stacked_violin( jitter=jitter, jitter_size=size, row_palette=row_palette, - density_norm=kwds.get("density_norm", scale), + density_norm=_deprecated_scale( + density_norm, scale, default=StackedViolin.DEFAULT_DENSITY_NORM + ), yticklabels=yticklabels, linewidth=kwds.get("linewidth", StackedViolin.DEFAULT_LINE_WIDTH), ).legend(title=colorbar_title) diff --git a/src/scanpy/plotting/_tools/__init__.py b/src/scanpy/plotting/_tools/__init__.py index dceb779fd8..47f392bd44 100644 --- a/src/scanpy/plotting/_tools/__init__.py +++ b/src/scanpy/plotting/_tools/__init__.py @@ -15,7 +15,7 @@ from ... import logging as logg from ..._compat import old_positionals from ..._settings import settings -from ..._utils import _doc_params, sanitize_anndata, subsample +from ..._utils import _doc_params, _empty, sanitize_anndata, subsample from ...get import rank_genes_groups_df from .._anndata import ranking from .._docs import ( @@ -47,6 +47,9 @@ from matplotlib.colors import Colormap, Normalize from matplotlib.figure import Figure + from ..._utils import Empty + from .._utils import DensityNorm + # ------------------------------------------------------------------------------ # PCA # ------------------------------------------------------------------------------ @@ -1213,7 +1216,7 @@ def rank_genes_groups_violin( use_raw: bool | None = None, key: str | None = None, split: bool = True, - density_norm: Literal["area", "count", "width"] = "width", + density_norm: DensityNorm = "width", strip: bool = True, jitter: int | float | bool = True, size: int = 1, @@ -1221,7 +1224,7 @@ def rank_genes_groups_violin( show: bool | None = None, save: bool | None = None, # deprecated - scale: Literal["area", "count", "width"] | None = None, + scale: DensityNorm | Empty = _empty, ): """\ Plot ranking of genes for all tested comparisons. diff --git a/src/scanpy/plotting/_utils.py b/src/scanpy/plotting/_utils.py index 44e85c5c68..b56649e568 100644 --- a/src/scanpy/plotting/_utils.py +++ b/src/scanpy/plotting/_utils.py @@ -3,7 +3,7 @@ import collections.abc as cabc import warnings from collections.abc import Sequence -from typing import TYPE_CHECKING, Callable, Literal, TypedDict, Union +from typing import TYPE_CHECKING, Callable, Literal, TypedDict, Union, overload import matplotlib as mpl import numpy as np @@ -19,7 +19,7 @@ from .. import logging as logg from .._compat import old_positionals from .._settings import settings -from .._utils import NeighborsView +from .._utils import NeighborsView, _empty from . import palettes if TYPE_CHECKING: @@ -32,6 +32,8 @@ from numpy.typing import ArrayLike from PIL.Image import Image + from .._utils import Empty + # TODO: more DensityNorm = Literal["area", "count", "width"] @@ -1309,10 +1311,31 @@ def check_colornorm(vmin=None, vmax=None, vcenter=None, norm=None): return norm +@overload +def _deprecated_scale( + density_norm: DensityNorm, + scale: DensityNorm | Empty, + *, + default: DensityNorm, +) -> DensityNorm: ... + + +@overload def _deprecated_scale( - density_norm: DensityNorm, scale: DensityNorm | None, *, default: DensityNorm -) -> DensityNorm: - if scale is None: + density_norm: DensityNorm | Empty, + scale: DensityNorm | Empty, + *, + default: DensityNorm | Empty = _empty, +) -> DensityNorm | Empty: ... + + +def _deprecated_scale( + density_norm: DensityNorm | Empty, + scale: DensityNorm | Empty, + *, + default: DensityNorm | Empty = _empty, +) -> DensityNorm | Empty: + if scale is _empty: return density_norm if density_norm != default: msg = "can’t specify both `scale` and `density_norm`" From 7552cd0d66d307a0b455b960ade854fe15f22359 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 20 Sep 2024 13:38:26 +0200 Subject: [PATCH 046/118] Rely on Ruff for TYPE_CHECKING block mgmt (#3248) --- src/scanpy/cli.py | 4 ++-- src/scanpy/external/tl/_wishbone.py | 6 +++--- src/scanpy/plotting/_anndata.py | 10 +++++----- src/scanpy/plotting/_baseplot_class.py | 6 +++--- src/scanpy/plotting/_tools/__init__.py | 11 +++-------- src/scanpy/plotting/_tools/paga.py | 17 +++++++---------- src/scanpy/plotting/_tools/scatterplots.py | 15 ++++++--------- src/scanpy/plotting/_utils.py | 17 ++++++++--------- src/scanpy/queries/_queries.py | 6 +++--- src/scanpy/tools/_marker_gene_overlap.py | 4 ++-- 10 files changed, 42 insertions(+), 54 deletions(-) diff --git a/src/scanpy/cli.py b/src/scanpy/cli.py index 4a41c3a0d4..04b75c8b74 100644 --- a/src/scanpy/cli.py +++ b/src/scanpy/cli.py @@ -1,9 +1,9 @@ from __future__ import annotations -import collections.abc as cabc import os import sys from argparse import ArgumentParser, Namespace, _SubParsersAction +from collections.abc import MutableMapping from functools import lru_cache, partial from pathlib import Path from shutil import which @@ -27,7 +27,7 @@ def __init__(self, *args, _command: str, _runargs: dict[str, Any], **kwargs): ) -class _CommandDelegator(cabc.MutableMapping): +class _CommandDelegator(MutableMapping): """\ Provide the ability to delegate, but don’t calculate the whole list until necessary diff --git a/src/scanpy/external/tl/_wishbone.py b/src/scanpy/external/tl/_wishbone.py index 7e78d2eec6..e857226feb 100644 --- a/src/scanpy/external/tl/_wishbone.py +++ b/src/scanpy/external/tl/_wishbone.py @@ -1,6 +1,6 @@ from __future__ import annotations -import collections.abc as cabc +from collections.abc import Collection from typing import TYPE_CHECKING import numpy as np @@ -11,7 +11,7 @@ from ..._utils._doctests import doctest_needs if TYPE_CHECKING: - from collections.abc import Collection, Iterable + from collections.abc import Iterable from anndata import AnnData @@ -115,7 +115,7 @@ def wishbone( f"Start cell {start_cell} not found in data. " "Please rerun with correct start cell." ) - if isinstance(num_waypoints, cabc.Collection): + if isinstance(num_waypoints, Collection): diff = np.setdiff1d(num_waypoints, adata.obs.index) if diff.size > 0: logging.warning( diff --git a/src/scanpy/plotting/_anndata.py b/src/scanpy/plotting/_anndata.py index ddd639f62d..e3cbf1ae88 100755 --- a/src/scanpy/plotting/_anndata.py +++ b/src/scanpy/plotting/_anndata.py @@ -2,8 +2,8 @@ from __future__ import annotations -import collections.abc as cabc from collections import OrderedDict +from collections.abc import Collection, Mapping, Sequence from itertools import product from typing import TYPE_CHECKING, get_args @@ -38,7 +38,7 @@ ) if TYPE_CHECKING: - from collections.abc import Collection, Iterable, Mapping, Sequence + from collections.abc import Iterable from typing import Literal, Union from anndata import AnnData @@ -220,7 +220,7 @@ def _scatter_obs( isinstance(layers, str) and layers in adata.layers.keys() ): layers = (layers, layers, layers) - elif isinstance(layers, cabc.Collection) and len(layers) == 3: + elif isinstance(layers, Collection) and len(layers) == 3: layers = tuple(layers) for layer in layers: if layer not in adata.layers.keys() and layer not in ["X", None]: @@ -299,7 +299,7 @@ def _scatter_obs( palette_was_none = False if palette is None: palette_was_none = True - if isinstance(palette, cabc.Sequence) and not isinstance(palette, str): + if isinstance(palette, Sequence) and not isinstance(palette, str): if not is_color_like(palette[0]): palettes = palette else: @@ -2665,7 +2665,7 @@ def _check_var_names_type(var_names, var_group_labels, var_group_positions): var_names, var_group_labels, var_group_positions """ - if isinstance(var_names, cabc.Mapping): + if isinstance(var_names, Mapping): if var_group_labels is not None or var_group_positions is not None: logg.warning( "`var_names` is a dictionary. This will reset the current " diff --git a/src/scanpy/plotting/_baseplot_class.py b/src/scanpy/plotting/_baseplot_class.py index b3b6803c8c..928fc0057e 100644 --- a/src/scanpy/plotting/_baseplot_class.py +++ b/src/scanpy/plotting/_baseplot_class.py @@ -2,7 +2,7 @@ from __future__ import annotations -import collections.abc as cabc +from collections.abc import Mapping from typing import TYPE_CHECKING, NamedTuple from warnings import warn @@ -17,7 +17,7 @@ from ._utils import check_colornorm, make_grid_spec if TYPE_CHECKING: - from collections.abc import Iterable, Mapping, Sequence + from collections.abc import Iterable, Sequence from typing import Literal, Self, Union import pandas as pd @@ -1097,7 +1097,7 @@ def _update_var_groups(self) -> None: updates var_names, var_group_labels, var_group_positions """ - if isinstance(self.var_names, cabc.Mapping): + if isinstance(self.var_names, Mapping): if self.has_var_groups: logg.warning( "`var_names` is a dictionary. This will reset the current " diff --git a/src/scanpy/plotting/_tools/__init__.py b/src/scanpy/plotting/_tools/__init__.py index 47f392bd44..eec202d0a5 100644 --- a/src/scanpy/plotting/_tools/__init__.py +++ b/src/scanpy/plotting/_tools/__init__.py @@ -1,7 +1,6 @@ from __future__ import annotations -import collections.abc as cabc -from collections.abc import Mapping +from collections.abc import Mapping, Sequence from copy import copy from typing import TYPE_CHECKING @@ -38,7 +37,7 @@ from .scatterplots import _panel_grid, embedding, pca if TYPE_CHECKING: - from collections.abc import Iterable, Sequence + from collections.abc import Iterable from typing import Literal from anndata import AnnData @@ -1611,11 +1610,7 @@ def embedding_density( # if group is set, then plot it using multiple panels # (even if only one group is set) - if ( - group is not None - and not isinstance(group, str) - and isinstance(group, cabc.Sequence) - ): + if group is not None and not isinstance(group, str) and isinstance(group, Sequence): if ax is not None: raise ValueError("Can only specify `ax` if no `group` sequence is given.") fig, gs = _panel_grid(hspace, wspace, ncols, len(group)) diff --git a/src/scanpy/plotting/_tools/paga.py b/src/scanpy/plotting/_tools/paga.py index 6ea2560b10..f0d45e9a80 100644 --- a/src/scanpy/plotting/_tools/paga.py +++ b/src/scanpy/plotting/_tools/paga.py @@ -1,7 +1,7 @@ from __future__ import annotations -import collections.abc as cabc import warnings +from collections.abc import Collection, Mapping, Sequence from pathlib import Path from types import MappingProxyType from typing import TYPE_CHECKING @@ -26,7 +26,6 @@ from .._utils import matrix if TYPE_CHECKING: - from collections.abc import Mapping, Sequence from typing import Any, Literal, Union from anndata import AnnData @@ -506,14 +505,12 @@ def paga( groups_key = adata.uns["paga"]["groups"] def is_flat(x): - has_one_per_category = isinstance(x, cabc.Collection) and len(x) == len( + has_one_per_category = isinstance(x, Collection) and len(x) == len( adata.obs[groups_key].cat.categories ) return has_one_per_category or x is None or isinstance(x, str) - if isinstance(colors, cabc.Mapping) and isinstance( - colors[next(iter(colors))], cabc.Mapping - ): + if isinstance(colors, Mapping) and isinstance(colors[next(iter(colors))], Mapping): # handle paga pie, remap string keys to integers names_to_ixs = { n: i for i, n in enumerate(adata.obs[groups_key].cat.categories) @@ -554,7 +551,7 @@ def is_flat(x): f"it needs to be one of {labels} not {root!r}." ) root = list(labels).index(root) - if isinstance(root, cabc.Sequence) and root[0] in labels: + if isinstance(root, Sequence) and root[0] in labels: root = [list(labels).index(r) for r in root] # define the adjacency matrices @@ -600,7 +597,7 @@ def is_flat(x): sct = _paga_graph( adata, axs[icolor], - colors=colors if isinstance(colors, cabc.Mapping) else c, + colors=colors if isinstance(colors, Mapping) else c, solid_edges=solid_edges, dashed_edges=dashed_edges, transitions=transitions, @@ -935,7 +932,7 @@ def _paga_graph( patheffects.withStroke(linewidth=fontoutline, foreground="w") ] # usual scatter plot - if not isinstance(colors[0], cabc.Mapping): + if not isinstance(colors[0], Mapping): n_groups = len(pos_array) sct = ax.scatter( pos_array[:, 0], @@ -959,7 +956,7 @@ def _paga_graph( # else pie chart plot else: for ix, (xx, yy) in enumerate(zip(pos_array[:, 0], pos_array[:, 1])): - if not isinstance(colors[ix], cabc.Mapping): + if not isinstance(colors[ix], Mapping): raise ValueError( f"{colors[ix]} is neither a dict of valid " "matplotlib colors nor a valid matplotlib color." diff --git a/src/scanpy/plotting/_tools/scatterplots.py b/src/scanpy/plotting/_tools/scatterplots.py index 4f2b208ef1..93aff99552 100644 --- a/src/scanpy/plotting/_tools/scatterplots.py +++ b/src/scanpy/plotting/_tools/scatterplots.py @@ -1,6 +1,5 @@ from __future__ import annotations -import collections.abc as cabc import inspect import sys from collections.abc import Mapping, Sequence # noqa: TCH003 @@ -202,13 +201,13 @@ def embedding( title = [title] if isinstance(title, str) else list(title) # turn vmax and vmin into a sequence - if isinstance(vmax, str) or not isinstance(vmax, cabc.Sequence): + if isinstance(vmax, str) or not isinstance(vmax, Sequence): vmax = [vmax] - if isinstance(vmin, str) or not isinstance(vmin, cabc.Sequence): + if isinstance(vmin, str) or not isinstance(vmin, Sequence): vmin = [vmin] - if isinstance(vcenter, str) or not isinstance(vcenter, cabc.Sequence): + if isinstance(vcenter, str) or not isinstance(vcenter, Sequence): vcenter = [vcenter] - if isinstance(norm, Normalize) or not isinstance(norm, cabc.Sequence): + if isinstance(norm, Normalize) or not isinstance(norm, Sequence): norm = [norm] # Size @@ -219,7 +218,7 @@ def embedding( # set as ndarray if ( size is not None - and isinstance(size, (cabc.Sequence, pd.Series, np.ndarray)) + and isinstance(size, (Sequence, pd.Series, np.ndarray)) and len(size) == adata.shape[0] ): size = np.array(size, dtype=float) @@ -245,9 +244,7 @@ def embedding( # Eg. ['Gene1', 'louvain', 'Gene2']. # component_list is a list of components [[0,1], [1,2]] if ( - not isinstance(color, str) - and isinstance(color, cabc.Sequence) - and len(color) > 1 + not isinstance(color, str) and isinstance(color, Sequence) and len(color) > 1 ) or len(dimensions) > 1: if ax is not None: raise ValueError( diff --git a/src/scanpy/plotting/_utils.py b/src/scanpy/plotting/_utils.py index b56649e568..a545f1e30c 100644 --- a/src/scanpy/plotting/_utils.py +++ b/src/scanpy/plotting/_utils.py @@ -1,8 +1,7 @@ from __future__ import annotations -import collections.abc as cabc import warnings -from collections.abc import Sequence +from collections.abc import Mapping, Sequence from typing import TYPE_CHECKING, Callable, Literal, TypedDict, Union, overload import matplotlib as mpl @@ -23,7 +22,7 @@ from . import palettes if TYPE_CHECKING: - from collections.abc import Collection, Mapping + from collections.abc import Collection from anndata import AnnData from matplotlib.colors import Colormap @@ -445,12 +444,12 @@ def _set_colors_for_categorical_obs( # this creates a palette from a colormap. E.g. 'Accent, Dark2, tab20' cmap = plt.get_cmap(palette) colors_list = [to_hex(x) for x in cmap(np.linspace(0, 1, len(categories)))] - elif isinstance(palette, cabc.Mapping): + elif isinstance(palette, Mapping): colors_list = [to_hex(palette[k], keep_alpha=True) for k in categories] else: # check if palette is a list and convert it to a cycler, thus # it doesnt matter if the list is shorter than the categories length: - if isinstance(palette, cabc.Sequence): + if isinstance(palette, Sequence): if len(palette) < len(categories): logg.warning( "Length of palette colors is smaller than the number of " @@ -551,7 +550,7 @@ def add_colors_for_categorical_sample_annotation( def plot_edges(axs, adata, basis, edges_width, edges_color, *, neighbors_key=None): import networkx as nx - if not isinstance(axs, cabc.Sequence): + if not isinstance(axs, Sequence): axs = [axs] if neighbors_key is None: @@ -577,7 +576,7 @@ def plot_edges(axs, adata, basis, edges_width, edges_color, *, neighbors_key=Non def plot_arrows(axs, adata, basis, arrows_kwds=None): - if not isinstance(axs, cabc.Sequence): + if not isinstance(axs, Sequence): axs = [axs] v_prefix = next( (p for p in ["velocity", "Delta"] if f"{p}_{basis}" in adata.obsm), None @@ -724,7 +723,7 @@ def setup_axes( ax = plt.axes([left, bottom, width, height], projection="3d") axs.append(ax) else: - axs = ax if isinstance(ax, cabc.Sequence) else [ax] + axs = ax if isinstance(ax, Sequence) else [ax] return axs, panel_pos, draw_region_width, figure_width @@ -763,7 +762,7 @@ def scatter_base( Depending on whether supplying a single array or a list of arrays, return a single axis or a list of axes. """ - if isinstance(highlights, cabc.Mapping): + if isinstance(highlights, Mapping): highlights_indices = sorted(highlights) highlights_labels = [highlights[i] for i in highlights_indices] else: diff --git a/src/scanpy/queries/_queries.py b/src/scanpy/queries/_queries.py index 24a2482449..8da90151ce 100644 --- a/src/scanpy/queries/_queries.py +++ b/src/scanpy/queries/_queries.py @@ -1,6 +1,6 @@ from __future__ import annotations -import collections.abc as cabc +from collections.abc import Iterable from functools import singledispatch from types import MappingProxyType from typing import TYPE_CHECKING @@ -12,7 +12,7 @@ from ..get import rank_genes_groups_df if TYPE_CHECKING: - from collections.abc import Iterable, Mapping + from collections.abc import Mapping from typing import Any import pandas as pd @@ -60,7 +60,7 @@ def simple_query( """ if isinstance(attrs, str): attrs = [attrs] - elif isinstance(attrs, cabc.Iterable): + elif isinstance(attrs, Iterable): attrs = list(attrs) else: raise TypeError(f"attrs must be of type list or str, was {type(attrs)}.") diff --git a/src/scanpy/tools/_marker_gene_overlap.py b/src/scanpy/tools/_marker_gene_overlap.py index 534f5c3b33..1c286e9333 100644 --- a/src/scanpy/tools/_marker_gene_overlap.py +++ b/src/scanpy/tools/_marker_gene_overlap.py @@ -4,7 +4,7 @@ from __future__ import annotations -import collections.abc as cabc +from collections.abc import Set from typing import TYPE_CHECKING import numpy as np @@ -190,7 +190,7 @@ def marker_gene_overlap( if normalize is not None and method != "overlap_count": raise ValueError("Can only normalize with method=`overlap_count`.") - if not all(isinstance(val, cabc.Set) for val in reference_markers.values()): + if not all(isinstance(val, Set) for val in reference_markers.values()): try: reference_markers = { key: set(val) for key, val in reference_markers.items() From 36ec3a689002d7870054714d7b7d1bd3a4d1efb7 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 20 Sep 2024 15:11:10 +0200 Subject: [PATCH 047/118] Clean up dendrogram typing (#3249) --- src/scanpy/plotting/_anndata.py | 97 ++++++++++++++------------ src/scanpy/plotting/_baseplot_class.py | 4 +- src/scanpy/plotting/_dotplot.py | 3 +- src/scanpy/plotting/_matrixplot.py | 4 +- src/scanpy/plotting/_stacked_violin.py | 3 +- src/scanpy/plotting/_utils.py | 5 ++ 6 files changed, 64 insertions(+), 52 deletions(-) diff --git a/src/scanpy/plotting/_anndata.py b/src/scanpy/plotting/_anndata.py index e3cbf1ae88..5bd3de8188 100755 --- a/src/scanpy/plotting/_anndata.py +++ b/src/scanpy/plotting/_anndata.py @@ -31,6 +31,7 @@ ) from ._utils import ( _deprecated_scale, + _dk, check_colornorm, scatter_base, scatter_group, @@ -1189,7 +1190,7 @@ def heatmap( dendro_data = _reorder_categories_after_dendrogram( adata, groupby, - dendrogram, + dendrogram_key=_dk(dendrogram), var_names=var_names, var_group_labels=var_group_labels, var_group_positions=var_group_positions, @@ -1324,7 +1325,7 @@ def heatmap( if dendrogram: dendro_ax = fig.add_subplot(axs[1, 2], sharey=heatmap_ax) _plot_dendrogram( - dendro_ax, adata, groupby, ticks=ticks, dendrogram_key=dendrogram + dendro_ax, adata, groupby, dendrogram_key=_dk(dendrogram), ticks=ticks ) # plot group legends on top of heatmap_ax (if given) @@ -1427,7 +1428,7 @@ def heatmap( dendro_ax, adata, groupby, - dendrogram_key=dendrogram, + dendrogram_key=_dk(dendrogram), ticks=ticks, orientation="top", ) @@ -1579,7 +1580,7 @@ def tracksplot( dendro_data = _reorder_categories_after_dendrogram( adata, groupby, - dendrogram, + dendrogram_key=_dk(dendrogram), var_names=var_names, var_group_labels=var_group_labels, var_group_positions=var_group_positions, @@ -1711,7 +1712,7 @@ def tracksplot( dendro_ax, adata, groupby, - dendrogram_key=dendrogram, + dendrogram_key=_dk(dendrogram), orientation="top", ticks=ticks, ) @@ -1872,7 +1873,7 @@ def correlation_matrix( >>> sc.pl.correlation_matrix(adata, 'bulk_labels') """ - dendrogram_key = _get_dendrogram_key(adata, dendrogram, groupby) + dendrogram_key = _get_dendrogram_key(adata, _dk(dendrogram), groupby) index = adata.uns[dendrogram_key]["categories_idx_ordered"] corr_matrix = adata.uns[dendrogram_key]["correlation_matrix"] @@ -2247,13 +2248,13 @@ def _plot_gene_groups_brackets( def _reorder_categories_after_dendrogram( adata: AnnData, - groupby, - dendrogram, + groupby: str | Sequence[str], *, - var_names=None, - var_group_labels=None, - var_group_positions=None, - categories=None, + dendrogram_key: str | None, + var_names: Sequence[str], + var_group_labels: Sequence[str] | None, + var_group_positions: Sequence[tuple[int, int]] | None, + categories: Sequence[str], ): """\ Function used by plotting functions that need to reorder the the groupby @@ -2273,12 +2274,12 @@ def _reorder_categories_after_dendrogram( 'var_group_labels', and 'var_group_positions' """ - key = _get_dendrogram_key(adata, dendrogram, groupby) + dendrogram_key = _get_dendrogram_key(adata, dendrogram_key, groupby) if isinstance(groupby, str): groupby = [groupby] - dendro_info = adata.uns[key] + dendro_info = adata.uns[dendrogram_key] if groupby != dendro_info["groupby"]: raise ValueError( "Incompatible observations. The precomputed dendrogram contains " @@ -2305,36 +2306,35 @@ def _reorder_categories_after_dendrogram( ) # reorder var_groups (if any) - if var_names is not None: - var_names_idx_ordered = list(range(len(var_names))) - - if var_group_positions: - if set(var_group_labels) == set(categories): - positions_ordered = [] - labels_ordered = [] - position_start = 0 - var_names_idx_ordered = [] - for cat_name in categories_ordered: - idx = var_group_labels.index(cat_name) - position = var_group_positions[idx] - _var_names = var_names[position[0] : position[1] + 1] - var_names_idx_ordered.extend(range(position[0], position[1] + 1)) - positions_ordered.append( - (position_start, position_start + len(_var_names) - 1) - ) - position_start += len(_var_names) - labels_ordered.append(var_group_labels[idx]) - var_group_labels = labels_ordered - var_group_positions = positions_ordered - else: - logg.warning( - "Groups are not reordered because the `groupby` categories " - "and the `var_group_labels` are different.\n" - f"categories: {_format_first_three_categories(categories)}\n" - f"var_group_labels: {_format_first_three_categories(var_group_labels)}" + if var_group_positions is None or var_group_labels is None: + assert var_group_positions is None + assert var_group_labels is None + var_names_idx_ordered = None + elif set(var_group_labels) == set(categories): + positions_ordered = [] + labels_ordered = [] + position_start = 0 + var_names_idx_ordered = [] + for cat_name in categories_ordered: + idx = var_group_labels.index(cat_name) + position = var_group_positions[idx] + _var_names = var_names[position[0] : position[1] + 1] + var_names_idx_ordered.extend(range(position[0], position[1] + 1)) + positions_ordered.append( + (position_start, position_start + len(_var_names) - 1) ) + position_start += len(_var_names) + labels_ordered.append(var_group_labels[idx]) + var_group_labels = labels_ordered + var_group_positions = positions_ordered else: - var_names_idx_ordered = None + logg.warning( + "Groups are not reordered because the `groupby` categories " + "and the `var_group_labels` are different.\n" + f"categories: {_format_first_three_categories(categories)}\n" + f"var_group_labels: {_format_first_three_categories(var_group_labels)}" + ) + var_names_idx_ordered = list(range(len(var_names))) if var_names_idx_ordered is not None: var_names_ordered = [var_names[x] for x in var_names_idx_ordered] @@ -2358,14 +2358,19 @@ def _format_first_three_categories(categories): return ", ".join(categories) -def _get_dendrogram_key(adata, dendrogram_key, groupby): +def _get_dendrogram_key( + adata: AnnData, dendrogram_key: str | None, groupby: str | Sequence[str] +) -> str: # the `dendrogram_key` can be a bool an NoneType or the name of the # dendrogram key. By default the name of the dendrogram key is 'dendrogram' - if not isinstance(dendrogram_key, str): + if dendrogram_key is None: if isinstance(groupby, str): dendrogram_key = f"dendrogram_{groupby}" - elif isinstance(groupby, list): + elif isinstance(groupby, Sequence): dendrogram_key = f'dendrogram_{"_".join(groupby)}' + else: + msg = f"groupby has wrong type: {type(groupby).__name__}." + raise AssertionError(msg) if dendrogram_key not in adata.uns: from ..tools._dendrogram import dendrogram @@ -2389,7 +2394,7 @@ def _get_dendrogram_key(adata, dendrogram_key, groupby): def _plot_dendrogram( dendro_ax: Axes, adata: AnnData, - groupby: str, + groupby: str | Sequence[str], *, dendrogram_key: str | None = None, orientation: Literal["top", "bottom", "left", "right"] = "right", diff --git a/src/scanpy/plotting/_baseplot_class.py b/src/scanpy/plotting/_baseplot_class.py index 928fc0057e..98c13bc79a 100644 --- a/src/scanpy/plotting/_baseplot_class.py +++ b/src/scanpy/plotting/_baseplot_class.py @@ -874,7 +874,7 @@ def savefig(self, filename: str, bbox_inches: str | None = "tight", **kwargs): self.make_figure() plt.savefig(filename, bbox_inches=bbox_inches, **kwargs) - def _reorder_categories_after_dendrogram(self, dendrogram) -> None: + def _reorder_categories_after_dendrogram(self, dendrogram_key: str | None) -> None: """\ Function used by plotting functions that need to reorder the the groupby observations based on the dendrogram results. @@ -900,7 +900,7 @@ def _format_first_three_categories(_categories): _categories = _categories[:3] + ["etc."] return ", ".join(_categories) - key = _get_dendrogram_key(self.adata, dendrogram, self.groupby) + key = _get_dendrogram_key(self.adata, dendrogram_key, self.groupby) dendro_info = self.adata.uns[key] if self.groupby != dendro_info["groupby"]: diff --git a/src/scanpy/plotting/_dotplot.py b/src/scanpy/plotting/_dotplot.py index 2048cd0e8e..48f7dbca44 100644 --- a/src/scanpy/plotting/_dotplot.py +++ b/src/scanpy/plotting/_dotplot.py @@ -12,6 +12,7 @@ from ._baseplot_class import BasePlot, doc_common_groupby_plot_args from ._docs import doc_common_plot_args, doc_show_save_ax, doc_vboundnorm from ._utils import ( + _dk, check_colornorm, fix_kwds, make_grid_spec, @@ -1043,7 +1044,7 @@ def dotplot( ) if dendrogram: - dp.add_dendrogram(dendrogram_key=dendrogram) + dp.add_dendrogram(dendrogram_key=_dk(dendrogram)) if swap_axes: dp.swap_axes() diff --git a/src/scanpy/plotting/_matrixplot.py b/src/scanpy/plotting/_matrixplot.py index f5fc18a72f..0567cf27c1 100644 --- a/src/scanpy/plotting/_matrixplot.py +++ b/src/scanpy/plotting/_matrixplot.py @@ -16,7 +16,7 @@ doc_show_save_ax, doc_vboundnorm, ) -from ._utils import check_colornorm, fix_kwds, savefig_or_show +from ._utils import _dk, check_colornorm, fix_kwds, savefig_or_show if TYPE_CHECKING: from collections.abc import Mapping, Sequence @@ -454,7 +454,7 @@ def matrixplot( ) if dendrogram: - mp.add_dendrogram(dendrogram_key=dendrogram) + mp.add_dendrogram(dendrogram_key=_dk(dendrogram)) if swap_axes: mp.swap_axes() diff --git a/src/scanpy/plotting/_stacked_violin.py b/src/scanpy/plotting/_stacked_violin.py index 3dcbbf067a..0d18956fcd 100644 --- a/src/scanpy/plotting/_stacked_violin.py +++ b/src/scanpy/plotting/_stacked_violin.py @@ -17,6 +17,7 @@ from ._docs import doc_common_plot_args, doc_show_save_ax, doc_vboundnorm from ._utils import ( _deprecated_scale, + _dk, check_colornorm, make_grid_spec, savefig_or_show, @@ -833,7 +834,7 @@ def stacked_violin( ) if dendrogram: - vp.add_dendrogram(dendrogram_key=dendrogram) + vp.add_dendrogram(dendrogram_key=_dk(dendrogram)) if swap_axes: vp.swap_axes() vp = vp.style( diff --git a/src/scanpy/plotting/_utils.py b/src/scanpy/plotting/_utils.py index a545f1e30c..ea6aa0cb10 100644 --- a/src/scanpy/plotting/_utils.py +++ b/src/scanpy/plotting/_utils.py @@ -1342,3 +1342,8 @@ def _deprecated_scale( msg = "`scale` is deprecated, use `density_norm` instead" warnings.warn(msg, FutureWarning) return scale + + +def _dk(dendrogram: bool | str | None) -> str | None: + """Helper to convert the `dendrogram` parameter to a `dendrogram_key` parameter.""" + return None if isinstance(dendrogram, bool) else dendrogram From d77a7551fd71581b22adff3f661af756046fc8da Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 20 Sep 2024 16:13:49 +0200 Subject: [PATCH 048/118] Deprecate defunct `order` parameter in `stacked_violin` (#3252) --- src/scanpy/plotting/_dotplot.py | 2 ++ src/scanpy/plotting/_matrixplot.py | 4 +++- src/scanpy/plotting/_stacked_violin.py | 15 ++++++++++----- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/scanpy/plotting/_dotplot.py b/src/scanpy/plotting/_dotplot.py index 48f7dbca44..a895a269ce 100644 --- a/src/scanpy/plotting/_dotplot.py +++ b/src/scanpy/plotting/_dotplot.py @@ -881,6 +881,7 @@ def dotplot( use_raw: bool | None = None, log: bool = False, num_categories: int = 7, + categories_order: Sequence[str] | None = None, expression_cutoff: float = 0.0, mean_only_expressed: bool = False, cmap: str = "Reds", @@ -1024,6 +1025,7 @@ def dotplot( use_raw=use_raw, log=log, num_categories=num_categories, + categories_order=categories_order, expression_cutoff=expression_cutoff, mean_only_expressed=mean_only_expressed, standard_scale=standard_scale, diff --git a/src/scanpy/plotting/_matrixplot.py b/src/scanpy/plotting/_matrixplot.py index 0567cf27c1..059233ce37 100644 --- a/src/scanpy/plotting/_matrixplot.py +++ b/src/scanpy/plotting/_matrixplot.py @@ -134,7 +134,7 @@ def __init__( var_group_labels: Sequence[str] | None = None, var_group_rotation: float | None = None, layer: str | None = None, - standard_scale: Literal["var", "group"] = None, + standard_scale: Literal["var", "group"] | None = None, ax: _AxesSubplot | None = None, values_df: pd.DataFrame | None = None, vmin: float | None = None, @@ -343,6 +343,7 @@ def matrixplot( use_raw: bool | None = None, log: bool = False, num_categories: int = 7, + categories_order: Sequence[str] | None = None, figsize: tuple[float, float] | None = None, dendrogram: bool | str = False, title: str | None = None, @@ -436,6 +437,7 @@ def matrixplot( use_raw=use_raw, log=log, num_categories=num_categories, + categories_order=categories_order, standard_scale=standard_scale, title=title, figsize=figsize, diff --git a/src/scanpy/plotting/_stacked_violin.py b/src/scanpy/plotting/_stacked_violin.py index 0d18956fcd..a3d5e65834 100644 --- a/src/scanpy/plotting/_stacked_violin.py +++ b/src/scanpy/plotting/_stacked_violin.py @@ -694,7 +694,7 @@ def stacked_violin( size: int = StackedViolin.DEFAULT_JITTER_SIZE, density_norm: DensityNorm = StackedViolin.DEFAULT_DENSITY_NORM, yticklabels: bool | None = StackedViolin.DEFAULT_PLOT_YTICKLABELS, - order: Sequence[str] | None = None, + categories_order: Sequence[str] | None = None, swap_axes: bool = False, show: bool | None = None, save: bool | str | None = None, @@ -707,6 +707,7 @@ def stacked_violin( vcenter: float | None = None, norm: Normalize | None = None, # deprecated + order: Sequence[str] | None | Empty = _empty, scale: DensityNorm | Empty = _empty, **kwds, ) -> StackedViolin | dict | None: @@ -735,10 +736,6 @@ def stacked_violin( See :func:`~seaborn.stripplot`. size Size of the jitter points. - order - Order in which to show the categories. Note: if `dendrogram=True` - the categories order will be given by the dendrogram and `order` - will be ignored. density_norm The method used to scale the width of each violin. If 'width' (the default), each violin will have the same width. @@ -809,6 +806,13 @@ def stacked_violin( print(axes_dict) """ + if order is not _empty: + msg = ( + "`order` is deprecated (and never worked for `stacked_violin`), " + "use categories_order instead" + ) + warnings.warn(msg, FutureWarning) + # no reason to set `categories_order` here, as `order` never worked. vp = StackedViolin( adata, @@ -817,6 +821,7 @@ def stacked_violin( use_raw=use_raw, log=log, num_categories=num_categories, + categories_order=categories_order, standard_scale=standard_scale, title=title, figsize=figsize, From b4fc78e675fd270f51a96719b9a94538d58d27b7 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 20 Sep 2024 17:05:13 +0200 Subject: [PATCH 049/118] Fix *Plot.style() methods (#3206) Co-authored-by: Ilan Gold --- docs/release-notes/3206.bugfix.md | 1 + src/scanpy/plotting/_baseplot_class.py | 12 +- src/scanpy/plotting/_dotplot.py | 196 +++++----- src/scanpy/plotting/_matrixplot.py | 28 +- src/scanpy/plotting/_stacked_violin.py | 91 +++-- src/scanpy/plotting/_tools/scatterplots.py | 9 +- tests/test_plotting.py | 413 +++++++++++---------- tests/test_score_genes.py | 5 +- 8 files changed, 369 insertions(+), 386 deletions(-) create mode 100644 docs/release-notes/3206.bugfix.md diff --git a/docs/release-notes/3206.bugfix.md b/docs/release-notes/3206.bugfix.md new file mode 100644 index 0000000000..d29c34300a --- /dev/null +++ b/docs/release-notes/3206.bugfix.md @@ -0,0 +1 @@ +Fix :meth:`scanpy.pl.DotPlot.style`, :meth:`scanpy.pl.MatrixPlot.style`, and :meth:`scanpy.pl.StackedViolin.style` resetting all non-specified parameters {smaller}`P Angerer` diff --git a/src/scanpy/plotting/_baseplot_class.py b/src/scanpy/plotting/_baseplot_class.py index 98c13bc79a..6e5c8cd2c5 100644 --- a/src/scanpy/plotting/_baseplot_class.py +++ b/src/scanpy/plotting/_baseplot_class.py @@ -13,6 +13,7 @@ from .. import logging as logg from .._compat import old_positionals +from .._utils import _empty from ._anndata import _get_dendrogram_key, _plot_dendrogram, _prepare_dataframe from ._utils import check_colornorm, make_grid_spec @@ -23,8 +24,9 @@ import pandas as pd from anndata import AnnData from matplotlib.axes import Axes - from matplotlib.colors import Normalize + from matplotlib.colors import Colormap, Normalize + from .._utils import Empty from ._utils import ColorLike, _AxesSubplot _VarNames = Union[str, Sequence[str]] @@ -403,21 +405,23 @@ def add_totals( return self @old_positionals("cmap") - def style(self, *, cmap: str | None = DEFAULT_COLORMAP) -> Self: + def style(self, *, cmap: Colormap | str | None | Empty = _empty) -> Self: """\ Set visual style parameters Parameters ---------- cmap - colormap + Matplotlib color map, specified by name or directly. + If ``None``, use :obj:`matplotlib.rcParams`\\ ``["image.cmap"]`` Returns ------- Returns `self` for method chaining. """ - self.cmap = cmap + if cmap is not _empty: + self.cmap = cmap return self @old_positionals("show", "title", "width") diff --git a/src/scanpy/plotting/_dotplot.py b/src/scanpy/plotting/_dotplot.py index a895a269ce..e2ae434db6 100644 --- a/src/scanpy/plotting/_dotplot.py +++ b/src/scanpy/plotting/_dotplot.py @@ -8,7 +8,7 @@ from .. import logging as logg from .._compat import old_positionals from .._settings import settings -from .._utils import _doc_params +from .._utils import _doc_params, _empty from ._baseplot_class import BasePlot, doc_common_groupby_plot_args from ._docs import doc_common_plot_args, doc_show_save_ax, doc_vboundnorm from ._utils import ( @@ -26,13 +26,11 @@ import pandas as pd from anndata import AnnData from matplotlib.axes import Axes - from matplotlib.colors import Normalize + from matplotlib.colors import Colormap, Normalize + from .._utils import Empty from ._baseplot_class import _VarNames - from ._utils import ( - ColorLike, - _AxesSubplot, - ) + from ._utils import ColorLike, _AxesSubplot @_doc_params(common_plot_args=doc_common_plot_args) @@ -98,7 +96,7 @@ class DotPlot(BasePlot): DEFAULT_SAVE_PREFIX = "dotplot_" # default style parameters - DEFAULT_COLORMAP = "winter" + DEFAULT_COLORMAP = "Reds" DEFAULT_COLOR_ON = "dot" DEFAULT_DOT_MAX = None DEFAULT_DOT_MIN = None @@ -264,6 +262,7 @@ def __init__( ] for df in (dot_color_df, dot_size_df) ) + self.standard_scale = standard_scale # Set default style parameters self.cmap = self.DEFAULT_COLORMAP @@ -304,18 +303,18 @@ def __init__( def style( self, *, - cmap: str = DEFAULT_COLORMAP, - color_on: Literal["dot", "square"] | None = DEFAULT_COLOR_ON, - dot_max: float | None = DEFAULT_DOT_MAX, - dot_min: float | None = DEFAULT_DOT_MIN, - smallest_dot: float | None = DEFAULT_SMALLEST_DOT, - largest_dot: float | None = DEFAULT_LARGEST_DOT, - dot_edge_color: ColorLike | None = DEFAULT_DOT_EDGECOLOR, - dot_edge_lw: float | None = DEFAULT_DOT_EDGELW, - size_exponent: float | None = DEFAULT_SIZE_EXPONENT, - grid: float | None = False, - x_padding: float | None = DEFAULT_PLOT_X_PADDING, - y_padding: float | None = DEFAULT_PLOT_Y_PADDING, + cmap: Colormap | str | None | Empty = _empty, + color_on: Literal["dot", "square"] | Empty = _empty, + dot_max: float | None | Empty = _empty, + dot_min: float | None | Empty = _empty, + smallest_dot: float | Empty = _empty, + largest_dot: float | Empty = _empty, + dot_edge_color: ColorLike | None | Empty = _empty, + dot_edge_lw: float | None | Empty = _empty, + size_exponent: float | Empty = _empty, + grid: bool | Empty = _empty, + x_padding: float | Empty = _empty, + y_padding: float | Empty = _empty, ) -> Self: r"""\ Modifies plot visual parameters @@ -325,31 +324,30 @@ def style( cmap String denoting matplotlib color map. color_on - Options are 'dot' or 'square'. Be default the colomap is applied to - the color of the dot. Optionally, the colormap can be applied to an - square behind the dot, in which case the dot is transparent and only - the edge is shown. + By default the color map is applied to the color of the ``"dot"``. + Optionally, the colormap can be applied to a ``"square"`` behind the dot, + in which case the dot is transparent and only the edge is shown. dot_max - If none, the maximum dot size is set to the maximum fraction value found - (e.g. 0.6). If given, the value should be a number between 0 and 1. + If ``None``, the maximum dot size is set to the maximum fraction value found (e.g. 0.6). + If given, the value should be a number between 0 and 1. All fractions larger than dot_max are clipped to this value. dot_min - If none, the minimum dot size is set to 0. If given, - the value should be a number between 0 and 1. + If ``None``, the minimum dot size is set to 0. + If given, the value should be a number between 0 and 1. All fractions smaller than dot_min are clipped to this value. smallest_dot - If none, the smallest dot has size 0. All expression fractions with `dot_min` are plotted with this size. largest_dot - If none, the largest dot has size 200. All expression fractions with `dot_max` are plotted with this size. dot_edge_color - Dot edge color. When `color_on='dot'` the default is no edge. When - `color_on='square'`, edge color is white for darker colors and black - for lighter background square colors. + Dot edge color. + When `color_on='dot'`, ``None`` means no edge. + When `color_on='square'`, ``None`` means that + the edge color is white for darker colors and black for lighter background square colors. dot_edge_lw - Dot edge line width. When `color_on='dot'` the default is no edge. When - `color_on='square'`, line width = 1.5. + Dot edge line width. + When `color_on='dot'`, ``None`` means no edge. + When `color_on='square'`, ``None`` means a line width of 1.5. size_exponent Dot size is computed as: fraction ** size exponent and afterwards scaled to match the @@ -389,31 +387,29 @@ def style( ... .style(dot_edge_color='black', dot_edge_lw=1, grid=True) \ ... .show() """ + super().style(cmap=cmap) - # change only the values that had changed - if cmap != self.cmap: - self.cmap = cmap - if dot_max != self.dot_max: + if dot_max is not _empty: self.dot_max = dot_max - if dot_min != self.dot_min: + if dot_min is not _empty: self.dot_min = dot_min - if smallest_dot != self.smallest_dot: + if smallest_dot is not _empty: self.smallest_dot = smallest_dot - if largest_dot != self.largest_dot: + if largest_dot is not _empty: self.largest_dot = largest_dot - if color_on != self.color_on: + if color_on is not _empty: self.color_on = color_on - if size_exponent != self.size_exponent: + if size_exponent is not _empty: self.size_exponent = size_exponent - if dot_edge_color != self.dot_edge_color: + if dot_edge_color is not _empty: self.dot_edge_color = dot_edge_color - if dot_edge_lw != self.dot_edge_lw: + if dot_edge_lw is not _empty: self.dot_edge_lw = dot_edge_lw - if grid != self.grid: + if grid is not _empty: self.grid = grid - if x_padding != self.plot_x_padding: + if x_padding is not _empty: self.plot_x_padding = x_padding - if y_padding != self.plot_y_padding: + if y_padding is not _empty: self.plot_y_padding = y_padding return self @@ -575,7 +571,7 @@ def _plot_legend(self, legend_ax, return_ax_dict, normalize): self._plot_colorbar(color_legend_ax, normalize) return_ax_dict["color_legend_ax"] = color_legend_ax - def _mainplot(self, ax): + def _mainplot(self, ax: Axes): # work on a copy of the dataframes. This is to avoid changes # on the original data frames after repetitive calls to the # DotPlot object, for example once with swap_axes and other without @@ -600,9 +596,10 @@ def _mainplot(self, ax): _color_df, ax, cmap=self.cmap, + color_on=self.color_on, dot_max=self.dot_max, dot_min=self.dot_min, - color_on=self.color_on, + standard_scale=self.standard_scale, edge_color=self.dot_edge_color, edge_lw=self.dot_edge_lw, smallest_dot=self.smallest_dot, @@ -627,24 +624,23 @@ def _dotplot( dot_color: pd.DataFrame, dot_ax: Axes, *, - cmap: str = "Reds", - color_on: str | None = "dot", - y_label: str | None = None, - dot_max: float | None = None, - dot_min: float | None = None, - standard_scale: Literal["var", "group"] | None = None, - smallest_dot: float | None = 0.0, - largest_dot: float | None = 200, - size_exponent: float | None = 2, - edge_color: ColorLike | None = None, - edge_lw: float | None = None, - grid: bool | None = False, - x_padding: float | None = 0.8, - y_padding: float | None = 1.0, - vmin: float | None = None, - vmax: float | None = None, - vcenter: float | None = None, - norm: Normalize | None = None, + cmap: Colormap | str | None, + color_on: Literal["dot", "square"], + dot_max: float | None, + dot_min: float | None, + standard_scale: Literal["var", "group"] | None, + smallest_dot: float, + largest_dot: float, + size_exponent: float, + edge_color: ColorLike | None, + edge_lw: float | None, + grid: bool, + x_padding: float, + y_padding: float, + vmin: float | None, + vmax: float | None, + vcenter: float | None, + norm: Normalize | None, **kwds, ): """\ @@ -657,47 +653,25 @@ def _dotplot( Parameters ---------- - dot_size: Data frame containing the dot_size. - dot_color: Data frame containing the dot_color, should have the same, - shape, columns and indices as dot_size. - dot_ax: matplotlib axis + dot_size + Data frame containing the dot_size. + dot_color + Data frame containing the dot_color, should have the same, + shape, columns and indices as dot_size. + dot_ax + matplotlib axis cmap - String denoting matplotlib color map. color_on - Options are 'dot' or 'square'. Be default the colomap is applied to - the color of the dot. Optionally, the colormap can be applied to an - square behind the dot, in which case the dot is transparent and only - the edge is shown. - y_label: String. Label for y axis dot_max - If none, the maximum dot size is set to the maximum fraction value found - (e.g. 0.6). If given, the value should be a number between 0 and 1. - All fractions larger than dot_max are clipped to this value. dot_min - If none, the minimum dot size is set to 0. If given, - the value should be a number between 0 and 1. - All fractions smaller than dot_min are clipped to this value. standard_scale - Whether or not to standardize that dimension between 0 and 1, - meaning for each variable or group, - subtract the minimum and divide each by its maximum. smallest_dot - If none, the smallest dot has size 0. - All expression levels with `dot_min` are plotted with this size. edge_color - Dot edge color. When `color_on='dot'` the default is no edge. When - `color_on='square'`, edge color is white edge_lw - Dot edge line width. When `color_on='dot'` the default is no edge. When - `color_on='square'`, line width = 1.5 grid - Adds a grid to the plot - x_paddding - Space between the plot left/right borders and the dots center. A unit - is the distance between the x ticks. Only applied when color_on = dot - y_paddding - Space between the plot top/bottom borders and the dots center. A unit is - the distance between the y ticks. Only applied when color_on = dot + x_padding + y_padding + See `style` kwds Are passed to :func:`matplotlib.pyplot.scatter`. @@ -806,7 +780,6 @@ def _dotplot( linewidth=edge_lw, edgecolor=edge_color, ) - dot_ax.scatter(x, y, **kwds) y_ticks = np.arange(dot_color.shape[0]) + 0.5 @@ -825,7 +798,6 @@ def _dotplot( ) dot_ax.tick_params(axis="both", labelsize="small") dot_ax.grid(visible=False) - dot_ax.set_ylabel(y_label) # to be consistent with the heatmap plot, is better to # invert the order of the y-axis, such that the first group is on @@ -884,11 +856,7 @@ def dotplot( categories_order: Sequence[str] | None = None, expression_cutoff: float = 0.0, mean_only_expressed: bool = False, - cmap: str = "Reds", - dot_max: float | None = DotPlot.DEFAULT_DOT_MAX, - dot_min: float | None = DotPlot.DEFAULT_DOT_MIN, standard_scale: Literal["var", "group"] | None = None, - smallest_dot: float | None = DotPlot.DEFAULT_SMALLEST_DOT, title: str | None = None, colorbar_title: str | None = DotPlot.DEFAULT_COLOR_LEGEND_TITLE, size_title: str | None = DotPlot.DEFAULT_SIZE_LEGEND_TITLE, @@ -909,6 +877,11 @@ def dotplot( vmax: float | None = None, vcenter: float | None = None, norm: Normalize | None = None, + # Style parameters + cmap: Colormap | str | None = DotPlot.DEFAULT_COLORMAP, + dot_max: float | None = DotPlot.DEFAULT_DOT_MAX, + dot_min: float | None = DotPlot.DEFAULT_DOT_MIN, + smallest_dot: float = DotPlot.DEFAULT_SMALLEST_DOT, **kwds, ) -> DotPlot | dict | None: """\ @@ -946,15 +919,14 @@ def dotplot( If True, gene expression is averaged only over the cells expressing the given genes. dot_max - If none, the maximum dot size is set to the maximum fraction value found + If ``None``, the maximum dot size is set to the maximum fraction value found (e.g. 0.6). If given, the value should be a number between 0 and 1. All fractions larger than dot_max are clipped to this value. dot_min - If none, the minimum dot size is set to 0. If given, + If ``None``, the minimum dot size is set to 0. If given, the value should be a number between 0 and 1. All fractions smaller than dot_min are clipped to this value. smallest_dot - If none, the smallest dot has size 0. All expression levels with `dot_min` are plotted with this size. {show_save_ax} {vminmax} @@ -1014,9 +986,7 @@ def dotplot( # backwards compatibility: previous version of dotplot used `color_map` # instead of `cmap` - cmap = kwds.get("color_map", cmap) - if "color_map" in kwds: - del kwds["color_map"] + cmap = kwds.pop("color_map", cmap) dp = DotPlot( adata, @@ -1055,7 +1025,7 @@ def dotplot( dot_max=dot_max, dot_min=dot_min, smallest_dot=smallest_dot, - dot_edge_lw=kwds.pop("linewidth", DotPlot.DEFAULT_DOT_EDGELW), + dot_edge_lw=kwds.pop("linewidth", _empty), ).legend(colorbar_title=colorbar_title, size_title=size_title) if return_fig: diff --git a/src/scanpy/plotting/_matrixplot.py b/src/scanpy/plotting/_matrixplot.py index 059233ce37..9184f2455b 100644 --- a/src/scanpy/plotting/_matrixplot.py +++ b/src/scanpy/plotting/_matrixplot.py @@ -9,7 +9,7 @@ from .. import logging as logg from .._compat import old_positionals from .._settings import settings -from .._utils import _doc_params +from .._utils import _doc_params, _empty from ._baseplot_class import BasePlot, doc_common_groupby_plot_args from ._docs import ( doc_common_plot_args, @@ -25,8 +25,9 @@ import pandas as pd from anndata import AnnData from matplotlib.axes import Axes - from matplotlib.colors import Normalize + from matplotlib.colors import Colormap, Normalize + from .._utils import Empty from ._baseplot_class import _VarNames from ._utils import ColorLike, _AxesSubplot @@ -198,9 +199,9 @@ def __init__( def style( self, - cmap: str = DEFAULT_COLORMAP, - edge_color: ColorLike | None = DEFAULT_EDGE_COLOR, - edge_lw: float | None = DEFAULT_EDGE_LW, + cmap: Colormap | str | None | Empty = _empty, + edge_color: ColorLike | None | Empty = _empty, + edge_lw: float | None | Empty = _empty, ) -> Self: """\ Modifies plot visual parameters. @@ -208,11 +209,14 @@ def style( Parameters ---------- cmap - String denoting matplotlib color map. + Matplotlib color map, specified by name or directly. + If ``None``, use :obj:`matplotlib.rcParams`\\ ``["image.cmap"]`` edge_color - Edge color between the squares of matrix plot. Default is gray + Edge color between the squares of matrix plot. + If ``None``, use :obj:`matplotlib.rcParams`\\ ``["patch.edgecolor"]`` edge_lw Edge line width. + If ``None``, use :obj:`matplotlib.rcParams`\\ ``["lines.linewidth"]`` Returns ------- @@ -242,13 +246,11 @@ def style( ) """ + super().style(cmap=cmap) - # change only the values that had changed - if cmap != self.cmap: - self.cmap = cmap - if edge_color != self.edge_color: + if edge_color is not _empty: self.edge_color = edge_color - if edge_lw != self.edge_lw: + if edge_lw is not _empty: self.edge_lw = edge_lw return self @@ -347,7 +349,7 @@ def matrixplot( figsize: tuple[float, float] | None = None, dendrogram: bool | str = False, title: str | None = None, - cmap: str | None = MatrixPlot.DEFAULT_COLORMAP, + cmap: Colormap | str | None = MatrixPlot.DEFAULT_COLORMAP, colorbar_title: str | None = MatrixPlot.DEFAULT_COLOR_LEGEND_TITLE, gene_symbols: str | None = None, var_group_positions: Sequence[tuple[int, int]] | None = None, diff --git a/src/scanpy/plotting/_stacked_violin.py b/src/scanpy/plotting/_stacked_violin.py index a3d5e65834..691dd863d0 100644 --- a/src/scanpy/plotting/_stacked_violin.py +++ b/src/scanpy/plotting/_stacked_violin.py @@ -29,7 +29,7 @@ from anndata import AnnData from matplotlib.axes import Axes - from matplotlib.colors import Normalize + from matplotlib.colors import Colormap, Normalize from .._utils import Empty from ._baseplot_class import _VarNames @@ -270,17 +270,17 @@ def __init__( def style( self, *, - cmap: str | None = DEFAULT_COLORMAP, - stripplot: bool | None = DEFAULT_STRIPPLOT, - jitter: float | bool | None = DEFAULT_JITTER, - jitter_size: int | None = DEFAULT_JITTER_SIZE, - linewidth: float | None = DEFAULT_LINE_WIDTH, - row_palette: str | None = DEFAULT_ROW_PALETTE, - density_norm: DensityNorm = DEFAULT_DENSITY_NORM, - yticklabels: bool | None = DEFAULT_PLOT_YTICKLABELS, - ylim: tuple[float, float] | None = DEFAULT_YLIM, - x_padding: float | None = DEFAULT_PLOT_X_PADDING, - y_padding: float | None = DEFAULT_PLOT_Y_PADDING, + cmap: Colormap | str | None | Empty = _empty, + stripplot: bool | Empty = _empty, + jitter: float | bool | Empty = _empty, + jitter_size: int | float | Empty = _empty, + linewidth: float | None | Empty = _empty, + row_palette: str | None | Empty = _empty, + density_norm: DensityNorm | Empty = _empty, + yticklabels: bool | Empty = _empty, + ylim: tuple[float, float] | None | Empty = _empty, + x_padding: float | Empty = _empty, + y_padding: float | Empty = _empty, # deprecated scale: DensityNorm | Empty = _empty, ) -> Self: @@ -290,7 +290,8 @@ def style( Parameters ---------- cmap - String denoting matplotlib color map. + Matplotlib color map, specified by name or directly. + If ``None``, use :obj:`matplotlib.rcParams`\ ``["image.cmap"]`` stripplot Add a stripplot on top of the violin plot. See :func:`~seaborn.stripplot`. @@ -300,9 +301,11 @@ def style( jitter_size Size of the jitter points. linewidth - linewidth for the violin plots. + line width for the violin plots. + If None, use :obj:`matplotlib.rcParams`\ ``["lines.linewidth"]`` row_palette The row palette determines the colors to use for the stacked violins. + If ``None``, use :obj:`matplotlib.rcParams`\ ``["axes.prop_cycle"]`` The value should be a valid seaborn or matplotlib palette name (see :func:`~seaborn.color_palette`). Alternatively, a single color name or hex value can be passed, @@ -315,8 +318,9 @@ def style( yticklabels Set to true to view the y tick labels. ylim - minimum and maximum values for the y-axis. If set. All rows will have - the same y-axis range. Example: ylim=(0, 5) + minimum and maximum values for the y-axis. + If not ``None``, all rows will have the same y-axis range. + Example: ``ylim=(0, 5)`` x_padding Space between the plot left/right borders and the violins. A unit is the distance between the x ticks. @@ -339,20 +343,18 @@ def style( >>> sc.pl.StackedViolin(adata, markers, groupby='bulk_labels') \ ... .style(row_palette='Blues', linewidth=0).show() """ + super().style(cmap=cmap) - # modify only values that had changed - if cmap != self.cmap: - self.cmap = cmap - if row_palette != self.row_palette: + if row_palette is not _empty: self.row_palette = row_palette self.kwds["color"] = self.row_palette - if stripplot != self.stripplot: + if stripplot is not _empty: self.stripplot = stripplot - if jitter != self.jitter: + if jitter is not _empty: self.jitter = jitter - if jitter_size != self.jitter_size: + if jitter_size is not _empty: self.jitter_size = jitter_size - if yticklabels != self.plot_yticklabels: + if yticklabels is not _empty: self.plot_yticklabels = yticklabels if self.plot_yticklabels: # space needs to be added to avoid overlapping @@ -360,21 +362,15 @@ def style( self.wspace = 0.3 else: self.wspace = StackedViolin.DEFAULT_WSPACE - if ylim != self.ylim: + if ylim is not _empty: self.ylim = ylim - if x_padding != self.plot_x_padding: + if x_padding is not _empty: self.plot_x_padding = x_padding - if y_padding != self.plot_y_padding: + if y_padding is not _empty: self.plot_y_padding = y_padding - if linewidth != self.kwds["linewidth"] and linewidth != self.DEFAULT_LINE_WIDTH: + if linewidth is not _empty: self.kwds["linewidth"] = linewidth - density_norm = _deprecated_scale( - density_norm, scale, default=self.DEFAULT_DENSITY_NORM - ) - if ( - density_norm != self.kwds["density_norm"] - and density_norm != self.DEFAULT_DENSITY_NORM - ): + if (density_norm := _deprecated_scale(density_norm, scale)) is not _empty: self.kwds["density_norm"] = density_norm return self @@ -474,8 +470,8 @@ def _make_rows_of_violinplots( _matrix, colormap_array, _color_df, - x_spacer_size, - y_spacer_size, + x_spacer_size: float | int, + y_spacer_size: float | int, x_axis_order, ): import seaborn as sns # Slow import, only import if called @@ -689,23 +685,24 @@ def stacked_violin( standard_scale: Literal["var", "group"] | None = None, var_group_rotation: float | None = None, layer: str | None = None, - stripplot: bool = StackedViolin.DEFAULT_STRIPPLOT, - jitter: float | bool = StackedViolin.DEFAULT_JITTER, - size: int = StackedViolin.DEFAULT_JITTER_SIZE, - density_norm: DensityNorm = StackedViolin.DEFAULT_DENSITY_NORM, - yticklabels: bool | None = StackedViolin.DEFAULT_PLOT_YTICKLABELS, categories_order: Sequence[str] | None = None, swap_axes: bool = False, show: bool | None = None, save: bool | str | None = None, return_fig: bool | None = False, - row_palette: str | None = StackedViolin.DEFAULT_ROW_PALETTE, - cmap: str | None = StackedViolin.DEFAULT_COLORMAP, ax: _AxesSubplot | None = None, vmin: float | None = None, vmax: float | None = None, vcenter: float | None = None, norm: Normalize | None = None, + # Style options + cmap: Colormap | str | None = StackedViolin.DEFAULT_COLORMAP, + stripplot: bool = StackedViolin.DEFAULT_STRIPPLOT, + jitter: float | bool = StackedViolin.DEFAULT_JITTER, + size: int | float = StackedViolin.DEFAULT_JITTER_SIZE, + row_palette: str | None = StackedViolin.DEFAULT_ROW_PALETTE, + density_norm: DensityNorm | Empty = _empty, + yticklabels: bool = StackedViolin.DEFAULT_PLOT_YTICKLABELS, # deprecated order: Sequence[str] | None | Empty = _empty, scale: DensityNorm | Empty = _empty, @@ -848,11 +845,9 @@ def stacked_violin( jitter=jitter, jitter_size=size, row_palette=row_palette, - density_norm=_deprecated_scale( - density_norm, scale, default=StackedViolin.DEFAULT_DENSITY_NORM - ), + density_norm=_deprecated_scale(density_norm, scale), yticklabels=yticklabels, - linewidth=kwds.get("linewidth", StackedViolin.DEFAULT_LINE_WIDTH), + linewidth=kwds.get("linewidth", _empty), ).legend(title=colorbar_title) if return_fig: return vp diff --git a/src/scanpy/plotting/_tools/scatterplots.py b/src/scanpy/plotting/_tools/scatterplots.py index 93aff99552..769514a69e 100644 --- a/src/scanpy/plotting/_tools/scatterplots.py +++ b/src/scanpy/plotting/_tools/scatterplots.py @@ -182,11 +182,10 @@ def embedding( # Prevents warnings during legend creation na_color = colors.to_hex(na_color, keep_alpha=True) - if "edgecolor" not in kwargs: - # by default turn off edge color. Otherwise, for - # very small sizes the edge will not reduce its size - # (https://github.com/scverse/scanpy/issues/293) - kwargs["edgecolor"] = "none" + # by default turn off edge color. Otherwise, for + # very small sizes the edge will not reduce its size + # (https://github.com/scverse/scanpy/issues/293) + kwargs.setdefault("edgecolor", "none") # Vectorized arguments diff --git a/tests/test_plotting.py b/tests/test_plotting.py index 60f1a774af..92eb61c252 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -370,6 +370,17 @@ def test_dotplot_obj(image_comparer): save_and_compare_images("dotplot_std_scale_var") +def test_dotplot_style_no_reset(): + pbmc = pbmc68k_reduced() + plot = sc.pl.dotplot(pbmc, "CD79A", "bulk_labels", return_fig=True) + assert isinstance(plot, sc.pl.DotPlot) + assert plot.cmap == sc.pl.DotPlot.DEFAULT_COLORMAP + plot.style(cmap="winter") + assert plot.cmap == "winter" + plot.style(color_on="square") + assert plot.cmap == "winter", "style() should not reset unspecified parameters" + + def test_dotplot_add_totals(image_comparer): save_and_compare_images = partial(image_comparer, ROOT, tol=5) @@ -588,221 +599,220 @@ def test_correlation(image_comparer): save_and_compare_images("correlation") -@pytest.mark.parametrize( - ("name", "fn"), - [ - ( - "ranked_genes_sharey", - partial( - sc.pl.rank_genes_groups, n_genes=12, n_panels_per_row=3, show=False - ), - ), - ( - "ranked_genes", - partial( - sc.pl.rank_genes_groups, - n_genes=12, - n_panels_per_row=3, - sharey=False, - show=False, - ), - ), - ( - "ranked_genes_heatmap", - partial( - sc.pl.rank_genes_groups_heatmap, n_genes=4, cmap="YlGnBu", show=False - ), - ), - ( - "ranked_genes_heatmap_swap_axes", - partial( - sc.pl.rank_genes_groups_heatmap, - n_genes=20, - swap_axes=True, - use_raw=False, - show_gene_labels=False, - show=False, - vmin=-3, - vmax=3, - cmap="bwr", - ), +_RANK_GENES_GROUPS_PARAMS = [ + ( + "sharey", + partial(sc.pl.rank_genes_groups, n_genes=12, n_panels_per_row=3, show=False), + ), + ( + "basic", + partial( + sc.pl.rank_genes_groups, + n_genes=12, + n_panels_per_row=3, + sharey=False, + show=False, ), - ( - "ranked_genes_heatmap_swap_axes_vcenter", - partial( - sc.pl.rank_genes_groups_heatmap, - n_genes=20, - swap_axes=True, - use_raw=False, - show_gene_labels=False, - show=False, - vmin=-3, - vcenter=1, - vmax=3, - cmap="RdBu_r", - ), + ), + ( + "heatmap", + partial(sc.pl.rank_genes_groups_heatmap, n_genes=4, cmap="YlGnBu", show=False), + ), + ( + "heatmap_swap_axes", + partial( + sc.pl.rank_genes_groups_heatmap, + n_genes=20, + swap_axes=True, + use_raw=False, + show_gene_labels=False, + show=False, + vmin=-3, + vmax=3, + cmap="bwr", ), - ( - "ranked_genes_stacked_violin", - partial( - sc.pl.rank_genes_groups_stacked_violin, - n_genes=3, - show=False, - groups=["3", "0", "5"], - ), + ), + ( + "heatmap_swap_axes_vcenter", + partial( + sc.pl.rank_genes_groups_heatmap, + n_genes=20, + swap_axes=True, + use_raw=False, + show_gene_labels=False, + show=False, + vmin=-3, + vcenter=1, + vmax=3, + cmap="RdBu_r", ), - ( - "ranked_genes_dotplot", - partial(sc.pl.rank_genes_groups_dotplot, n_genes=4, show=False), + ), + ( + "stacked_violin", + partial( + sc.pl.rank_genes_groups_stacked_violin, + n_genes=3, + show=False, + groups=["3", "0", "5"], ), - ( - "ranked_genes_dotplot_gene_names", - partial( - sc.pl.rank_genes_groups_dotplot, - var_names={ - "T-cell": ["CD3D", "CD3E", "IL32"], - "B-cell": ["CD79A", "CD79B", "MS4A1"], - "myeloid": ["CST3", "LYZ"], - }, - values_to_plot="logfoldchanges", - cmap="bwr", - vmin=-3, - vmax=3, - show=False, - ), + ), + ( + "dotplot", + partial(sc.pl.rank_genes_groups_dotplot, n_genes=4, show=False), + ), + ( + "dotplot_gene_names", + partial( + sc.pl.rank_genes_groups_dotplot, + var_names={ + "T-cell": ["CD3D", "CD3E", "IL32"], + "B-cell": ["CD79A", "CD79B", "MS4A1"], + "myeloid": ["CST3", "LYZ"], + }, + values_to_plot="logfoldchanges", + cmap="bwr", + vmin=-3, + vmax=3, + show=False, ), - ( - "ranked_genes_dotplot_logfoldchange", - partial( - sc.pl.rank_genes_groups_dotplot, - n_genes=4, - values_to_plot="logfoldchanges", - vmin=-5, - vmax=5, - min_logfoldchange=3, - cmap="RdBu_r", - swap_axes=True, - title="log fold changes swap_axes", - show=False, - ), + ), + ( + "dotplot_logfoldchange", + partial( + sc.pl.rank_genes_groups_dotplot, + n_genes=4, + values_to_plot="logfoldchanges", + vmin=-5, + vmax=5, + min_logfoldchange=3, + cmap="RdBu_r", + swap_axes=True, + title="log fold changes swap_axes", + show=False, ), - ( - "ranked_genes_dotplot_logfoldchange_vcenter", - partial( - sc.pl.rank_genes_groups_dotplot, - n_genes=4, - values_to_plot="logfoldchanges", - vmin=-5, - vcenter=1, - vmax=5, - min_logfoldchange=3, - cmap="RdBu_r", - swap_axes=True, - title="log fold changes swap_axes", - show=False, - ), + ), + ( + "dotplot_logfoldchange_vcenter", + partial( + sc.pl.rank_genes_groups_dotplot, + n_genes=4, + values_to_plot="logfoldchanges", + vmin=-5, + vcenter=1, + vmax=5, + min_logfoldchange=3, + cmap="RdBu_r", + swap_axes=True, + title="log fold changes swap_axes", + show=False, ), - ( - "ranked_genes_matrixplot", - partial( - sc.pl.rank_genes_groups_matrixplot, - n_genes=5, - show=False, - title="matrixplot", - gene_symbols="symbol", - use_raw=False, - ), + ), + ( + "matrixplot", + partial( + sc.pl.rank_genes_groups_matrixplot, + n_genes=5, + show=False, + title="matrixplot", + gene_symbols="symbol", + use_raw=False, ), - ( - "ranked_genes_matrixplot_gene_names_symbol", - partial( - sc.pl.rank_genes_groups_matrixplot, - var_names={ - "T-cell": ["CD3D__", "CD3E__", "IL32__"], - "B-cell": ["CD79A__", "CD79B__", "MS4A1__"], - "myeloid": ["CST3__", "LYZ__"], - }, - values_to_plot="logfoldchanges", - cmap="bwr", - vmin=-3, - vmax=3, - gene_symbols="symbol", - use_raw=False, - show=False, - ), + ), + ( + "matrixplot_gene_names_symbol", + partial( + sc.pl.rank_genes_groups_matrixplot, + var_names={ + "T-cell": ["CD3D__", "CD3E__", "IL32__"], + "B-cell": ["CD79A__", "CD79B__", "MS4A1__"], + "myeloid": ["CST3__", "LYZ__"], + }, + values_to_plot="logfoldchanges", + cmap="bwr", + vmin=-3, + vmax=3, + gene_symbols="symbol", + use_raw=False, + show=False, ), - ( - "ranked_genes_matrixplot_n_genes_negative", - partial( - sc.pl.rank_genes_groups_matrixplot, - n_genes=-5, - show=False, - title="matrixplot n_genes=-5", - ), + ), + ( + "matrixplot_n_genes_negative", + partial( + sc.pl.rank_genes_groups_matrixplot, + n_genes=-5, + show=False, + title="matrixplot n_genes=-5", ), - ( - "ranked_genes_matrixplot_swap_axes", - partial( - sc.pl.rank_genes_groups_matrixplot, - n_genes=5, - show=False, - swap_axes=True, - values_to_plot="logfoldchanges", - vmin=-6, - vmax=6, - cmap="bwr", - title="log fold changes swap_axes", - ), + ), + ( + "matrixplot_swap_axes", + partial( + sc.pl.rank_genes_groups_matrixplot, + n_genes=5, + show=False, + swap_axes=True, + values_to_plot="logfoldchanges", + vmin=-6, + vmax=6, + cmap="bwr", + title="log fold changes swap_axes", ), - ( - "ranked_genes_matrixplot_swap_axes_vcenter", - partial( - sc.pl.rank_genes_groups_matrixplot, - n_genes=5, - show=False, - swap_axes=True, - values_to_plot="logfoldchanges", - vmin=-6, - vcenter=1, - vmax=6, - cmap="bwr", - title="log fold changes swap_axes", - ), + ), + ( + "matrixplot_swap_axes_vcenter", + partial( + sc.pl.rank_genes_groups_matrixplot, + n_genes=5, + show=False, + swap_axes=True, + values_to_plot="logfoldchanges", + vmin=-6, + vcenter=1, + vmax=6, + cmap="bwr", + title="log fold changes swap_axes", ), - ( - "ranked_genes_tracksplot", - partial( - sc.pl.rank_genes_groups_tracksplot, - n_genes=3, - show=False, - groups=["3", "2", "1"], - ), + ), + ( + "tracksplot", + partial( + sc.pl.rank_genes_groups_tracksplot, + n_genes=3, + show=False, + groups=["3", "2", "1"], ), - ( - "ranked_genes_violin", - partial( - sc.pl.rank_genes_groups_violin, - groups="0", - n_genes=5, - use_raw=True, - jitter=False, - strip=False, - show=False, - ), + ), + ( + "violin", + partial( + sc.pl.rank_genes_groups_violin, + groups="0", + n_genes=5, + use_raw=True, + jitter=False, + strip=False, + show=False, ), - ( - "ranked_genes_violin_not_raw", - partial( - sc.pl.rank_genes_groups_violin, - groups="0", - n_genes=5, - use_raw=False, - jitter=False, - strip=False, - show=False, - ), + ), + ( + "violin_not_raw", + partial( + sc.pl.rank_genes_groups_violin, + groups="0", + n_genes=5, + use_raw=False, + jitter=False, + strip=False, + show=False, ), - ], + ), +] + + +@pytest.mark.parametrize( + ("name", "fn"), + [pytest.param(name, fn, id=name) for name, fn in _RANK_GENES_GROUPS_PARAMS], ) def test_rank_genes_groups(image_comparer, name, fn): save_and_compare_images = partial(image_comparer, ROOT, tol=15) @@ -815,7 +825,8 @@ def test_rank_genes_groups(image_comparer, name, fn): with plt.rc_context({"axes.grid": True, "figure.figsize": (4, 4)}): fn(pbmc) - save_and_compare_images(name) + key = "ranked_genes" if name == "basic" else f"ranked_genes_{name}" + save_and_compare_images(key) plt.close() diff --git a/tests/test_score_genes.py b/tests/test_score_genes.py index c243b8e022..4ac1b62224 100644 --- a/tests/test_score_genes.py +++ b/tests/test_score_genes.py @@ -19,7 +19,8 @@ from numpy.typing import NDArray -HERE = Path(__file__).parent / "_data" +HERE = Path(__file__).parent +DATA_PATH = HERE / "_data" def _create_random_gene_names(n_genes, name_length) -> NDArray[np.str_]: @@ -72,7 +73,7 @@ def test_score_with_reference(): sc.pp.scale(adata) sc.tl.score_genes(adata, gene_list=adata.var_names[:100], score_name="Test") - with (HERE / "score_genes_reference_paul2015.pkl").open("rb") as file: + with (DATA_PATH / "score_genes_reference_paul2015.pkl").open("rb") as file: reference = pickle.load(file) # np.testing.assert_allclose(reference, adata.obs["Test"].to_numpy()) np.testing.assert_array_equal(reference, adata.obs["Test"].to_numpy()) From 4a61039d5ada81dabf5531435f1c8e526d3c255f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2024 07:43:58 +0000 Subject: [PATCH 050/118] [pre-commit.ci] pre-commit autoupdate (#3256) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6ce8309e63..a09eb15442 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.5 + rev: v0.6.7 hooks: - id: ruff types_or: [python, pyi, jupyter] From 876828aed9880b360cae12eb3a1d80953115125d Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Tue, 24 Sep 2024 19:19:24 +0200 Subject: [PATCH 051/118] Add `SIM` checks (#3258) --- pyproject.toml | 1 + src/scanpy/_settings.py | 4 +- src/scanpy/_utils/__init__.py | 17 ++--- src/scanpy/_utils/compute/is_constant.py | 5 +- src/scanpy/datasets/_datasets.py | 2 +- src/scanpy/datasets/_ebi_expression_atlas.py | 5 +- src/scanpy/external/pl.py | 5 +- src/scanpy/get/get.py | 10 +-- src/scanpy/neighbors/__init__.py | 11 +-- src/scanpy/plotting/_anndata.py | 75 ++++++------------- src/scanpy/plotting/_baseplot_class.py | 43 +++++------ src/scanpy/plotting/_tools/__init__.py | 43 ++++------- src/scanpy/plotting/_tools/paga.py | 2 +- src/scanpy/plotting/_tools/scatterplots.py | 17 +---- src/scanpy/plotting/_utils.py | 4 +- src/scanpy/preprocessing/_combat.py | 5 +- .../preprocessing/_deprecated/__init__.py | 22 +++--- src/scanpy/preprocessing/_normalization.py | 12 +-- src/scanpy/preprocessing/_pca.py | 7 +- .../preprocessing/_scrublet/__init__.py | 2 +- src/scanpy/preprocessing/_simple.py | 15 +--- src/scanpy/readwrite.py | 13 ++-- src/scanpy/tools/_dpt.py | 2 +- src/scanpy/tools/_draw_graph.py | 2 +- src/scanpy/tools/_ingest.py | 12 +-- src/scanpy/tools/_louvain.py | 5 +- src/scanpy/tools/_marker_gene_overlap.py | 9 +-- src/scanpy/tools/_paga.py | 10 +-- src/scanpy/tools/_rank_genes_groups.py | 15 +--- src/scanpy/tools/_sim.py | 32 ++++---- src/scanpy/tools/_top_genes.py | 5 +- src/scanpy/tools/_umap.py | 2 +- src/scanpy/tools/_utils.py | 6 +- .../notebooks/test_paga_paul15_subsampled.py | 2 +- tests/test_highly_variable_genes.py | 4 +- tests/test_plotting.py | 12 +-- tests/test_rank_genes_groups_logreg.py | 2 +- tests/test_scaling.py | 2 +- 38 files changed, 160 insertions(+), 282 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ec5c6e0541..355c4ff483 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -237,6 +237,7 @@ select = [ "PLR0917", # Ban APIs with too many positional parameters "FBT", # No positional boolean parameters "PT", # Pytest style + "SIM", # Simplify control flow ] ignore = [ # line too long -> we accept long comment lines; black gets rid of long code lines diff --git a/src/scanpy/_settings.py b/src/scanpy/_settings.py index b090261d1f..63f91d2279 100644 --- a/src/scanpy/_settings.py +++ b/src/scanpy/_settings.py @@ -371,7 +371,7 @@ def logpath(self) -> Path | None: def logpath(self, logpath: Path | str | None): _type_check(logpath, "logfile", (str, Path)) # set via “file object” branch of logfile.setter - self.logfile = Path(logpath).open("a") + self.logfile = Path(logpath).open("a") # noqa: SIM115 self._logpath = Path(logpath) @property @@ -519,7 +519,7 @@ def __str__(self) -> str: return "\n".join( f"{k} = {v!r}" for k, v in inspect.getmembers(self) - if not k.startswith("_") and not k == "getdoc" + if not k.startswith("_") and k != "getdoc" ) diff --git a/src/scanpy/_utils/__init__.py b/src/scanpy/_utils/__init__.py index 46d62bcde6..b8513d87ba 100644 --- a/src/scanpy/_utils/__init__.py +++ b/src/scanpy/_utils/__init__.py @@ -13,7 +13,7 @@ import sys import warnings from collections import namedtuple -from contextlib import contextmanager +from contextlib import contextmanager, suppress from enum import Enum from functools import partial, singledispatch, wraps from operator import mul, truediv @@ -281,10 +281,8 @@ def get_igraph_from_adjacency(adjacency, directed=None): g = ig.Graph(directed=directed) g.add_vertices(adjacency.shape[0]) # this adds adjacency.shape[0] vertices g.add_edges(list(zip(sources, targets))) - try: + with suppress(KeyError): g.es["weight"] = weights - except KeyError: - pass if g.vcount() != adjacency.shape[0]: logg.warning( f"The constructed graph has only {g.vcount()} nodes. " @@ -613,11 +611,10 @@ def _( out: sparse.csr_matrix | sparse.csc_matrix | None = None, ) -> sparse.csr_matrix | sparse.csc_matrix: check_op(op) - if out is not None: - if X.data is not out.data: - raise ValueError( - "`out` argument provided but not equal to X. This behavior is not supported for sparse matrix scaling." - ) + if out is not None and X.data is not out.data: + raise ValueError( + "`out` argument provided but not equal to X. This behavior is not supported for sparse matrix scaling." + ) if not allow_divide_by_zero and op is truediv: scaling_array = scaling_array.copy() + (scaling_array == 0) @@ -684,7 +681,7 @@ def _( column_scale = axis == 1 if isinstance(scaling_array, DaskArray): - if (row_scale and not X.chunksize[0] == scaling_array.chunksize[0]) or ( + if (row_scale and X.chunksize[0] != scaling_array.chunksize[0]) or ( column_scale and ( ( diff --git a/src/scanpy/_utils/compute/is_constant.py b/src/scanpy/_utils/compute/is_constant.py index 7dac03b40a..80f6581980 100644 --- a/src/scanpy/_utils/compute/is_constant.py +++ b/src/scanpy/_utils/compute/is_constant.py @@ -121,10 +121,7 @@ def _is_constant_csr_rows( for i in range(n): start = indptr[i] stop = indptr[i + 1] - if stop - start == shape[1]: - val = data[start] - else: - val = 0 + val = data[start] if stop - start == shape[1] else 0 for j in range(start, stop): if data[j] != val: result[i] = False diff --git a/src/scanpy/datasets/_datasets.py b/src/scanpy/datasets/_datasets.py index ccbc9a3bb3..41b23160d6 100644 --- a/src/scanpy/datasets/_datasets.py +++ b/src/scanpy/datasets/_datasets.py @@ -219,7 +219,7 @@ def moignard15() -> AnnData: } # annotate each observation/cell adata.obs["exp_groups"] = [ - next(gname for gname in groups.keys() if sname.startswith(gname)) + next(gname for gname in groups if sname.startswith(gname)) for sname in adata.obs_names ] # fix the order and colors of names in "groups" diff --git a/src/scanpy/datasets/_ebi_expression_atlas.py b/src/scanpy/datasets/_ebi_expression_atlas.py index 9f3bcb81ad..b7e1886e71 100644 --- a/src/scanpy/datasets/_ebi_expression_atlas.py +++ b/src/scanpy/datasets/_ebi_expression_atlas.py @@ -65,10 +65,7 @@ def read_mtx_from_stream(stream: BinaryIO) -> sparse.csr_matrix: n, m, _ = (int(x) for x in curline[:-1].split(b" ")) max_int32 = np.iinfo(np.int32).max - if n > max_int32 or m > max_int32: - coord_dtype = np.int64 - else: - coord_dtype = np.int32 + coord_dtype = np.int64 if n > max_int32 or m > max_int32 else np.int32 data = pd.read_csv( stream, diff --git a/src/scanpy/external/pl.py b/src/scanpy/external/pl.py index 662bc88eb3..a3d1767cee 100644 --- a/src/scanpy/external/pl.py +++ b/src/scanpy/external/pl.py @@ -1,5 +1,6 @@ from __future__ import annotations +import contextlib from typing import TYPE_CHECKING import matplotlib.pyplot as plt @@ -214,10 +215,8 @@ def sam( return axes if isinstance(c, str): - try: + with contextlib.suppress(KeyError): c = np.array(list(adata.obs[c])) - except KeyError: - pass if isinstance(c[0], (str, np.str_)) and isinstance(c, (np.ndarray, list)): import samalg.utilities as ut diff --git a/src/scanpy/get/get.py b/src/scanpy/get/get.py index c5e95de1ab..0c1272ae62 100644 --- a/src/scanpy/get/get.py +++ b/src/scanpy/get/get.py @@ -121,10 +121,7 @@ def _check_indices( use_raw: bool = False, ) -> tuple[list[str], list[str], list[str]]: """Common logic for checking indices for obs_df and var_df.""" - if use_raw: - alt_repr = "adata.raw" - else: - alt_repr = "adata" + alt_repr = "adata.raw" if use_raw else "adata" alt_dim = ("obs", "var")[dim == "obs"] @@ -288,10 +285,7 @@ def obs_df( var = adata.raw.var else: var = adata.var - if gene_symbols is not None: - alias_index = pd.Index(var[gene_symbols]) - else: - alias_index = None + alias_index = pd.Index(var[gene_symbols]) if gene_symbols is not None else None obs_cols, var_idx_keys, var_symbols = _check_indices( adata.obs, diff --git a/src/scanpy/neighbors/__init__.py b/src/scanpy/neighbors/__init__.py index 0666a8b3ed..64b14cf112 100644 --- a/src/scanpy/neighbors/__init__.py +++ b/src/scanpy/neighbors/__init__.py @@ -1,5 +1,6 @@ from __future__ import annotations +import contextlib from collections.abc import Mapping from textwrap import indent from types import MappingProxyType @@ -469,10 +470,7 @@ def transitions(self) -> np.ndarray | csr_matrix: ----- This has not been tested, in contrast to `transitions_sym`. """ - if issparse(self.Z): - Zinv = self.Z.power(-1) - else: - Zinv = np.diag(1.0 / np.diag(self.Z)) + Zinv = self.Z.power(-1) if issparse(self.Z) else np.diag(1.0 / np.diag(self.Z)) return self.Z @ self.transitions_sym @ Zinv @property @@ -591,10 +589,9 @@ def compute_neighbors( if isinstance(index, NNDescent): # very cautious here - try: + # TODO catch the correct exception + with contextlib.suppress(Exception): self._rp_forest = _make_forest_dict(index) - except Exception: # TODO catch the correct exception - pass start_connect = logg.debug("computed neighbors", time=start_neighbors) if method == "umap": diff --git a/src/scanpy/plotting/_anndata.py b/src/scanpy/plotting/_anndata.py index 5bd3de8188..5dfea0ae29 100755 --- a/src/scanpy/plotting/_anndata.py +++ b/src/scanpy/plotting/_anndata.py @@ -157,15 +157,15 @@ def scatter( if x is None or y is None: raise ValueError("Either provide a `basis` or `x` and `y`.") if ( - (x in adata.obs.keys() or x in var_index) - and (y in adata.obs.keys() or y in var_index) - and (color is None or color in adata.obs.keys() or color in var_index) + (x in adata.obs.columns or x in var_index) + and (y in adata.obs.columns or y in var_index) + and (color is None or color in adata.obs.columns or color in var_index) ): return _scatter_obs(**args) if ( - (x in adata.var.keys() or x in adata.obs.index) - and (y in adata.var.keys() or y in adata.obs.index) - and (color is None or color in adata.var.keys() or color in adata.obs.index) + (x in adata.var.columns or x in adata.obs.index) + and (y in adata.var.columns or y in adata.obs.index) + and (color is None or color in adata.var.columns or color in adata.obs.index) ): adata_T = adata.T axs = _scatter_obs( @@ -217,14 +217,12 @@ def _scatter_obs( use_raw = _check_use_raw(adata, use_raw) # Process layers - if layers in ["X", None] or ( - isinstance(layers, str) and layers in adata.layers.keys() - ): + if layers in ["X", None] or (isinstance(layers, str) and layers in adata.layers): layers = (layers, layers, layers) elif isinstance(layers, Collection) and len(layers) == 3: layers = tuple(layers) for layer in layers: - if layer not in adata.layers.keys() and layer not in ["X", None]: + if layer not in adata.layers and layer not in ["X", None]: raise ValueError( "`layers` should have elements that are " "either None or in adata.layers.keys()." @@ -256,7 +254,7 @@ def _scatter_obs( ) if title is not None and isinstance(title, str): title = [title] - highlights = adata.uns["highlights"] if "highlights" in adata.uns else [] + highlights = adata.uns.get("highlights", []) if basis is not None: try: # ignore the '0th' diffusion component @@ -292,19 +290,14 @@ def _scatter_obs( n = Y.shape[0] size = 120000 / n - if legend_loc.startswith("on data") and legend_fontsize is None: - legend_fontsize = rcParams["legend.fontsize"] - elif legend_fontsize is None: + if legend_fontsize is None: legend_fontsize = rcParams["legend.fontsize"] palette_was_none = False if palette is None: palette_was_none = True if isinstance(palette, Sequence) and not isinstance(palette, str): - if not is_color_like(palette[0]): - palettes = palette - else: - palettes = [palette] + palettes = palette if not is_color_like(palette[0]) else [palette] else: palettes = [palette for _ in range(len(keys))] palettes = [_utils.default_palette(palette) for palette in palettes] @@ -328,7 +321,7 @@ def _scatter_obs( else: component_name = None axis_labels = (x, y) if component_name is None else None - show_ticks = True if component_name is None else False + show_ticks = component_name is None # generate the colors color_ids: list[np.ndarray | ColorLike] = [] @@ -364,9 +357,8 @@ def _scatter_obs( categoricals.append(ikey) color_ids.append(c) - if right_margin is None and len(categoricals) > 0: - if legend_loc == "right margin": - right_margin = 0.5 + if right_margin is None and len(categoricals) > 0 and legend_loc == "right margin": + right_margin = 0.5 if title is None and keys[0] is not None: title = [ key.replace("_", " ") if not is_color_like(key) else "" for key in keys @@ -488,10 +480,7 @@ def add_centroid(centroids, name, Y, mask): all_pos = np.zeros((len(adata.obs[key].cat.categories), 2)) for iname, name in enumerate(adata.obs[key].cat.categories): - if name in centroids: - all_pos[iname] = centroids[name] - else: - all_pos[iname] = [np.nan, np.nan] + all_pos[iname] = centroids.get(name, [np.nan, np.nan]) if legend_loc == "on data export": filename = settings.writedir / "pos.csv" logg.warning(f"exporting label positions to {filename}") @@ -1245,10 +1234,7 @@ def heatmap( groupby_width = 0.2 if categorical else 0 if figsize is None: height = 6 - if show_gene_labels: - heatmap_width = len(var_names) * 0.3 - else: - heatmap_width = 8 + heatmap_width = len(var_names) * 0.3 if show_gene_labels else 8 width = heatmap_width + dendro_width + groupby_width else: width, height = figsize @@ -1352,10 +1338,7 @@ def heatmap( dendro_height = 0.8 if dendrogram else 0 groupby_height = 0.13 if categorical else 0 if figsize is None: - if show_gene_labels: - heatmap_height = len(var_names) * 0.18 - else: - heatmap_height = 4 + heatmap_height = len(var_names) * 0.18 if show_gene_labels else 4 width = 10 height = heatmap_height + dendro_height + groupby_height else: @@ -1440,10 +1423,7 @@ def heatmap( for idx, (label, pos) in enumerate( zip(var_group_labels, var_group_positions) ): - if var_groups_subset_of_groupby: - label_code = label2code[label] - else: - label_code = idx + label_code = label2code[label] if var_groups_subset_of_groupby else idx arr += [label_code] * (pos[1] + 1 - pos[0]) gene_groups_ax.imshow( np.array([arr]).T, aspect="auto", cmap=groupby_cmap, norm=norm @@ -1892,10 +1872,7 @@ def correlation_matrix( labels = adata.obs[groupby].cat.categories num_rows = corr_matrix.shape[0] colorbar_height = 0.2 - if dendrogram: - dendrogram_width = 1.8 - else: - dendrogram_width = 0 + dendrogram_width = 1.8 if dendrogram else 0 if figsize is None: corr_matrix_height = num_rows * 0.6 height = corr_matrix_height + colorbar_height @@ -2052,7 +2029,7 @@ def _prepare_dataframe( "groupby has to be a valid observation. " f"Given {group}, is not in observations: {adata.obs_keys()}" + msg ) - if group in adata.obs.keys() and group == adata.obs.index.name: + if group in adata.obs.columns and group == adata.obs.index.name: raise ValueError( f"Given group {group} is both and index and a column level, " "which is ambiguous." @@ -2171,10 +2148,7 @@ def _plot_gene_groups_brackets( if orientation == "top": # rotate labels if any of them is longer than 4 characters if rotation is None and group_labels: - if max([len(x) for x in group_labels]) > 4: - rotation = 90 - else: - rotation = 0 + rotation = 90 if max([len(x) for x in group_labels]) > 4 else 0 for idx in range(len(left)): verts.append((left[idx], 0)) # lower-left verts.append((left[idx], 0.6)) # upper-left @@ -2600,11 +2574,8 @@ def _plot_categories_as_colorblocks( ) if len(labels) > 1: groupby_ax.set_xticks(ticks) - if max([len(str(x)) for x in labels]) < 3: - # if the labels are small do not rotate them - rotation = 0 - else: - rotation = 90 + # if the labels are small do not rotate them + rotation = 0 if max(len(str(x)) for x in labels) < 3 else 90 groupby_ax.set_xticklabels(labels, rotation=rotation) # remove x ticks diff --git a/src/scanpy/plotting/_baseplot_class.py b/src/scanpy/plotting/_baseplot_class.py index 6e5c8cd2c5..e68cc07727 100644 --- a/src/scanpy/plotting/_baseplot_class.py +++ b/src/scanpy/plotting/_baseplot_class.py @@ -137,9 +137,7 @@ def __init__( self.width, self.height = figsize if figsize is not None else (None, None) self.has_var_groups = ( - True - if var_group_positions is not None and len(var_group_positions) > 0 - else False + var_group_positions is not None and len(var_group_positions) > 0 ) self._update_var_groups() @@ -160,18 +158,19 @@ def __init__( "Plot would be very large." ) - if categories_order is not None: - if set(self.obs_tidy.index.categories) != set(categories_order): - logg.error( - "Please check that the categories given by " - "the `order` parameter match the categories that " - "want to be reordered.\n\n" - "Mismatch: " - f"{set(self.obs_tidy.index.categories).difference(categories_order)}\n\n" - f"Given order categories: {categories_order}\n\n" - f"{groupby} categories: {list(self.obs_tidy.index.categories)}\n" - ) - return + if categories_order is not None and ( + set(self.obs_tidy.index.categories) != set(categories_order) + ): + logg.error( + "Please check that the categories given by " + "the `order` parameter match the categories that " + "want to be reordered.\n\n" + "Mismatch: " + f"{set(self.obs_tidy.index.categories).difference(categories_order)}\n\n" + f"Given order categories: {categories_order}\n\n" + f"{groupby} categories: {list(self.obs_tidy.index.categories)}\n" + ) + return self.adata = adata self.groupby = [groupby] if isinstance(groupby, str) else groupby @@ -388,8 +387,8 @@ def add_totals( self.group_extra_size = 0 return self - _sort = True if sort is not None else False - _ascending = True if sort == "ascending" else False + _sort = sort is not None + _ascending = sort == "ascending" counts_df = self.obs_tidy.index.value_counts(sort=_sort, ascending=_ascending) if _sort: @@ -489,10 +488,7 @@ def _plot_totals( if self.categories_order is not None: counts_df = counts_df.loc[self.categories_order] if params["color"] is None: - if f"{self.groupby}_colors" in self.adata.uns: - color = self.adata.uns[f"{self.groupby}_colors"] - else: - color = "salmon" + color = self.adata.uns.get(f"{self.groupby}_colors", "salmon") else: color = params["color"] @@ -1027,10 +1023,7 @@ def _plot_var_groups_brackets( if orientation == "top": # rotate labels if any of them is longer than 4 characters if rotation is None and group_labels: - if max([len(x) for x in group_labels]) > 4: - rotation = 90 - else: - rotation = 0 + rotation = 90 if max([len(x) for x in group_labels]) > 4 else 0 for idx, (left_coor, right_coor) in enumerate(zip(left, right)): verts.append((left_coor, 0)) # lower-left verts.append((left_coor, 0.6)) # upper-left diff --git a/src/scanpy/plotting/_tools/__init__.py b/src/scanpy/plotting/_tools/__init__.py index eec202d0a5..837d3791e8 100644 --- a/src/scanpy/plotting/_tools/__init__.py +++ b/src/scanpy/plotting/_tools/__init__.py @@ -93,9 +93,7 @@ def pca_overview(adata: AnnData, **params): -------- pp.pca """ - show = params["show"] if "show" in params else None - if "show" in params: - del params["show"] + show = params.pop("show", None) pca(adata, **params, show=False) pca_loadings(adata, show=False) pca_variance_ratio(adata, show=show) @@ -398,10 +396,7 @@ def rank_genes_groups( tl.rank_genes_groups """ - if "n_panels_per_row" in kwds: - n_panels_per_row = kwds["n_panels_per_row"] - else: - n_panels_per_row = ncols + n_panels_per_row = kwds.get("n_panels_per_row", ncols) if n_genes < 1: raise NotImplementedError( "Specifying a negative number for n_genes has not been implemented for " @@ -567,10 +562,7 @@ def _rank_genes_groups_plot( if len(genes_list) == 0: logg.warning(f"No genes found for group {group}") continue - if n_genes < 0: - genes_list = genes_list[n_genes:] - else: - genes_list = genes_list[:n_genes] + genes_list = genes_list[n_genes:] if n_genes < 0 else genes_list[:n_genes] var_names[group] = genes_list var_names_list.extend(genes_list) @@ -1566,10 +1558,7 @@ def embedding_density( # turn group into a list if needed if group == "all": - if groupby is None: - group = None - else: - group = list(adata.obs[groupby].cat.categories) + group = None if groupby is None else list(adata.obs[groupby].cat.categories) elif isinstance(group, str): group = [group] @@ -1633,10 +1622,7 @@ def embedding_density( adata.obs[density_col_name] = dens_values dot_sizes[group_mask] = np.ones(sum(group_mask)) * fg_dotsize - if title is None: - _title = group_name - else: - _title = title + _title = group_name if title is None else title ax = embedding( adata, @@ -1773,16 +1759,15 @@ def _get_values_to_plot( df["names"] = df[gene_symbols] # check that all genes are present in the df as sc.tl.rank_genes_groups # can be called with only top genes - if not check_done: - if df.shape[0] < adata.shape[1]: - message = ( - "Please run `sc.tl.rank_genes_groups` with " - "'n_genes=adata.shape[1]' to save all gene " - f"scores. Currently, only {df.shape[0]} " - "are found" - ) - logg.error(message) - raise ValueError(message) + if not check_done and df.shape[0] < adata.shape[1]: + message = ( + "Please run `sc.tl.rank_genes_groups` with " + "'n_genes=adata.shape[1]' to save all gene " + f"scores. Currently, only {df.shape[0]} " + "are found" + ) + logg.error(message) + raise ValueError(message) df["group"] = group df_list.append(df) diff --git a/src/scanpy/plotting/_tools/paga.py b/src/scanpy/plotting/_tools/paga.py index f0d45e9a80..159be79913 100644 --- a/src/scanpy/plotting/_tools/paga.py +++ b/src/scanpy/plotting/_tools/paga.py @@ -1131,7 +1131,7 @@ def paga_path( groups_key = adata.uns["paga"]["groups"] groups_names = adata.obs[groups_key].cat.categories - if "dpt_pseudotime" not in adata.obs.keys(): + if "dpt_pseudotime" not in adata.obs.columns: raise ValueError( "`pl.paga_path` requires computation of a pseudotime `tl.dpt` " "for ordering at single-cell resolution" diff --git a/src/scanpy/plotting/_tools/scatterplots.py b/src/scanpy/plotting/_tools/scatterplots.py index 769514a69e..5c15fa8df4 100644 --- a/src/scanpy/plotting/_tools/scatterplots.py +++ b/src/scanpy/plotting/_tools/scatterplots.py @@ -886,7 +886,7 @@ def pca( return embedding( adata, "pca", show=show, return_fig=return_fig, save=save, **kwargs ) - if "pca" not in adata.obsm.keys() and "X_pca" not in adata.obsm.keys(): + if "pca" not in adata.obsm and "X_pca" not in adata.obsm: raise KeyError( f"Could not find entry in `obsm` for 'pca'.\n" f"Available keys are: {list(adata.obsm.keys())}." @@ -1011,10 +1011,7 @@ def spatial( crop_coord = _check_crop_coord(crop_coord, scale_factor) na_color = _check_na_color(na_color, img=img) - if bw: - cmap_img = "gray" - else: - cmap_img = None + cmap_img = "gray" if bw else None circle_radius = size * scale_factor * spot_size * 0.5 axs = embedding( @@ -1342,10 +1339,7 @@ def _check_spatial_data( library_id = list(spatial_mapping.keys())[0] else: library_id = None - if library_id is not None: - spatial_data = spatial_mapping[library_id] - else: - spatial_data = None + spatial_data = spatial_mapping[library_id] if library_id is not None else None return library_id, spatial_data @@ -1387,10 +1381,7 @@ def _check_na_color( na_color: ColorLike | None, *, img: np.ndarray | None = None ) -> ColorLike: if na_color is None: - if img is not None: - na_color = (0.0, 0.0, 0.0, 0.0) - else: - na_color = "lightgray" + na_color = (0.0, 0.0, 0.0, 0.0) if img is not None else "lightgray" return na_color diff --git a/src/scanpy/plotting/_utils.py b/src/scanpy/plotting/_utils.py index ea6aa0cb10..13832658f5 100644 --- a/src/scanpy/plotting/_utils.py +++ b/src/scanpy/plotting/_utils.py @@ -1280,10 +1280,10 @@ def fix_kwds(kwds_dict, **kwargs): def _get_basis(adata: AnnData, basis: str): - if basis in adata.obsm.keys(): + if basis in adata.obsm: basis_key = basis - elif f"X_{basis}" in adata.obsm.keys(): + elif f"X_{basis}" in adata.obsm: basis_key = f"X_{basis}" return basis_key diff --git a/src/scanpy/preprocessing/_combat.py b/src/scanpy/preprocessing/_combat.py index b8487e4e7e..ef193d38b4 100644 --- a/src/scanpy/preprocessing/_combat.py +++ b/src/scanpy/preprocessing/_combat.py @@ -196,10 +196,7 @@ def combat( raise ValueError("Covariates must be unique") # only works on dense matrices so far - if issparse(adata.X): - X = adata.X.toarray().T - else: - X = adata.X.T + X = adata.X.toarray().T if issparse(adata.X) else adata.X.T data = pd.DataFrame(data=X, index=adata.var_names, columns=adata.obs_names) sanitize_anndata(adata) diff --git a/src/scanpy/preprocessing/_deprecated/__init__.py b/src/scanpy/preprocessing/_deprecated/__init__.py index bb944b874a..7cd7520171 100644 --- a/src/scanpy/preprocessing/_deprecated/__init__.py +++ b/src/scanpy/preprocessing/_deprecated/__init__.py @@ -7,7 +7,7 @@ @legacy_api("max_fraction", "mult_with_mean") def normalize_per_cell_weinreb16_deprecated( - X: np.ndarray, + x: np.ndarray, *, max_fraction: float = 1, mult_with_mean: bool = False, @@ -37,23 +37,23 @@ def normalize_per_cell_weinreb16_deprecated( if max_fraction < 0 or max_fraction > 1: raise ValueError("Choose max_fraction between 0 and 1.") - counts_per_cell = X.sum(1).A1 if issparse(X) else X.sum(1) - gene_subset = np.all(X <= counts_per_cell[:, None] * max_fraction, axis=0) - if issparse(X): + counts_per_cell = x.sum(1).A1 if issparse(x) else x.sum(1) + gene_subset = np.all(x <= counts_per_cell[:, None] * max_fraction, axis=0) + if issparse(x): gene_subset = gene_subset.A1 tc_include = ( - X[:, gene_subset].sum(1).A1 if issparse(X) else X[:, gene_subset].sum(1) + x[:, gene_subset].sum(1).A1 if issparse(x) else x[:, gene_subset].sum(1) ) - X_norm = ( - X.multiply(csr_matrix(1 / tc_include[:, None])) - if issparse(X) - else X / tc_include[:, None] + x_norm = ( + x.multiply(csr_matrix(1 / tc_include[:, None])) + if issparse(x) + else x / tc_include[:, None] ) if mult_with_mean: - X_norm *= np.mean(counts_per_cell) + x_norm *= np.mean(counts_per_cell) - return X_norm + return x_norm def zscore_deprecated(X: np.ndarray) -> np.ndarray: diff --git a/src/scanpy/preprocessing/_normalization.py b/src/scanpy/preprocessing/_normalization.py index c6fccfb70a..686c69b224 100644 --- a/src/scanpy/preprocessing/_normalization.py +++ b/src/scanpy/preprocessing/_normalization.py @@ -206,25 +206,25 @@ def normalize_total( view_to_actual(adata) - X = _get_obs_rep(adata, layer=layer) + x = _get_obs_rep(adata, layer=layer) gene_subset = None msg = "normalizing counts per cell" - counts_per_cell = axis_sum(X, axis=1) + counts_per_cell = axis_sum(x, axis=1) if exclude_highly_expressed: counts_per_cell = np.ravel(counts_per_cell) # at least one cell as more than max_fraction of counts per cell - gene_subset = axis_sum((X > counts_per_cell[:, None] * max_fraction), axis=0) + gene_subset = axis_sum((x > counts_per_cell[:, None] * max_fraction), axis=0) gene_subset = np.asarray(np.ravel(gene_subset) == 0) msg += ( ". The following highly-expressed genes are not considered during " f"normalization factor computation:\n{adata.var_names[~gene_subset].tolist()}" ) - counts_per_cell = axis_sum(X[:, gene_subset], axis=1) + counts_per_cell = axis_sum(x[:, gene_subset], axis=1) start = logg.info(msg) counts_per_cell = np.ravel(counts_per_cell) @@ -237,12 +237,12 @@ def normalize_total( if key_added is not None: adata.obs[key_added] = counts_per_cell _set_obs_rep( - adata, _normalize_data(X, counts_per_cell, target_sum), layer=layer + adata, _normalize_data(x, counts_per_cell, target_sum), layer=layer ) else: # not recarray because need to support sparse dat = dict( - X=_normalize_data(X, counts_per_cell, target_sum, copy=True), + X=_normalize_data(x, counts_per_cell, target_sum, copy=True), norm_factor=counts_per_cell, ) diff --git a/src/scanpy/preprocessing/_pca.py b/src/scanpy/preprocessing/_pca.py index 5b5706c123..93432841f8 100644 --- a/src/scanpy/preprocessing/_pca.py +++ b/src/scanpy/preprocessing/_pca.py @@ -202,10 +202,7 @@ def pca( if n_comps is None: min_dim = min(adata_comp.n_vars, adata_comp.n_obs) - if settings.N_PCS >= min_dim: - n_comps = min_dim - 1 - else: - n_comps = settings.N_PCS + n_comps = min_dim - 1 if min_dim <= settings.N_PCS else settings.N_PCS logg.info(f" with n_comps={n_comps}") @@ -395,7 +392,7 @@ def _handle_mask_var( if use_highly_variable or ( use_highly_variable is None and mask_var is _empty - and "highly_variable" in adata.var.keys() + and "highly_variable" in adata.var.columns ): mask_var = "highly_variable" diff --git a/src/scanpy/preprocessing/_scrublet/__init__.py b/src/scanpy/preprocessing/_scrublet/__init__.py index 976dafe89f..d57eb81750 100644 --- a/src/scanpy/preprocessing/_scrublet/__init__.py +++ b/src/scanpy/preprocessing/_scrublet/__init__.py @@ -245,7 +245,7 @@ def _run_scrublet(ad_obs: AnnData, ad_sim: AnnData | None = None): return {"obs": ad_obs.obs, "uns": ad_obs.uns["scrublet"]} if batch_key is not None: - if batch_key not in adata.obs.keys(): + if batch_key not in adata.obs.columns: msg = ( "`batch_key` must be a column of .obs in the input AnnData object," f"but {batch_key!r} is not in {adata.obs.keys()!r}." diff --git a/src/scanpy/preprocessing/_simple.py b/src/scanpy/preprocessing/_simple.py index aea5d93324..e18773d843 100644 --- a/src/scanpy/preprocessing/_simple.py +++ b/src/scanpy/preprocessing/_simple.py @@ -446,10 +446,7 @@ def log1p_sparse(X: spmatrix, *, base: Number | None = None, copy: bool = False) def log1p_array(X: np.ndarray, *, base: Number | None = None, copy: bool = False): # Can force arrays to be np.ndarrays, but would be useful to not if copy: - if not np.issubdtype(X.dtype, np.floating): - X = X.astype(float) - else: - X = X.copy() + X = X.astype(float) if not np.issubdtype(X.dtype, np.floating) else X.copy() elif not (np.issubdtype(X.dtype, np.floating) or np.issubdtype(X.dtype, complex)): X = X.astype(float) np.log1p(X, out=X) @@ -770,10 +767,7 @@ def regress_out( # regress on one or several ordinal variables else: # create data frame with selected keys (if given) - if keys: - regressors = adata.obs[keys] - else: - regressors = adata.obs.copy() + regressors = adata.obs[keys] if keys else adata.obs.copy() # add column of ones at index 0 (first column) regressors.insert(0, "ones", 1.0) @@ -790,10 +784,7 @@ def regress_out( for idx, data_chunk in enumerate(chunk_list): # each task is a tuple of a data_chunk eg. (adata.X[:,0:100]) and # the regressors. This data will be passed to each of the jobs. - if variable_is_categorical: - regres = regressors_chunk[idx] - else: - regres = regressors + regres = regressors_chunk[idx] if variable_is_categorical else regressors tasks.append(tuple((data_chunk, regres, variable_is_categorical))) from joblib import Parallel, delayed diff --git a/src/scanpy/readwrite.py b/src/scanpy/readwrite.py index 90179daf46..9e0a298e18 100644 --- a/src/scanpy/readwrite.py +++ b/src/scanpy/readwrite.py @@ -703,13 +703,12 @@ def read_params( params = OrderedDict([]) for line in filename.open(): - if "=" in line: - if not as_header or line.startswith("#"): - line = line[1:] if line.startswith("#") else line - key, val = line.split("=") - key = key.strip() - val = val.strip() - params[key] = convert_string(val) + if "=" in line and (not as_header or line.startswith("#")): + line = line[1:] if line.startswith("#") else line + key, val = line.split("=") + key = key.strip() + val = val.strip() + params[key] = convert_string(val) return params diff --git a/src/scanpy/tools/_dpt.py b/src/scanpy/tools/_dpt.py index 8c5f7d857b..c0fa59262f 100644 --- a/src/scanpy/tools/_dpt.py +++ b/src/scanpy/tools/_dpt.py @@ -137,7 +137,7 @@ def dpt( " adata.uns['iroot'] = root_cell_index\n" " adata.var['xroot'] = adata[root_cell_name, :].X" ) - if "X_diffmap" not in adata.obsm.keys(): + if "X_diffmap" not in adata.obsm: logg.warning( "Trying to run `tl.dpt` without prior call of `tl.diffmap`. " "Falling back to `tl.diffmap` with default parameters." diff --git a/src/scanpy/tools/_draw_graph.py b/src/scanpy/tools/_draw_graph.py index b36638b5b5..4e8c91fb1f 100644 --- a/src/scanpy/tools/_draw_graph.py +++ b/src/scanpy/tools/_draw_graph.py @@ -130,7 +130,7 @@ def draw_graph( if adjacency is None: adjacency = _choose_graph(adata, obsp, neighbors_key) # init coordinates - if init_pos in adata.obsm.keys(): + if init_pos in adata.obsm: init_coords = adata.obsm[init_pos] elif init_pos == "paga" or init_pos: init_coords = get_init_pos_from_paga( diff --git a/src/scanpy/tools/_ingest.py b/src/scanpy/tools/_ingest.py index 136f58af46..9ced418888 100644 --- a/src/scanpy/tools/_ingest.py +++ b/src/scanpy/tools/_ingest.py @@ -297,16 +297,12 @@ def _init_neighbors(self, adata, neighbors_key): self._use_rep = "X_pca" self._n_pcs = neighbors["params"]["n_pcs"] self._rep = adata.obsm["X_pca"][:, : self._n_pcs] - elif adata.n_vars > settings.N_PCS and "X_pca" in adata.obsm.keys(): + elif adata.n_vars > settings.N_PCS and "X_pca" in adata.obsm: self._use_rep = "X_pca" self._rep = adata.obsm["X_pca"][:, : settings.N_PCS] self._n_pcs = self._rep.shape[1] - if "metric_kwds" in neighbors["params"]: - self._metric_kwds = neighbors["params"]["metric_kwds"] - else: - self._metric_kwds = {} - + self._metric_kwds = neighbors["params"].get("metric_kwds", {}) self._metric = neighbors["params"]["metric"] self._neigh_random_state = neighbors["params"].get("random_state", 0) @@ -317,7 +313,7 @@ def _init_pca(self, adata): self._pca_use_hvg = adata.uns["pca"]["params"]["use_highly_variable"] mask = "highly_variable" - if self._pca_use_hvg and mask not in adata.var.keys(): + if self._pca_use_hvg and mask not in adata.var.columns: msg = f"Did not find `adata.var[{mask!r}']`." raise ValueError(msg) @@ -376,7 +372,7 @@ def _same_rep(self): return self._pca(self._n_pcs) if self._use_rep == "X": return adata.X - if self._use_rep in adata.obsm.keys(): + if self._use_rep in adata.obsm: return adata.obsm[self._use_rep] return adata.X diff --git a/src/scanpy/tools/_louvain.py b/src/scanpy/tools/_louvain.py index e6259f035d..d3e616a850 100644 --- a/src/scanpy/tools/_louvain.py +++ b/src/scanpy/tools/_louvain.py @@ -163,10 +163,7 @@ def louvain( if not directed: logg.debug(" using the undirected graph") g = _utils.get_igraph_from_adjacency(adjacency, directed=directed) - if use_weights: - weights = np.array(g.es["weight"]).astype(np.float64) - else: - weights = None + weights = np.array(g.es["weight"]).astype(np.float64) if use_weights else None if flavor == "vtraag": import louvain diff --git a/src/scanpy/tools/_marker_gene_overlap.py b/src/scanpy/tools/_marker_gene_overlap.py index 1c286e9333..a1d71cf993 100644 --- a/src/scanpy/tools/_marker_gene_overlap.py +++ b/src/scanpy/tools/_marker_gene_overlap.py @@ -30,10 +30,7 @@ def _calc_overlap_count(markers1: dict, markers2: dict): overlaps = np.zeros((len(markers1), len(markers2))) for j, marker_group in enumerate(markers1): - tmp = [ - len(markers2[i].intersection(markers1[marker_group])) - for i in markers2.keys() - ] + tmp = [len(markers2[i].intersection(markers1[marker_group])) for i in markers2] overlaps[j, :] = tmp return overlaps @@ -51,7 +48,7 @@ def _calc_overlap_coef(markers1: dict, markers2: dict): tmp = [ len(markers2[i].intersection(markers1[marker_group])) / max(min(len(markers2[i]), len(markers1[marker_group])), 1) - for i in markers2.keys() + for i in markers2 ] overlap_coef[j, :] = tmp @@ -70,7 +67,7 @@ def _calc_jaccard(markers1: dict, markers2: dict): tmp = [ len(markers2[i].intersection(markers1[marker_group])) / len(markers2[i].union(markers1[marker_group])) - for i in markers2.keys() + for i in markers2 ] jacc_results[j, :] = tmp diff --git a/src/scanpy/tools/_paga.py b/src/scanpy/tools/_paga.py index 98f0ac622b..98146b83e2 100644 --- a/src/scanpy/tools/_paga.py +++ b/src/scanpy/tools/_paga.py @@ -196,10 +196,7 @@ def _compute_connectivities_v1_2(self): inter_es = inter_es.tocoo() for i, j, v in zip(inter_es.row, inter_es.col, inter_es.data): expected_random_null = (es[i] * ns[j] + es[j] * ns[i]) / (n - 1) - if expected_random_null != 0: - scaled_value = v / expected_random_null - else: - scaled_value = 1 + scaled_value = v / expected_random_null if expected_random_null != 0 else 1 if scaled_value > 1: scaled_value = 1 connectivities[i, j] = scaled_value @@ -229,10 +226,7 @@ def _compute_connectivities_v1_0(self): for i, j, v in zip(inter_es.row, inter_es.col, inter_es.data): # have n_neighbors**2 inside sqrt for backwards compat geom_mean_approx_knn = np.sqrt(n_neighbors_sq * ns[i] * ns[j]) - if geom_mean_approx_knn != 0: - scaled_value = v / geom_mean_approx_knn - else: - scaled_value = 1 + scaled_value = v / geom_mean_approx_knn if geom_mean_approx_knn != 0 else 1 connectivities[i, j] = scaled_value # set attributes self.ns = ns diff --git a/src/scanpy/tools/_rank_genes_groups.py b/src/scanpy/tools/_rank_genes_groups.py index 3327fe7501..56b71d55eb 100644 --- a/src/scanpy/tools/_rank_genes_groups.py +++ b/src/scanpy/tools/_rank_genes_groups.py @@ -287,10 +287,7 @@ def wilcoxon( # initialize space for z-scores scores = np.zeros(n_genes) # initialize space for tie correction coefficients - if tie_correct: - T = np.zeros(n_genes) - else: - T = 1 + T = np.zeros(n_genes) if tie_correct else 1 for group_index, mask_obs in enumerate(self.groups_masks_obs): if group_index == self.ireference: @@ -346,10 +343,7 @@ def wilcoxon( for group_index, mask_obs in enumerate(self.groups_masks_obs): n_active = np.count_nonzero(mask_obs) - if tie_correct: - T_i = T[group_index] - else: - T_i = 1 + T_i = T[group_index] if tie_correct else 1 std_dev = np.sqrt( T_i * n_active * (n_cells - n_active) * (n_cells + 1) / 12.0 @@ -733,10 +727,7 @@ def rank_genes_groups( def _calc_frac(X): - if issparse(X): - n_nonzero = X.getnnz(axis=0) - else: - n_nonzero = np.count_nonzero(X, axis=0) + n_nonzero = X.getnnz(axis=0) if issparse(X) else np.count_nonzero(X, axis=0) return n_nonzero / X.shape[0] diff --git a/src/scanpy/tools/_sim.py b/src/scanpy/tools/_sim.py index bf562b8408..7410442952 100644 --- a/src/scanpy/tools/_sim.py +++ b/src/scanpy/tools/_sim.py @@ -198,7 +198,7 @@ def sample_dynamic_data(**params): X[::step], dir=writedir, noiseObs=noiseObs, - append=(False if restart == 0 else True), + append=restart != 0, branching=branching, nrRealizations=nrRealizations, ) @@ -208,7 +208,7 @@ def sample_dynamic_data(**params): noiseDyn * np.random.randn(500, 3), dir=writedir, noiseObs=noiseObs, - append=(False if restart == 0 else True), + append=restart != 0, branching=branching, nrRealizations=nrRealizations, ) @@ -270,7 +270,7 @@ def sample_dynamic_data(**params): X[::step], dir=writedir, noiseObs=noiseObs, - append=(False if restart == 0 else True), + append=restart != 0, branching=branching, nrRealizations=nrRealizations, ) @@ -367,7 +367,7 @@ def write_data( # variable names if varNames: header += f'{"it":>2} ' - for v in varNames.keys(): + for v in varNames: header += f"{v:>7} " with (dir / f"sim_{id}.txt").open("ab" if append else "wb") as f: np.savetxt( @@ -430,7 +430,7 @@ def __init__( # checks if initType not in ["branch", "random"]: raise RuntimeError("initType must be either: branch, random") - if model not in self.availModels.keys(): + if model not in self.availModels: message = "model not among predefined models \n" # noqa: F841 # TODO FIX # read from file from .. import sim_models @@ -605,12 +605,12 @@ def set_coupl(self, Coupl=None): or via sampling. """ self.varNames = {str(i): i for i in range(self.dim)} - if self.model not in self.availModels.keys() and Coupl is None: + if self.model not in self.availModels and Coupl is None: self.read_model() elif "var" in self.model.name: # vector auto regressive process self.Coupl = Coupl - self.boolRules = {s: "" for s in self.varNames.keys()} + self.boolRules = {s: "" for s in self.varNames} names = list(self.varNames.keys()) for gp in range(self.dim): pas = [] @@ -819,7 +819,7 @@ def parents_from_boolRule(self, rule): pa_old = [] pa_delete = [] for pa in rule_pa: - if pa not in self.varNames.keys(): + if pa not in self.varNames: settings.m(0, "list of available variables:") settings.m(0, list(self.varNames.keys())) message = ( @@ -842,12 +842,11 @@ def parents_from_boolRule(self, rule): def build_boolCoeff(self): """Compute coefficients for tuple space.""" # coefficients for hill functions from boolean update rules - self.boolCoeff = {s: [] for s in self.varNames.keys()} + self.boolCoeff = {s: [] for s in self.varNames} # parents - self.pas = {s: [] for s in self.varNames.keys()} + self.pas = {s: [] for s in self.varNames} # - for key in self.boolRules.keys(): - rule = self.boolRules[key] + for key, rule in self.boolRules.items(): self.pas[key] = self.parents_from_boolRule(rule) pasIndices = [self.varNames[pa] for pa in self.pas[key]] # check whether there are coupling matrix entries for each parent @@ -1150,11 +1149,10 @@ def sim_givenAdj(self, Adj: np.ndarray, model="line"): # if there is more than a child with a single parent # order these children (there are two in three dim) # by distance to the source/parent - if nrchildren_par[1] > 1: - if Adj[children_sorted[0], parents[0]] == 0: - help = children_sorted[0] - children_sorted[0] = children_sorted[1] - children_sorted[1] = help + if nrchildren_par[1] > 1 and Adj[children_sorted[0], parents[0]] == 0: + help = children_sorted[0] + children_sorted[0] = children_sorted[1] + children_sorted[1] = help for gp in children_sorted: for g in range(dim): diff --git a/src/scanpy/tools/_top_genes.py b/src/scanpy/tools/_top_genes.py index 00dc764d82..d66e9232f0 100644 --- a/src/scanpy/tools/_top_genes.py +++ b/src/scanpy/tools/_top_genes.py @@ -181,10 +181,7 @@ def ROC_AUC_analysis( y_true = mask for i, j in enumerate(name_list): vec = adata[:, [j]].X - if issparse(vec): - y_score = vec.todense() - else: - y_score = vec + y_score = vec.todense() if issparse(vec) else vec ( fpr[name_list[i]], diff --git a/src/scanpy/tools/_umap.py b/src/scanpy/tools/_umap.py index c23b5551fa..4f225da2a1 100644 --- a/src/scanpy/tools/_umap.py +++ b/src/scanpy/tools/_umap.py @@ -187,7 +187,7 @@ def umap( if a is None or b is None: a, b = find_ab_params(spread, min_dist) adata.uns[key_uns] = dict(params=dict(a=a, b=b)) - if isinstance(init_pos, str) and init_pos in adata.obsm.keys(): + if isinstance(init_pos, str) and init_pos in adata.obsm: init_coords = adata.obsm[init_pos] elif isinstance(init_pos, str) and init_pos == "paga": init_coords = get_init_pos_from_paga( diff --git a/src/scanpy/tools/_utils.py b/src/scanpy/tools/_utils.py index b3ffa7d324..97e2de0df1 100644 --- a/src/scanpy/tools/_utils.py +++ b/src/scanpy/tools/_utils.py @@ -30,7 +30,7 @@ def _choose_representation( use_rep = "X" if use_rep is None: if adata.n_vars > settings.N_PCS: - if "X_pca" in adata.obsm.keys(): + if "X_pca" in adata.obsm: if n_pcs is not None and n_pcs > adata.obsm["X_pca"].shape[1]: raise ValueError( "`X_pca` does not have enough PCs. Rerun `sc.pp.pca` with adjusted `n_comps`." @@ -50,7 +50,7 @@ def _choose_representation( logg.info(" using data matrix X directly") X = adata.X else: - if use_rep in adata.obsm.keys() and n_pcs is not None: + if use_rep in adata.obsm and n_pcs is not None: if n_pcs > adata.obsm[use_rep].shape[1]: raise ValueError( f"{use_rep} does not have enough Dimensions. Provide a " @@ -58,7 +58,7 @@ def _choose_representation( "`n_pcs` or lower `n_pcs` " ) X = adata.obsm[use_rep][:, :n_pcs] - elif use_rep in adata.obsm.keys() and n_pcs is None: + elif use_rep in adata.obsm and n_pcs is None: X = adata.obsm[use_rep] elif use_rep == "X": X = adata.X diff --git a/tests/notebooks/test_paga_paul15_subsampled.py b/tests/notebooks/test_paga_paul15_subsampled.py index 6d4ee886ba..9ce6ea8319 100644 --- a/tests/notebooks/test_paga_paul15_subsampled.py +++ b/tests/notebooks/test_paga_paul15_subsampled.py @@ -129,7 +129,7 @@ def test_paga_paul15_subsampled(image_comparer, plt): left_margin=0.15, n_avg=50, annotations=["distance"], - show_yticks=True if ipath == 0 else False, + show_yticks=ipath == 0, show_colorbar=False, color_map="Greys", color_maps_annotations={"distance": "viridis"}, diff --git a/tests/test_highly_variable_genes.py b/tests/test_highly_variable_genes.py index f3b9298505..cdd5238c70 100644 --- a/tests/test_highly_variable_genes.py +++ b/tests/test_highly_variable_genes.py @@ -255,7 +255,7 @@ def test_pearson_residuals_general( "residual_variances", "highly_variable_rank", ]: - assert key in output_df.keys() + assert key in output_df.columns # check consistency with normalization method if subset: @@ -324,7 +324,7 @@ def test_pearson_residuals_batch(pbmc3k_parametrized_small, subset, n_top_genes) "highly_variable_nbatches", "highly_variable_intersection", ]: - assert key in output_df.keys() + assert key in output_df.columns # general checks on ranks, hvg flag and residual variance _check_pearson_hvg_columns(output_df, n_top_genes) diff --git a/tests/test_plotting.py b/tests/test_plotting.py index 92eb61c252..b34db78780 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -1590,11 +1590,13 @@ def test_color_cycler(caplog): colors = sns.color_palette("deep") cyl = sns.rcmod.cycler("color", sns.color_palette("deep")) - with caplog.at_level(logging.WARNING): - with plt.rc_context({"axes.prop_cycle": cyl, "patch.facecolor": colors[0]}): - sc.pl.umap(pbmc, color="phase") - plt.show() - plt.close() + with ( + caplog.at_level(logging.WARNING), + plt.rc_context({"axes.prop_cycle": cyl, "patch.facecolor": colors[0]}), + ): + sc.pl.umap(pbmc, color="phase") + plt.show() + plt.close() assert caplog.text == "" diff --git a/tests/test_rank_genes_groups_logreg.py b/tests/test_rank_genes_groups_logreg.py index 3cc294487e..618de375f7 100644 --- a/tests/test_rank_genes_groups_logreg.py +++ b/tests/test_rank_genes_groups_logreg.py @@ -40,7 +40,7 @@ def test_rank_genes_groups_with_renamed_categories_use_rep(): assert adata.uns["rank_genes_groups"]["names"][0].tolist() == ("1", "3", "0") sc.tl.rank_genes_groups(adata, "blobs", method="logreg") - assert not adata.uns["rank_genes_groups"]["names"][0].tolist() == ("3", "1", "0") + assert adata.uns["rank_genes_groups"]["names"][0].tolist() != ("3", "1", "0") def test_rank_genes_groups_with_unsorted_groups(): diff --git a/tests/test_scaling.py b/tests/test_scaling.py index fad2443dc1..0ad62bbc7d 100644 --- a/tests/test_scaling.py +++ b/tests/test_scaling.py @@ -120,7 +120,7 @@ def test_mask_string(): adata.obs["some cells"] = np.array((0, 0, 1, 1, 1, 0, 0), dtype=bool) sc.pp.scale(adata, mask_obs="some cells") assert np.array_equal(adata.X, X_centered_for_mask) - assert "mean of some cells" in adata.var.keys() + assert "mean of some cells" in adata.var.columns @pytest.mark.parametrize("zero_center", [True, False]) From fb2d8d5668570684da67feacd976ba14e1f1a675 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 26 Sep 2024 16:13:50 +0200 Subject: [PATCH 052/118] Fix compat typing and old_positionals usage (#3264) --- docs/release-notes/3264.bugfix.md | 1 + pyproject.toml | 1 + src/scanpy/_compat.py | 32 ++++++++++++++----- src/scanpy/neighbors/__init__.py | 3 +- src/scanpy/plotting/_baseplot_class.py | 7 ++-- src/scanpy/plotting/_preprocessing.py | 3 +- .../preprocessing/_deprecated/__init__.py | 5 +-- .../_deprecated/highly_variable_genes.py | 4 +-- src/scanpy/preprocessing/_simple.py | 9 ++++-- src/scanpy/readwrite.py | 3 +- src/scanpy/tools/_ingest.py | 5 ++- 11 files changed, 45 insertions(+), 28 deletions(-) create mode 100644 docs/release-notes/3264.bugfix.md diff --git a/docs/release-notes/3264.bugfix.md b/docs/release-notes/3264.bugfix.md new file mode 100644 index 0000000000..0886ee6aa3 --- /dev/null +++ b/docs/release-notes/3264.bugfix.md @@ -0,0 +1 @@ +Switched all compatibility adapters for positional parameters to {exc}`FutureWarning` {smaller}`P Angerer` diff --git a/pyproject.toml b/pyproject.toml index 355c4ff483..b13631fe9b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -259,6 +259,7 @@ required-imports = ["from __future__ import annotations"] "pytest.importorskip".msg = "Use the “@needs” decorator/mark instead" "pandas.api.types.is_categorical_dtype".msg = "Use isinstance(s.dtype, CategoricalDtype) instead" "pandas.value_counts".msg = "Use pd.Series(a).value_counts() instead" +"legacy_api_wrap.legacy_api".msg = "Use scanpy._compat.old_positionals instead" [tool.ruff.lint.flake8-type-checking] exempt-modules = [] strict = true diff --git a/src/scanpy/_compat.py b/src/scanpy/_compat.py index 4af24fd6a9..e247524c31 100644 --- a/src/scanpy/_compat.py +++ b/src/scanpy/_compat.py @@ -3,22 +3,30 @@ import sys from dataclasses import dataclass, field from functools import cache, partial +from importlib.util import find_spec from pathlib import Path +from typing import TYPE_CHECKING -from legacy_api_wrap import legacy_api from packaging.version import Version -try: +if TYPE_CHECKING: + from importlib.metadata import PackageMetadata + + +if TYPE_CHECKING: + # type checkers are confused and can only see …core.Array + from dask.array.core import Array as DaskArray +elif find_spec("dask"): from dask.array import Array as DaskArray -except ImportError: +else: class DaskArray: pass -try: +if find_spec("zappy") or TYPE_CHECKING: from zappy.base import ZappyArray -except ImportError: +else: class ZappyArray: pass @@ -60,17 +68,25 @@ def __exit__(self, *_excinfo) -> None: os.chdir(self._old_cwd.pop()) -def pkg_metadata(package): +def pkg_metadata(package: str) -> PackageMetadata: from importlib.metadata import metadata return metadata(package) @cache -def pkg_version(package): +def pkg_version(package: str) -> Version: from importlib.metadata import version return Version(version(package)) -old_positionals = partial(legacy_api, category=FutureWarning) +if find_spec("legacy_api_wrap") or TYPE_CHECKING: + from legacy_api_wrap import legacy_api # noqa: TID251 + + old_positionals = partial(legacy_api, category=FutureWarning) +else: + # legacy_api_wrap is currently a hard dependency, + # but this code makes it possible to run scanpy without it. + def old_positionals(*old_positionals: str): + return lambda func: func diff --git a/src/scanpy/neighbors/__init__.py b/src/scanpy/neighbors/__init__.py index 64b14cf112..b98e7d4458 100644 --- a/src/scanpy/neighbors/__init__.py +++ b/src/scanpy/neighbors/__init__.py @@ -9,7 +9,6 @@ import numpy as np import scipy -from legacy_api_wrap import legacy_api from scipy.sparse import issparse from sklearn.utils import check_random_state @@ -711,7 +710,7 @@ def _handle_transformer( # else `transformer` is probably an instance return conn_method, transformer, shortcut - @legacy_api("density_normalize") + @old_positionals("density_normalize") def compute_transitions(self, *, density_normalize: bool = True): """\ Compute transition matrix. diff --git a/src/scanpy/plotting/_baseplot_class.py b/src/scanpy/plotting/_baseplot_class.py index e68cc07727..23e74505b1 100644 --- a/src/scanpy/plotting/_baseplot_class.py +++ b/src/scanpy/plotting/_baseplot_class.py @@ -7,7 +7,6 @@ from warnings import warn import numpy as np -from legacy_api_wrap import legacy_api from matplotlib import gridspec from matplotlib import pyplot as plt @@ -206,7 +205,7 @@ def __init__( self.ax_dict = None self.ax = ax - @legacy_api("swap_axes") + @old_positionals("swap_axes") def swap_axes(self, *, swap_axes: bool | None = True) -> Self: """ Plots a transposed image. @@ -234,7 +233,7 @@ def swap_axes(self, *, swap_axes: bool | None = True) -> Self: self.are_axes_swapped = swap_axes return self - @legacy_api("show", "dendrogram_key", "size") + @old_positionals("show", "dendrogram_key", "size") def add_dendrogram( self, *, @@ -321,7 +320,7 @@ def add_dendrogram( } return self - @legacy_api("show", "sort", "size", "color") + @old_positionals("show", "sort", "size", "color") def add_totals( self, *, diff --git a/src/scanpy/plotting/_preprocessing.py b/src/scanpy/plotting/_preprocessing.py index f2fd1c6d66..e6c7808be1 100644 --- a/src/scanpy/plotting/_preprocessing.py +++ b/src/scanpy/plotting/_preprocessing.py @@ -3,7 +3,6 @@ import numpy as np import pandas as pd from anndata import AnnData -from legacy_api_wrap import legacy_api from matplotlib import pyplot as plt from matplotlib import rcParams @@ -104,7 +103,7 @@ def highly_variable_genes( # backwards compat -@legacy_api("log", "show", "save") +@old_positionals("log", "show", "save") def filter_genes_dispersion( result: np.recarray, *, diff --git a/src/scanpy/preprocessing/_deprecated/__init__.py b/src/scanpy/preprocessing/_deprecated/__init__.py index 7cd7520171..c23361631a 100644 --- a/src/scanpy/preprocessing/_deprecated/__init__.py +++ b/src/scanpy/preprocessing/_deprecated/__init__.py @@ -1,11 +1,12 @@ from __future__ import annotations import numpy as np -from legacy_api_wrap import legacy_api from scipy.sparse import csr_matrix, issparse +from ..._compat import old_positionals -@legacy_api("max_fraction", "mult_with_mean") + +@old_positionals("max_fraction", "mult_with_mean") def normalize_per_cell_weinreb16_deprecated( x: np.ndarray, *, diff --git a/src/scanpy/preprocessing/_deprecated/highly_variable_genes.py b/src/scanpy/preprocessing/_deprecated/highly_variable_genes.py index ab75346127..f2c3ce971b 100644 --- a/src/scanpy/preprocessing/_deprecated/highly_variable_genes.py +++ b/src/scanpy/preprocessing/_deprecated/highly_variable_genes.py @@ -6,10 +6,10 @@ import numpy as np import pandas as pd from anndata import AnnData -from legacy_api_wrap import legacy_api from scipy.sparse import issparse from ... import logging as logg +from ..._compat import old_positionals from .._distributed import materialize_as_ndarray from .._utils import _get_mean_var @@ -19,7 +19,7 @@ from scipy.sparse import spmatrix -@legacy_api( +@old_positionals( "flavor", "min_disp", "max_disp", diff --git a/src/scanpy/preprocessing/_simple.py b/src/scanpy/preprocessing/_simple.py index e18773d843..495ec08aad 100644 --- a/src/scanpy/preprocessing/_simple.py +++ b/src/scanpy/preprocessing/_simple.py @@ -13,7 +13,6 @@ import numpy as np import scipy as sp from anndata import AnnData -from legacy_api_wrap import legacy_api from pandas.api.types import CategoricalDtype from scipy.sparse import csr_matrix, issparse, isspmatrix_csr, spmatrix from sklearn.utils import check_array, sparsefuncs @@ -544,7 +543,7 @@ def sqrt( return X.sqrt() -@legacy_api( +@old_positionals( "counts_per_cell_after", "counts_per_cell", "key_n_counts", @@ -647,7 +646,11 @@ def normalize_per_cell( adata.obs[key_n_counts] = counts_per_cell adata._inplace_subset_obs(cell_subset) counts_per_cell = counts_per_cell[cell_subset] - normalize_per_cell(adata.X, counts_per_cell_after, counts_per_cell) + normalize_per_cell( + adata.X, + counts_per_cell_after=counts_per_cell_after, + counts_per_cell=counts_per_cell, + ) layers = adata.layers.keys() if layers == "all" else layers if use_rep == "after": diff --git a/src/scanpy/readwrite.py b/src/scanpy/readwrite.py index 9e0a298e18..b24380fe16 100644 --- a/src/scanpy/readwrite.py +++ b/src/scanpy/readwrite.py @@ -20,7 +20,6 @@ read_mtx, read_text, ) -from legacy_api_wrap import legacy_api from matplotlib.image import imread from . import logging as logg @@ -673,7 +672,7 @@ def write( # ------------------------------------------------------------------------------- -@legacy_api("as_header") +@old_positionals("as_header") def read_params( filename: Path | str, *, as_header: bool = False ) -> dict[str, int | float | bool | str | None]: diff --git a/src/scanpy/tools/_ingest.py b/src/scanpy/tools/_ingest.py index 9ced418888..3698067035 100644 --- a/src/scanpy/tools/_ingest.py +++ b/src/scanpy/tools/_ingest.py @@ -5,7 +5,6 @@ import numpy as np import pandas as pd -from legacy_api_wrap import legacy_api from packaging.version import Version from scipy.sparse import issparse from sklearn.utils import check_random_state @@ -154,7 +153,7 @@ def ingest( ing.map_labels(col, labeling_method[i]) logg.info(" finished", time=start) - return ing.to_adata(inplace) + return ing.to_adata(inplace=inplace) def _rp_forest_generate( @@ -464,7 +463,7 @@ def map_labels(self, labels, method): else: raise NotImplementedError("Ingest supports knn labeling for now.") - @legacy_api("inplace") + @old_positionals("inplace") def to_adata(self, *, inplace: bool = False) -> AnnData | None: """\ Returns `adata_new` with mapped embeddings and labels. From 5dd2d091436ea7883591d6d7ec5ee0c3ab31d8a2 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Mon, 30 Sep 2024 15:53:46 +0200 Subject: [PATCH 053/118] Split up PCA tests (#3268) --- tests/test_pca.py | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/tests/test_pca.py b/tests/test_pca.py index bebb752998..7e49c49cfb 100644 --- a/tests/test_pca.py +++ b/tests/test_pca.py @@ -1,6 +1,7 @@ from __future__ import annotations import warnings +from contextlib import nullcontext from functools import wraps from typing import TYPE_CHECKING @@ -190,19 +191,27 @@ def test_pca_warnings_sparse(): def test_pca_transform(array_type): - A = array_type(A_list).astype("float32") + adata = AnnData(array_type(A_list).astype("float32")) A_pca_abs = np.abs(A_pca) - A_svd_abs = np.abs(A_svd) - - adata = AnnData(A) - with warnings.catch_warnings(record=True) as record: - sc.pp.pca(adata, n_comps=4, zero_center=True, dtype="float64") - assert len(record) == 0, record + warnings.filterwarnings("error") + sc.pp.pca(adata, n_comps=4, zero_center=True, dtype="float64") assert np.linalg.norm(A_pca_abs[:, :4] - np.abs(adata.obsm["X_pca"])) < 2e-05 - with warnings.catch_warnings(record=True) as record: + +def test_pca_transform_randomized(array_type): + adata = AnnData(array_type(A_list).astype("float32")) + A_pca_abs = np.abs(A_pca) + + warnings.filterwarnings("error") + with ( + pytest.warns( + UserWarning, match="svd_solver 'randomized' does not work with sparse input" + ) + if sparse.issparse(adata.X) + else nullcontext() + ): sc.pp.pca( adata, n_comps=5, @@ -211,21 +220,16 @@ def test_pca_transform(array_type): dtype="float64", random_state=14, ) - if sparse.issparse(A): - assert any( - isinstance(r.message, UserWarning) - and "svd_solver 'randomized' does not work with sparse input" - in str(r.message) - for r in record - ) - else: - assert len(record) == 0 assert np.linalg.norm(A_pca_abs - np.abs(adata.obsm["X_pca"])) < 2e-05 - with warnings.catch_warnings(record=True) as record: - sc.pp.pca(adata, n_comps=4, zero_center=False, dtype="float64", random_state=14) - assert len(record) == 0 + +def test_pca_transform_no_zero_center(array_type): + adata = AnnData(array_type(A_list).astype("float32")) + A_svd_abs = np.abs(A_svd) + + warnings.filterwarnings("error") + sc.pp.pca(adata, n_comps=4, zero_center=False, dtype="float64", random_state=14) assert np.linalg.norm(A_svd_abs[:, :4] - np.abs(adata.obsm["X_pca"])) < 2e-05 From b54822f84f1f47183dc647c8f38b1a603c41e078 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 13:23:25 +0200 Subject: [PATCH 054/118] [pre-commit.ci] pre-commit autoupdate (#3270) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- src/scanpy/plotting/_anndata.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a09eb15442..cd0dd7072f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.7 + rev: v0.6.8 hooks: - id: ruff types_or: [python, pyi, jupyter] diff --git a/src/scanpy/plotting/_anndata.py b/src/scanpy/plotting/_anndata.py index 5dfea0ae29..b72ccfc99d 100755 --- a/src/scanpy/plotting/_anndata.py +++ b/src/scanpy/plotting/_anndata.py @@ -826,7 +826,7 @@ def violin( if groupby is not None: obs_df = get.obs_df(adata, keys=[groupby] + keys, layer=layer, use_raw=use_raw) - if kwds.get("palette", None) is None: + if kwds.get("palette") is None: if not isinstance(adata.obs[groupby].dtype, CategoricalDtype): raise ValueError( f"The column `adata.obs[{groupby!r}]` needs to be categorical, " From 5bdf30567647140993647c69e62bcd345b7cfd4b Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Tue, 15 Oct 2024 11:11:32 +0200 Subject: [PATCH 055/118] Remove 3.9 support (#3283) --- .azure-pipelines.yml | 6 +++--- benchmarks/asv.conf.json | 2 +- docs/release-notes/3283.breaking.md | 1 + hatch.toml | 2 +- pyproject.toml | 7 +++---- src/scanpy/_settings.py | 12 ++++++------ src/scanpy/_utils/__init__.py | 20 ++++++++++---------- src/scanpy/external/pl.py | 4 ++-- src/scanpy/external/pp/_bbknn.py | 2 +- src/scanpy/external/pp/_magic.py | 3 ++- src/scanpy/external/tl/_pypairs.py | 3 +-- src/scanpy/get/_aggregated.py | 3 +-- src/scanpy/neighbors/__init__.py | 2 +- src/scanpy/neighbors/_types.py | 4 ++-- src/scanpy/plotting/_anndata.py | 9 +++++---- src/scanpy/plotting/_baseplot_class.py | 4 ++-- src/scanpy/plotting/_scrublet.py | 4 ++-- src/scanpy/plotting/_tools/paga.py | 6 +++--- src/scanpy/plotting/_tools/scatterplots.py | 6 +----- src/scanpy/plotting/_utils.py | 12 ++++++------ src/scanpy/preprocessing/_normalization.py | 2 +- src/scanpy/preprocessing/_scrublet/core.py | 11 ++--------- src/scanpy/tools/_rank_genes_groups.py | 2 +- src/testing/scanpy/_pytest/marks.py | 18 +++++++----------- tests/conftest.py | 4 ++-- tests/external/test_scanorama_integrate.py | 9 +-------- tests/test_highly_variable_genes.py | 3 ++- tests/test_normalization.py | 2 +- 28 files changed, 71 insertions(+), 92 deletions(-) create mode 100644 docs/release-notes/3283.breaking.md diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index e0e8faefd6..f0e181f1ba 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -15,8 +15,8 @@ jobs: vmImage: 'ubuntu-22.04' strategy: matrix: - Python3.9: - python.version: '3.9' + Python3.10: + python.version: '3.10' Python3.12: {} minimal_dependencies: TEST_EXTRA: 'test-min' @@ -24,7 +24,7 @@ jobs: DEPENDENCIES_VERSION: "pre-release" TEST_TYPE: "coverage" minimum_versions: - python.version: '3.9' + python.version: '3.10' DEPENDENCIES_VERSION: "minimum-version" TEST_TYPE: "coverage" diff --git a/benchmarks/asv.conf.json b/benchmarks/asv.conf.json index 26591b490d..98192b3725 100644 --- a/benchmarks/asv.conf.json +++ b/benchmarks/asv.conf.json @@ -54,7 +54,7 @@ // The Pythons you'd like to test against. If not provided, defaults // to the current version of Python used to run `asv`. - // "pythons": ["3.9", "3.12"], + // "pythons": ["3.10", "3.12"], // The list of conda channel names to be searched for benchmark // dependency packages in the specified order diff --git a/docs/release-notes/3283.breaking.md b/docs/release-notes/3283.breaking.md new file mode 100644 index 0000000000..6f391f325d --- /dev/null +++ b/docs/release-notes/3283.breaking.md @@ -0,0 +1 @@ +Remove Python 3.9 support {smaller}`P Angerer` diff --git a/hatch.toml b/hatch.toml index 77c1c92b1f..705b003bb6 100644 --- a/hatch.toml +++ b/hatch.toml @@ -22,7 +22,7 @@ overrides.matrix.deps.env-vars = [ { if = ["min"], key = "UV_RESOLUTION", value = "lowest-direct" }, ] overrides.matrix.deps.python = [ - { if = ["min"] , value = "3.9" }, + { if = ["min"] , value = "3.10" }, { if = ["stable", "full", "pre"], value = "3.12" }, ] overrides.matrix.deps.features = [ diff --git a/pyproject.toml b/pyproject.toml index b13631fe9b..1d78652993 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ requires = ["hatchling", "hatch-vcs"] [project] name = "scanpy" description = "Single-Cell Analysis in Python." -requires-python = ">=3.9" +requires-python = ">=3.10" license = "BSD-3-clause" authors = [ {name = "Alex Wolf"}, @@ -39,7 +39,6 @@ classifiers = [ "Operating System :: Microsoft :: Windows", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", @@ -53,9 +52,9 @@ dependencies = [ "pandas >=1.5", "scipy>=1.8", "seaborn>=0.13", - "h5py>=3.1", + "h5py>=3.6", "tqdm", - "scikit-learn>=0.24", + "scikit-learn>=1.1", "statsmodels>=0.13", "patsy", "networkx>=2.7", diff --git a/src/scanpy/_settings.py b/src/scanpy/_settings.py index 63f91d2279..fa44fc8492 100644 --- a/src/scanpy/_settings.py +++ b/src/scanpy/_settings.py @@ -15,14 +15,14 @@ if TYPE_CHECKING: from collections.abc import Generator, Iterable - from typing import Any, Literal, TextIO, Union + from typing import Any, Literal, TextIO # Collected from the print_* functions in matplotlib.backends - _Format = Union[ - Literal["png", "jpg", "tif", "tiff"], - Literal["pdf", "ps", "eps", "svg", "svgz", "pgf"], - Literal["raw", "rgba"], - ] + _Format = ( + Literal["png", "jpg", "tif", "tiff"] + | Literal["pdf", "ps", "eps", "svg", "svgz", "pgf"] + | Literal["raw", "rgba"] + ) _VERBOSITY_TO_LOGLEVEL = { "error": "ERROR", diff --git a/src/scanpy/_utils/__init__.py b/src/scanpy/_utils/__init__.py index b8513d87ba..883f8b97b9 100644 --- a/src/scanpy/_utils/__init__.py +++ b/src/scanpy/_utils/__init__.py @@ -19,7 +19,7 @@ from operator import mul, truediv from textwrap import dedent from types import MethodType, ModuleType -from typing import TYPE_CHECKING, Union, overload +from typing import TYPE_CHECKING, overload from weakref import WeakSet import h5py @@ -42,9 +42,9 @@ from anndata._core.sparse_dataset import SparseDataset if TYPE_CHECKING: - from collections.abc import Mapping + from collections.abc import Callable, Mapping from pathlib import Path - from typing import Any, Callable, Literal, TypeVar + from typing import Any, Literal, TypeVar from anndata import AnnData from numpy.typing import DTypeLike, NDArray @@ -54,7 +54,7 @@ # e.g. https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html # maybe in the future random.Generator -AnyRandom = Union[int, np.random.RandomState, None] +AnyRandom = int | np.random.RandomState | None class Empty(Enum): @@ -538,9 +538,9 @@ def update_params( if TYPE_CHECKING: - _SparseMatrix = Union[sparse.csr_matrix, sparse.csc_matrix] - _MemoryArray = Union[NDArray, _SparseMatrix] - _SupportedArray = Union[_MemoryArray, DaskArray] + _SparseMatrix = sparse.csr_matrix | sparse.csc_matrix + _MemoryArray = NDArray | _SparseMatrix + _SupportedArray = _MemoryArray | DaskArray @singledispatch @@ -750,8 +750,8 @@ def _( def sum_drop_keepdims(*args, **kwargs): kwargs.pop("computing_meta", None) # masked operations on sparse produce which numpy matrices gives the same API issues handled here - if isinstance(X._meta, (sparse.spmatrix, np.matrix)) or isinstance( - args[0], (sparse.spmatrix, np.matrix) + if isinstance(X._meta, sparse.spmatrix | np.matrix) or isinstance( + args[0], sparse.spmatrix | np.matrix ): kwargs.pop("keepdims", None) axis = kwargs["axis"] @@ -1110,7 +1110,7 @@ def _resolve_axis( def is_backed_type(X: object) -> bool: - return isinstance(X, (SparseDataset, h5py.File, h5py.Dataset)) + return isinstance(X, SparseDataset | h5py.File | h5py.Dataset) def raise_not_implemented_error_if_backed_type(X: object, method_name: str) -> None: diff --git a/src/scanpy/external/pl.py b/src/scanpy/external/pl.py index a3d1767cee..a6ad48f718 100644 --- a/src/scanpy/external/pl.py +++ b/src/scanpy/external/pl.py @@ -218,7 +218,7 @@ def sam( with contextlib.suppress(KeyError): c = np.array(list(adata.obs[c])) - if isinstance(c[0], (str, np.str_)) and isinstance(c, (np.ndarray, list)): + if isinstance(c[0], str | np.str_) and isinstance(c, np.ndarray | list): import samalg.utilities as ut i = ut.convert_annotations(c) @@ -238,7 +238,7 @@ def sam( cbar = plt.colorbar(cax, ax=axes, ticks=ui) cbar.ax.set_yticklabels(c[ai]) else: - if not isinstance(c, (np.ndarray, list)): + if not isinstance(c, np.ndarray | list): colorbar = False i = c diff --git a/src/scanpy/external/pp/_bbknn.py b/src/scanpy/external/pp/_bbknn.py index 4a7d5e7c9b..07d6e41f93 100644 --- a/src/scanpy/external/pp/_bbknn.py +++ b/src/scanpy/external/pp/_bbknn.py @@ -6,7 +6,7 @@ from ..._utils._doctests import doctest_needs if TYPE_CHECKING: - from typing import Callable + from collections.abc import Callable from anndata import AnnData from sklearn.metrics import DistanceMetric diff --git a/src/scanpy/external/pp/_magic.py b/src/scanpy/external/pp/_magic.py index 983db18fcf..fd4b19667d 100644 --- a/src/scanpy/external/pp/_magic.py +++ b/src/scanpy/external/pp/_magic.py @@ -4,6 +4,7 @@ from __future__ import annotations +from types import NoneType from typing import TYPE_CHECKING from packaging.version import Version @@ -155,7 +156,7 @@ def magic( ) start = logg.info("computing MAGIC") - all_or_pca = isinstance(name_list, (str, type(None))) + all_or_pca = isinstance(name_list, str | NoneType) if all_or_pca and name_list not in {"all_genes", "pca_only", None}: raise ValueError( "Invalid string value for `name_list`: " diff --git a/src/scanpy/external/tl/_pypairs.py b/src/scanpy/external/tl/_pypairs.py index 821a060a4d..255334fe7a 100644 --- a/src/scanpy/external/tl/_pypairs.py +++ b/src/scanpy/external/tl/_pypairs.py @@ -13,12 +13,11 @@ if TYPE_CHECKING: from collections.abc import Collection, Mapping - from typing import Union import pandas as pd from anndata import AnnData - Genes = Collection[Union[str, int, bool]] + Genes = Collection[str | int | bool] @doctest_needs("pypairs") diff --git a/src/scanpy/get/_aggregated.py b/src/scanpy/get/_aggregated.py index 5318244af2..e95fedf9dc 100644 --- a/src/scanpy/get/_aggregated.py +++ b/src/scanpy/get/_aggregated.py @@ -14,11 +14,10 @@ if TYPE_CHECKING: from collections.abc import Collection, Iterable - from typing import Union from numpy.typing import NDArray - Array = Union[np.ndarray, sparse.csc_matrix, sparse.csr_matrix] + Array = np.ndarray | sparse.csc_matrix | sparse.csr_matrix # Used with get_args AggType = Literal["count_nonzero", "mean", "sum", "var", "median"] diff --git a/src/scanpy/neighbors/__init__.py b/src/scanpy/neighbors/__init__.py index b98e7d4458..7b1c3f2506 100644 --- a/src/scanpy/neighbors/__init__.py +++ b/src/scanpy/neighbors/__init__.py @@ -312,7 +312,7 @@ def __init__( self.restrict_array = restrict_array # restrict the array to a subset def __getitem__(self, index): - if isinstance(index, (int, np.integer)): + if isinstance(index, int | np.integer): if self.restrict_array is None: glob_index = index else: diff --git a/src/scanpy/neighbors/_types.py b/src/scanpy/neighbors/_types.py index 35e4c154cb..d98ec76af3 100644 --- a/src/scanpy/neighbors/_types.py +++ b/src/scanpy/neighbors/_types.py @@ -1,7 +1,7 @@ from __future__ import annotations from collections.abc import Callable -from typing import TYPE_CHECKING, Literal, Protocol, Union +from typing import TYPE_CHECKING, Literal, Protocol import numpy as np @@ -42,7 +42,7 @@ "sqeuclidean", "yule", ] -_Metric = Union[_MetricSparseCapable, _MetricScipySpatial] +_Metric = _MetricSparseCapable | _MetricScipySpatial class KnnTransformerLike(Protocol): diff --git a/src/scanpy/plotting/_anndata.py b/src/scanpy/plotting/_anndata.py index b72ccfc99d..aadd0ac6ac 100755 --- a/src/scanpy/plotting/_anndata.py +++ b/src/scanpy/plotting/_anndata.py @@ -5,6 +5,7 @@ from collections import OrderedDict from collections.abc import Collection, Mapping, Sequence from itertools import product +from types import NoneType from typing import TYPE_CHECKING, get_args import matplotlib as mpl @@ -40,7 +41,7 @@ if TYPE_CHECKING: from collections.abc import Iterable - from typing import Literal, Union + from typing import Literal from anndata import AnnData from cycler import Cycler @@ -60,7 +61,7 @@ # TODO: is that all? _Basis = Literal["pca", "tsne", "umap", "diffmap", "draw_graph_fr"] - _VarNames = Union[str, Sequence[str]] + _VarNames = str | Sequence[str] VALID_LEGENDLOCS = frozenset(get_args(_utils._LegendLoc)) @@ -811,7 +812,7 @@ def violin( density_norm = _deprecated_scale(density_norm, scale, default="width") del scale - if isinstance(ylabel, (str, type(None))): + if isinstance(ylabel, str | NoneType): ylabel = [ylabel] * (1 if groupby is None else len(keys)) if groupby is None: if len(ylabel) != 1: @@ -992,7 +993,7 @@ def clustermap( """ import seaborn as sns # Slow import, only import if called - if not isinstance(obs_keys, (str, type(None))): + if not isinstance(obs_keys, str | NoneType): raise ValueError("Currently, only a single key is supported.") sanitize_anndata(adata) use_raw = _check_use_raw(adata, use_raw) diff --git a/src/scanpy/plotting/_baseplot_class.py b/src/scanpy/plotting/_baseplot_class.py index 23e74505b1..fff1b40322 100644 --- a/src/scanpy/plotting/_baseplot_class.py +++ b/src/scanpy/plotting/_baseplot_class.py @@ -18,7 +18,7 @@ if TYPE_CHECKING: from collections.abc import Iterable, Sequence - from typing import Literal, Self, Union + from typing import Literal, Self import pandas as pd from anndata import AnnData @@ -28,7 +28,7 @@ from .._utils import Empty from ._utils import ColorLike, _AxesSubplot - _VarNames = Union[str, Sequence[str]] + _VarNames = str | Sequence[str] class VBoundNorm(NamedTuple): diff --git a/src/scanpy/plotting/_scrublet.py b/src/scanpy/plotting/_scrublet.py index 66e33e2e82..4a1247574d 100644 --- a/src/scanpy/plotting/_scrublet.py +++ b/src/scanpy/plotting/_scrublet.py @@ -11,13 +11,13 @@ if TYPE_CHECKING: from collections.abc import Sequence - from typing import Literal, Union + from typing import Literal from anndata import AnnData from matplotlib.axes import Axes from matplotlib.figure import Figure - Scale = Union[Literal["linear", "log", "symlog", "logit"], str] + Scale = Literal["linear", "log", "symlog", "logit"] | str @old_positionals( diff --git a/src/scanpy/plotting/_tools/paga.py b/src/scanpy/plotting/_tools/paga.py index 159be79913..29408735b6 100644 --- a/src/scanpy/plotting/_tools/paga.py +++ b/src/scanpy/plotting/_tools/paga.py @@ -26,7 +26,7 @@ from .._utils import matrix if TYPE_CHECKING: - from typing import Any, Literal, Union + from typing import Any, Literal from anndata import AnnData from matplotlib.axes import Axes @@ -36,7 +36,7 @@ from ...tools._draw_graph import _Layout as _LayoutWithoutEqTree from .._utils import _FontSize, _FontWeight, _LegendLoc - _Layout = Union[_LayoutWithoutEqTree, Literal["eq_tree"]] + _Layout = _LayoutWithoutEqTree | Literal["eq_tree"] @old_positionals( @@ -725,7 +725,7 @@ def _paga_graph( nx_g_dashed = nx.Graph(adjacency_dashed) # convert pos to array and dict - if not isinstance(pos, (Path, str)): + if not isinstance(pos, Path | str): pos_array = pos else: pos = Path(pos) diff --git a/src/scanpy/plotting/_tools/scatterplots.py b/src/scanpy/plotting/_tools/scatterplots.py index 5c15fa8df4..7f69a76025 100644 --- a/src/scanpy/plotting/_tools/scatterplots.py +++ b/src/scanpy/plotting/_tools/scatterplots.py @@ -1,7 +1,6 @@ from __future__ import annotations import inspect -import sys from collections.abc import Mapping, Sequence # noqa: TCH003 from copy import copy from functools import partial @@ -217,7 +216,7 @@ def embedding( # set as ndarray if ( size is not None - and isinstance(size, (Sequence, pd.Series, np.ndarray)) + and isinstance(size, Sequence | pd.Series | np.ndarray) and len(size) == adata.shape[0] ): size = np.array(size, dtype=float) @@ -593,9 +592,6 @@ def my_vmax(colors): np.percentile(colors, p=80) def _wraps_plot_scatter(wrapper): """Update the wrapper function to use the correct signature.""" - if sys.version_info < (3, 10): - # Python 3.9 does not support `eval_str`, so we only support this in 3.10+ - return wrapper params = inspect.signature(embedding, eval_str=True).parameters.copy() wrapper_sig = inspect.signature(wrapper, eval_str=True) diff --git a/src/scanpy/plotting/_utils.py b/src/scanpy/plotting/_utils.py index 13832658f5..09a01a9bc5 100644 --- a/src/scanpy/plotting/_utils.py +++ b/src/scanpy/plotting/_utils.py @@ -1,8 +1,8 @@ from __future__ import annotations import warnings -from collections.abc import Mapping, Sequence -from typing import TYPE_CHECKING, Callable, Literal, TypedDict, Union, overload +from collections.abc import Callable, Mapping, Sequence +from typing import TYPE_CHECKING, Literal, TypedDict, overload import matplotlib as mpl import numpy as np @@ -37,7 +37,7 @@ DensityNorm = Literal["area", "count", "width"] # These are needed by _wraps_plot_scatter -VBound = Union[str, float, Callable[[Sequence[float]], float]] +VBound = str | float | Callable[[Sequence[float]], float] _FontWeight = Literal["light", "normal", "medium", "semibold", "bold", "heavy", "black"] _FontSize = Literal[ "xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large" @@ -59,7 +59,7 @@ "upper center", "center", ] -ColorLike = Union[str, tuple[float, ...]] +ColorLike = str | tuple[float, ...] class _AxesSubplot(Axes, axes.SubplotBase): @@ -156,7 +156,7 @@ def timeseries_subplot( """ if color is not None: - use_color_map = isinstance(color[0], (float, np.floating)) + use_color_map = isinstance(color[0], float | np.floating) palette = default_palette(palette) x_range = np.arange(X.shape[0]) if time is None else time if X.ndim == 1: @@ -371,7 +371,7 @@ def default_palette( ) -> str | Cycler: if palette is None: return rcParams["axes.prop_cycle"] - elif not isinstance(palette, (str, Cycler)): + elif not isinstance(palette, str | Cycler): return cycler(color=palette) else: return palette diff --git a/src/scanpy/preprocessing/_normalization.py b/src/scanpy/preprocessing/_normalization.py index 686c69b224..c888ded9c6 100644 --- a/src/scanpy/preprocessing/_normalization.py +++ b/src/scanpy/preprocessing/_normalization.py @@ -28,7 +28,7 @@ def _normalize_data(X, counts, after=None, *, copy: bool = False): X = X.copy() if copy else X - if issubclass(X.dtype.type, (int, np.integer)): + if issubclass(X.dtype.type, int | np.integer): X = X.astype(np.float32) # TODO: Check if float64 should be used if after is None: if isinstance(counts, DaskArray): diff --git a/src/scanpy/preprocessing/_scrublet/core.py b/src/scanpy/preprocessing/_scrublet/core.py index 20d49eda04..4c992b2b64 100644 --- a/src/scanpy/preprocessing/_scrublet/core.py +++ b/src/scanpy/preprocessing/_scrublet/core.py @@ -1,6 +1,5 @@ from __future__ import annotations -import sys from dataclasses import InitVar, dataclass, field from typing import TYPE_CHECKING, cast @@ -28,13 +27,7 @@ __all__ = ["Scrublet"] -if sys.version_info > (3, 10): - kw_only = lambda yes: {"kw_only": yes} # noqa: E731 -else: - kw_only = lambda _: {} # noqa: E731 - - -@dataclass(**kw_only(True)) # noqa: FBT003 +@dataclass(kw_only=True) class Scrublet: """\ Initialize Scrublet object with counts matrix and doublet prediction parameters @@ -73,7 +66,7 @@ class Scrublet: # init fields counts_obs: InitVar[sparse.csr_matrix | sparse.csc_matrix | NDArray[np.integer]] = ( - field(**kw_only(False)) # noqa: FBT003 + field(kw_only=False) ) total_counts_obs: InitVar[NDArray[np.integer] | None] = None sim_doublet_ratio: float = 2.0 diff --git a/src/scanpy/tools/_rank_genes_groups.py b/src/scanpy/tools/_rank_genes_groups.py index 56b71d55eb..d864b01b88 100644 --- a/src/scanpy/tools/_rank_genes_groups.py +++ b/src/scanpy/tools/_rank_genes_groups.py @@ -620,7 +620,7 @@ def rank_genes_groups( # for clarity, rename variable if groups == "all": groups_order = "all" - elif isinstance(groups, (str, int)): + elif isinstance(groups, str | int): raise ValueError("Specify a sequence of groups") else: groups_order = list(groups) diff --git a/src/testing/scanpy/_pytest/marks.py b/src/testing/scanpy/_pytest/marks.py index c046dd7246..22b32269d2 100644 --- a/src/testing/scanpy/_pytest/marks.py +++ b/src/testing/scanpy/_pytest/marks.py @@ -1,6 +1,5 @@ from __future__ import annotations -import sys from enum import Enum, auto from importlib.util import find_spec from typing import TYPE_CHECKING @@ -29,11 +28,6 @@ def _skip_if_skmisc_too_old() -> str | None: SKIP_EXTRA["skmisc"] = _skip_if_skmisc_too_old -def _next_val(name: str, start: int, count: int, last_values: list[str]) -> str: - """Distribution name for matching modules""" - return name.replace("_", "-") - - class QuietMarkDecorator(pytest.MarkDecorator): def __init__(self, mark: pytest.Mark) -> None: super().__init__(mark, _ispytest=True) @@ -47,11 +41,13 @@ class needs(QuietMarkDecorator, Enum): :func:`pytest.importorskip` skips tests after they started running. """ - # _generate_next_value_ needs to come before members, also it’s finnicky: - # https://github.com/python/mypy/issues/7591#issuecomment-652800625 - _generate_next_value_ = ( - staticmethod(_next_val) if sys.version_info >= (3, 10) else _next_val - ) + # _generate_next_value_ needs to come before members + @staticmethod + def _generate_next_value_( + name: str, start: int, count: int, last_values: list[str] + ) -> str: + """Distribution name for matching modules""" + return name.replace("_", "-") mod: str diff --git a/tests/conftest.py b/tests/conftest.py index 52bc61168a..4cbe5ff53e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,7 +3,7 @@ import sys from pathlib import Path from textwrap import dedent -from typing import TYPE_CHECKING, TypedDict, Union, cast +from typing import TYPE_CHECKING, TypedDict, cast import pytest @@ -88,7 +88,7 @@ def fmt_descr(descr): return f"{descr} ({basename})" if basename else descr result = cast( - Union[CompareResult, None], + CompareResult | None, compare_images(str(expected), str(actual), tol=tol, in_decorator=True), ) if result is None: diff --git a/tests/external/test_scanorama_integrate.py b/tests/external/test_scanorama_integrate.py index 19a53a4d27..baa2007fc0 100644 --- a/tests/external/test_scanorama_integrate.py +++ b/tests/external/test_scanorama_integrate.py @@ -1,18 +1,11 @@ from __future__ import annotations -import sys - -import pytest - import scanpy as sc import scanpy.external as sce from testing.scanpy._helpers.data import pbmc68k_reduced from testing.scanpy._pytest.marks import needs -pytestmark = [ - needs.scanorama, - pytest.mark.skipif(sys.version_info < (3, 10), reason="annoy is unstable on 3.9"), -] +pytestmark = [needs.scanorama] def test_scanorama_integrate(): diff --git a/tests/test_highly_variable_genes.py b/tests/test_highly_variable_genes.py index cdd5238c70..0f08b853e0 100644 --- a/tests/test_highly_variable_genes.py +++ b/tests/test_highly_variable_genes.py @@ -20,7 +20,8 @@ from testing.scanpy._pytest.params import ARRAY_TYPES if TYPE_CHECKING: - from typing import Callable, Literal + from collections.abc import Callable + from typing import Literal FILE = Path(__file__).parent / Path("_scripts/seurat_hvg.csv") FILE_V3 = Path(__file__).parent / Path("_scripts/seurat_hvg_v3.csv.gz") diff --git a/tests/test_normalization.py b/tests/test_normalization.py index 2527c997db..3acefe1bb1 100644 --- a/tests/test_normalization.py +++ b/tests/test_normalization.py @@ -239,7 +239,7 @@ def test_normalize_pearson_residuals_pca( np.repeat(True, n_unmasked), np.repeat(False, n_genes - n_unmasked) # noqa: FBT003 ] n_var_copy = locals()[n_var_copy_name] - assert isinstance(n_var_copy, (int, np.integer)) + assert isinstance(n_var_copy, int | np.integer) if do_hvg: sc.experimental.pp.highly_variable_genes( From 66ee0c9c09302c1b7bcd776459e25b63789920e1 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Tue, 15 Oct 2024 16:05:27 +0200 Subject: [PATCH 056/118] =?UTF-8?q?Fix=20#3206=E2=80=99s=20release=20note?= =?UTF-8?q?=20(#3287)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/release-notes/3206.bugfix.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/release-notes/3206.bugfix.md b/docs/release-notes/3206.bugfix.md index d29c34300a..9e47d00b09 100644 --- a/docs/release-notes/3206.bugfix.md +++ b/docs/release-notes/3206.bugfix.md @@ -1 +1 @@ -Fix :meth:`scanpy.pl.DotPlot.style`, :meth:`scanpy.pl.MatrixPlot.style`, and :meth:`scanpy.pl.StackedViolin.style` resetting all non-specified parameters {smaller}`P Angerer` +Fix {meth}`scanpy.pl.DotPlot.style`, {meth}`scanpy.pl.MatrixPlot.style`, and {meth}`scanpy.pl.StackedViolin.style` resetting all non-specified parameters {smaller}`P Angerer` From b48bb972a07c78d9249ae8ce194d38816c064c72 Mon Sep 17 00:00:00 2001 From: Ilan Gold Date: Thu, 17 Oct 2024 15:00:11 +0200 Subject: [PATCH 057/118] (fix): conditional imports to avoid `anndata.io` warning (#3289) --- src/scanpy/__init__.py | 39 ++++++++++++++------- src/scanpy/readwrite.py | 33 +++++++++++------ src/testing/scanpy/_pytest/fixtures/data.py | 6 +++- tests/test_package_structure.py | 8 +++++ 4 files changed, 63 insertions(+), 23 deletions(-) diff --git a/src/scanpy/__init__.py b/src/scanpy/__init__.py index b9be00f8f3..ae56a974f3 100644 --- a/src/scanpy/__init__.py +++ b/src/scanpy/__init__.py @@ -4,6 +4,8 @@ import sys +from packaging.version import Version + try: # See https://github.com/maresb/hatch-vcs-footgun-example from setuptools_scm import get_version @@ -29,18 +31,31 @@ set_figure_params = settings.set_figure_params -from anndata import ( - AnnData, - concat, - read_csv, - read_excel, - read_h5ad, - read_hdf, - read_loom, - read_mtx, - read_text, - read_umi_tools, -) +import anndata + +if Version(anndata.__version__) >= Version("0.11.0rc0"): + from anndata.io import ( + read_csv, + read_excel, + read_h5ad, + read_hdf, + read_loom, + read_mtx, + read_text, + read_umi_tools, + ) +else: + from anndata import ( + read_csv, + read_excel, + read_h5ad, + read_hdf, + read_loom, + read_mtx, + read_text, + read_umi_tools, + ) +from anndata import AnnData, concat from . import datasets, experimental, external, get, logging, metrics, queries from . import plotting as pl diff --git a/src/scanpy/readwrite.py b/src/scanpy/readwrite.py index b24380fe16..3fbf8ef61c 100644 --- a/src/scanpy/readwrite.py +++ b/src/scanpy/readwrite.py @@ -10,16 +10,29 @@ import h5py import numpy as np import pandas as pd -from anndata import ( - AnnData, - read_csv, - read_excel, - read_h5ad, - read_hdf, - read_loom, - read_mtx, - read_text, -) +from packaging.version import Version + +if Version(anndata.__version__) >= Version("0.11.0rc0"): + from anndata.io import ( + read_csv, + read_excel, + read_h5ad, + read_hdf, + read_loom, + read_mtx, + read_text, + ) +else: + from anndata import ( + read_csv, + read_excel, + read_h5ad, + read_hdf, + read_loom, + read_mtx, + read_text, + ) +from anndata import AnnData from matplotlib.image import imread from . import logging as logg diff --git a/src/testing/scanpy/_pytest/fixtures/data.py b/src/testing/scanpy/_pytest/fixtures/data.py index d2be706076..4e5762f6cb 100644 --- a/src/testing/scanpy/_pytest/fixtures/data.py +++ b/src/testing/scanpy/_pytest/fixtures/data.py @@ -16,7 +16,11 @@ from anndata._core.sparse_dataset import ( BaseCompressedSparseDataset as SparseDataset, ) - from anndata.experimental import sparse_dataset + + if Version(anndata_version) >= Version("0.11.0rc0"): + from anndata.io import sparse_dataset + else: + from anndata.experimental import sparse_dataset def make_sparse(x): return sparse_dataset(x) diff --git a/tests/test_package_structure.py b/tests/test_package_structure.py index 19a6836e65..834c06d8b4 100644 --- a/tests/test_package_structure.py +++ b/tests/test_package_structure.py @@ -1,5 +1,6 @@ from __future__ import annotations +import importlib import os from collections import defaultdict from inspect import Parameter, signature @@ -69,6 +70,13 @@ def test_descend_classes_and_funcs(): assert {p.values[0] for p in api_functions} == funcs +@pytest.mark.filterwarnings("error::FutureWarning:.*Import anndata.*") +def test_import_future_anndata_import_warning(): + import scanpy + + importlib.reload(scanpy) + + @pytest.mark.parametrize(("f", "qualname"), api_functions) def test_function_headers(f, qualname): filename = getsourcefile(f) From 861c81ba87681869af489a12f284e9d9ba670c5e Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 17 Oct 2024 18:47:55 +0200 Subject: [PATCH 058/118] Fix benchmark job: Use upstream asv (#3292) --- .github/workflows/benchmark.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index f2de5e34df..68e274ad54 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -48,8 +48,7 @@ jobs: key: benchmark-state-${{ hashFiles('benchmarks/**') }} - name: Install dependencies - # TODO: revert once this PR is merged: https://github.com/airspeed-velocity/asv/pull/1397 - run: pip install 'asv @ git+https://github.com/ivirshup/asv@fix-conda-usage' + run: pip install 'asv>=0.6.4' - name: Configure ASV working-directory: ${{ env.ASV_DIR }} From fead3b5a5e2e4855c4ac5ab009c3372922710929 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 18 Oct 2024 12:34:12 +0200 Subject: [PATCH 059/118] Use upstream sklearn PCA if possible (#3267) --- docs/release-notes/3267.feature.md | 1 + hatch.toml | 2 +- pyproject.toml | 3 +- .../{_pca.py => _pca/__init__.py} | 316 +++++++++--------- src/scanpy/preprocessing/_pca/_compat.py | 79 +++++ tests/test_pca.py | 98 +++--- 6 files changed, 278 insertions(+), 221 deletions(-) create mode 100644 docs/release-notes/3267.feature.md rename src/scanpy/preprocessing/{_pca.py => _pca/__init__.py} (70%) create mode 100644 src/scanpy/preprocessing/_pca/_compat.py diff --git a/docs/release-notes/3267.feature.md b/docs/release-notes/3267.feature.md new file mode 100644 index 0000000000..ea4a5c6080 --- /dev/null +++ b/docs/release-notes/3267.feature.md @@ -0,0 +1 @@ +Use upstreamed {class}`~sklearn.decomposition.PCA` implementation for {class}`~scipy.sparse.sparray` and {class}`~scipy.sparse.spmatrix` (see {ref}`sklearn:changes_1_4`) {smaller}`P Angerer` diff --git a/hatch.toml b/hatch.toml index 705b003bb6..ab2bb7550e 100644 --- a/hatch.toml +++ b/hatch.toml @@ -15,7 +15,7 @@ scripts.clean = "git restore --source=HEAD --staged --worktree -- docs/release-n [envs.hatch-test] default-args = [] -features = ["test"] +features = ["test", "dask-ml"] extra-dependencies = ["ipykernel"] overrides.matrix.deps.env-vars = [ { if = ["pre"], key = "UV_PRERELEASE", value = "allow" }, diff --git a/pyproject.toml b/pyproject.toml index 1d78652993..dff45651fb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -126,8 +126,7 @@ doc = [ "sphinxcontrib-bibtex", "setuptools", # TODO: remove necessity for being able to import doc-linked classes - "dask", - "scanpy[paga]", + "scanpy[paga,dask-ml]", "sam-algorithm", ] dev = [ diff --git a/src/scanpy/preprocessing/_pca.py b/src/scanpy/preprocessing/_pca/__init__.py similarity index 70% rename from src/scanpy/preprocessing/_pca.py rename to src/scanpy/preprocessing/_pca/__init__.py index 93432841f8..8bc39cbf57 100644 --- a/src/scanpy/preprocessing/_pca.py +++ b/src/scanpy/preprocessing/_pca/__init__.py @@ -1,7 +1,7 @@ from __future__ import annotations import warnings -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Literal, get_args, overload from warnings import warn import anndata as ad @@ -9,24 +9,47 @@ from anndata import AnnData from packaging.version import Version from scipy.sparse import issparse -from scipy.sparse.linalg import LinearOperator, svds -from sklearn.utils import check_array, check_random_state -from sklearn.utils.extmath import svd_flip - -from .. import logging as logg -from .._compat import DaskArray, pkg_version -from .._settings import settings -from .._utils import _doc_params, _empty, is_backed_type -from ..get import _check_mask, _get_obs_rep -from ._docs import doc_mask_var_hvg -from ._utils import _get_mean_var +from sklearn.utils import check_random_state + +from ... import logging as logg +from ..._compat import DaskArray, pkg_version +from ..._settings import settings +from ..._utils import _doc_params, _empty, is_backed_type +from ...get import _check_mask, _get_obs_rep +from .._docs import doc_mask_var_hvg +from ._compat import _pca_compat_sparse if TYPE_CHECKING: + from collections.abc import Container + from typing import LiteralString, TypeVar + + import dask_ml.decomposition as dmld + import sklearn.decomposition as skld from numpy.typing import DTypeLike, NDArray + from scipy import sparse from scipy.sparse import spmatrix - from sklearn.decomposition import PCA - from .._utils import AnyRandom, Empty + from ..._utils import AnyRandom, Empty + + CSMatrix = sparse.csr_matrix | sparse.csc_matrix + + MethodDaskML = type[dmld.PCA | dmld.IncrementalPCA | dmld.TruncatedSVD] + MethodSklearn = type[skld.PCA | skld.TruncatedSVD] + + T = TypeVar("T", bound=LiteralString) + M = TypeVar("M", bound=LiteralString) + + +SvdSolvPCADaskML = Literal["auto", "full", "tsqr", "randomized"] +SvdSolvTruncatedSVDDaskML = Literal["tsqr", "randomized"] +SvdSolvDaskML = SvdSolvPCADaskML | SvdSolvTruncatedSVDDaskML + +SvdSolvPCASklearn = Literal["auto", "full", "arpack", "randomized"] +SvdSolvTruncatedSVDSklearn = Literal["arpack", "randomized"] +SvdSolvPCASparseSklearn = Literal["arpack"] +SvdSolvSkearn = SvdSolvPCASklearn | SvdSolvTruncatedSVDSklearn | SvdSolvPCASparseSklearn + +SvdSolver = SvdSolvDaskML | SvdSolvSkearn @_doc_params( @@ -38,7 +61,7 @@ def pca( *, layer: str | None = None, zero_center: bool | None = True, - svd_solver: str | None = None, + svd_solver: SvdSolver | None = None, random_state: AnyRandom = 0, return_info: bool = False, mask_var: NDArray[np.bool_] | str | None | Empty = _empty, @@ -180,7 +203,7 @@ def pca( logg.info( "Note that scikit-learn's randomized PCA might not be exactly " "reproducible across different computational platforms. For exact " - "reproducibility, choose `svd_solver='arpack'.`" + "reproducibility, choose `svd_solver='arpack'`." ) data_is_AnnData = isinstance(data, AnnData) if data_is_AnnData: @@ -224,11 +247,9 @@ def pca( UserWarning, ) - is_dask = isinstance(X, DaskArray) - # check_random_state returns a numpy RandomState when passed an int but # dask needs an int for random state - if not is_dask: + if not isinstance(X, DaskArray): random_state = check_random_state(random_state) elif not isinstance(random_state, int): msg = f"random_state needs to be an int, not a {type(random_state).__name__} when passing a dask array" @@ -243,12 +264,12 @@ def pca( logg.debug("Ignoring zero_center, random_state, svd_solver") incremental_pca_kwargs = dict() - if is_dask: + if isinstance(X, DaskArray): from dask.array import zeros from dask_ml.decomposition import IncrementalPCA incremental_pca_kwargs["svd_solver"] = _handle_dask_ml_args( - svd_solver, "IncrementalPCA" + svd_solver, IncrementalPCA ) else: from numpy import zeros @@ -265,46 +286,54 @@ def pca( for chunk, start, end in adata_comp.chunked_X(chunk_size): chunk = chunk.toarray() if issparse(chunk) else chunk X_pca[start:end] = pca_.transform(chunk) - elif (not issparse(X) or svd_solver == "randomized") and zero_center: - if is_dask: - from dask_ml.decomposition import PCA - - svd_solver = _handle_dask_ml_args(svd_solver, "PCA") + elif zero_center: + if issparse(X) and ( + pkg_version("scikit-learn") < Version("1.4") or svd_solver == "lobpcg" + ): + if svd_solver not in {"lobpcg", "arpack"}: + if svd_solver is not None: + msg = ( + f"Ignoring {svd_solver=} and using 'arpack', " + "sparse PCA with sklearn < 1.4 only supports 'lobpcg' and 'arpack'." + ) + warnings.warn(msg) + svd_solver = "arpack" + elif svd_solver == "lobpcg": + msg = ( + f"{svd_solver=} for sparse relies on legacy code and will not be supported in the future. " + "Also the lobpcg solver has been observed to be inaccurate. Please use 'arpack' instead." + ) + warnings.warn(msg, FutureWarning) + X_pca, pca_ = _pca_compat_sparse( + X, n_comps, solver=svd_solver, random_state=random_state + ) else: - from sklearn.decomposition import PCA + if isinstance(X, DaskArray): + from dask_ml.decomposition import PCA - svd_solver = _handle_sklearn_args(svd_solver, "PCA") + svd_solver = _handle_dask_ml_args(svd_solver, PCA) + else: + from sklearn.decomposition import PCA - if issparse(X) and svd_solver == "randomized": - # This is for backwards compat. Better behaviour would be to either error or use arpack. - warnings.warn( - "svd_solver 'randomized' does not work with sparse input. Densifying the array. " - "This may take a very large amount of memory." - ) - X = X.toarray() - pca_ = PCA( - n_components=n_comps, svd_solver=svd_solver, random_state=random_state - ) - X_pca = pca_.fit_transform(X) - elif issparse(X) and zero_center: - svd_solver = _handle_sklearn_args(svd_solver, "PCA (with sparse input)") + svd_solver = _handle_sklearn_args(svd_solver, PCA, sparse=issparse(X)) - X_pca, pca_ = _pca_with_sparse( - X, n_comps, solver=svd_solver, random_state=random_state - ) - elif not zero_center: - if is_dask: + pca_ = PCA( + n_components=n_comps, svd_solver=svd_solver, random_state=random_state + ) + X_pca = pca_.fit_transform(X) + else: + if isinstance(X, DaskArray): from dask_ml.decomposition import TruncatedSVD - svd_solver = _handle_dask_ml_args(svd_solver, "TruncatedSVD") + svd_solver = _handle_dask_ml_args(svd_solver, TruncatedSVD) else: from sklearn.decomposition import TruncatedSVD - svd_solver = _handle_sklearn_args(svd_solver, "TruncatedSVD") + svd_solver = _handle_sklearn_args(svd_solver, TruncatedSVD) logg.debug( " without zero-centering: \n" - " the explained variance does not correspond to the exact statistical defintion\n" + " the explained variance does not correspond to the exact statistical definition\n" " the first component, e.g., might be heavily influenced by different means\n" " the following components often resemble the exact PCA very closely" ) @@ -312,9 +341,6 @@ def pca( n_components=n_comps, random_state=random_state, algorithm=svd_solver ) X_pca = pca_.fit_transform(X) - else: - msg = "This shouldn’t happen. Please open a bug report." - raise AssertionError(msg) if X_pca.dtype.descr != np.dtype(dtype).descr: X_pca = X_pca.astype(dtype) @@ -402,110 +428,84 @@ def _handle_mask_var( return mask_var, _check_mask(adata, mask_var, "var") -def _pca_with_sparse( - X: spmatrix, - n_pcs: int, +@overload +def _handle_dask_ml_args( + svd_solver: str | None, method: type[dmld.PCA | dmld.IncrementalPCA] +) -> SvdSolvPCADaskML: ... +@overload +def _handle_dask_ml_args( + svd_solver: str | None, method: type[dmld.TruncatedSVD] +) -> SvdSolvTruncatedSVDDaskML: ... +def _handle_dask_ml_args(svd_solver: str | None, method: MethodDaskML) -> str: + import dask_ml.decomposition as dmld + + args: tuple[SvdSolvDaskML, ...] + default: SvdSolvDaskML + match method: + case dmld.PCA | dmld.IncrementalPCA: + args = get_args(SvdSolvPCADaskML) + default = "auto" + case dmld.TruncatedSVD: + args = get_args(SvdSolvTruncatedSVDDaskML) + default = "tsqr" + case _: + msg = f"Unknown {method=} in _handle_dask_ml_args" + raise ValueError(msg) + return _handle_x_args(svd_solver, method, args, default) + + +@overload +def _handle_sklearn_args( + svd_solver: str | None, method: type[skld.TruncatedSVD], *, sparse: None = None +) -> SvdSolvTruncatedSVDSklearn: ... +@overload +def _handle_sklearn_args( + svd_solver: str | None, method: type[skld.PCA], *, sparse: Literal[False] +) -> SvdSolvPCASklearn: ... +@overload +def _handle_sklearn_args( + svd_solver: str | None, method: type[skld.PCA], *, sparse: Literal[True] +) -> SvdSolvPCASparseSklearn: ... +def _handle_sklearn_args( + svd_solver: str | None, method: MethodSklearn, *, sparse: bool | None = None +) -> str: + import sklearn.decomposition as skld + + args: tuple[SvdSolvSkearn, ...] + default: SvdSolvSkearn + suffix = "" + match (method, sparse): + case (skld.TruncatedSVD, None): + args = get_args(SvdSolvTruncatedSVDSklearn) + default = "randomized" + case (skld.PCA, False): + args = get_args(SvdSolvPCASklearn) + default = "arpack" + case (skld.PCA, True): + args = get_args(SvdSolvPCASparseSklearn) + default = "arpack" + suffix = " (with sparse input)" + case _: + msg = f"Unknown {method=} ({sparse=}) in _handle_sklearn_args" + raise ValueError(msg) + + return _handle_x_args(svd_solver, method, args, default, suffix=suffix) + + +def _handle_x_args( + svd_solver: str | None, + method: type, + args: Container[T], + default: T, *, - solver: str = "arpack", - mu: NDArray[np.floating] | None = None, - random_state: AnyRandom = None, -) -> tuple[NDArray[np.floating], PCA]: - random_state = check_random_state(random_state) - np.random.set_state(random_state.get_state()) - random_init = np.random.rand(np.min(X.shape)) - X = check_array(X, accept_sparse=["csr", "csc"]) - - if mu is None: - mu = np.asarray(X.mean(0)).flatten()[None, :] - mdot = mu.dot - mmat = mdot - mhdot = mu.T.dot - mhmat = mu.T.dot - Xdot = X.dot - Xmat = Xdot - XHdot = X.T.conj().dot - XHmat = XHdot - ones = np.ones(X.shape[0])[None, :].dot - - def matvec(x): - return Xdot(x) - mdot(x) - - def matmat(x): - return Xmat(x) - mmat(x) - - def rmatvec(x): - return XHdot(x) - mhdot(ones(x)) - - def rmatmat(x): - return XHmat(x) - mhmat(ones(x)) - - XL = LinearOperator( - matvec=matvec, - dtype=X.dtype, - matmat=matmat, - shape=X.shape, - rmatvec=rmatvec, - rmatmat=rmatmat, - ) - - u, s, v = svds(XL, solver=solver, k=n_pcs, v0=random_init) - # u_based_decision was changed in https://github.com/scikit-learn/scikit-learn/pull/27491 - u, v = svd_flip( - u, v, u_based_decision=pkg_version("scikit-learn") < Version("1.5.0rc1") - ) - idx = np.argsort(-s) - v = v[idx, :] - - X_pca = (u * s)[:, idx] - ev = s[idx] ** 2 / (X.shape[0] - 1) - - total_var = _get_mean_var(X)[1].sum() - ev_ratio = ev / total_var - - from sklearn.decomposition import PCA - - pca = PCA(n_components=n_pcs, svd_solver=solver, random_state=random_state) - pca.explained_variance_ = ev - pca.explained_variance_ratio_ = ev_ratio - pca.components_ = v - return X_pca, pca - - -def _handle_dask_ml_args(svd_solver: str, method: str) -> str: - method2args = { - "PCA": {"auto", "full", "tsqr", "randomized"}, - "IncrementalPCA": {"auto", "full", "tsqr", "randomized"}, - "TruncatedSVD": {"tsqr", "randomized"}, - } - method2default = { - "PCA": "auto", - "IncrementalPCA": "auto", - "TruncatedSVD": "tsqr", - } - - return _handle_x_args("dask_ml", svd_solver, method, method2args, method2default) - - -def _handle_sklearn_args(svd_solver: str | None, method: str) -> str: - method2args = { - "PCA": {"auto", "full", "arpack", "randomized"}, - "TruncatedSVD": {"arpack", "randomized"}, - "PCA (with sparse input)": {"lobpcg", "arpack"}, - } - method2default = { - "PCA": "arpack", - "TruncatedSVD": "randomized", - "PCA (with sparse input)": "arpack", - } - - return _handle_x_args("sklearn", svd_solver, method, method2args, method2default) - - -def _handle_x_args(lib, svd_solver: str | None, method, method2args, method2default): - if svd_solver not in method2args[method]: - if svd_solver is not None: - warnings.warn( - f"Ignoring {svd_solver} and using {method2default[method]}, {lib}.decomposition.{method} only supports {method2args[method]}" - ) - svd_solver = method2default[method] - return svd_solver + suffix: str = "", +) -> T: + if svd_solver in args: + return svd_solver + if svd_solver is not None: + msg = ( + f"Ignoring {svd_solver=} and using {default}, " + f"{method.__module__}.{method.__qualname__}{suffix} only supports {args}." + ) + warnings.warn(msg) + return default diff --git a/src/scanpy/preprocessing/_pca/_compat.py b/src/scanpy/preprocessing/_pca/_compat.py new file mode 100644 index 0000000000..23cb60a2e9 --- /dev/null +++ b/src/scanpy/preprocessing/_pca/_compat.py @@ -0,0 +1,79 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +import numpy as np +from packaging.version import Version +from scipy.sparse.linalg import LinearOperator, svds +from sklearn.utils import check_array, check_random_state +from sklearn.utils.extmath import svd_flip + +from ..._compat import pkg_version +from .._utils import _get_mean_var + +if TYPE_CHECKING: + from typing import Literal + + from numpy.typing import NDArray + from scipy import sparse + from sklearn.decomposition import PCA + + from .._utils import AnyRandom + + CSMatrix = sparse.csr_matrix | sparse.csc_matrix + + +def _pca_compat_sparse( + x: CSMatrix, + n_pcs: int, + *, + solver: Literal["arpack", "lobpcg"], + mu: NDArray[np.floating] | None = None, + random_state: AnyRandom = None, +) -> tuple[NDArray[np.floating], PCA]: + """Sparse PCA for scikit-learn <1.4""" + random_state = check_random_state(random_state) + np.random.set_state(random_state.get_state()) + random_init = np.random.rand(np.min(x.shape)) + x = check_array(x, accept_sparse=["csr", "csc"]) + + if mu is None: + mu = np.asarray(x.mean(0)).flatten()[None, :] + ones = np.ones(x.shape[0])[None, :].dot + + def mat_op(v: NDArray[np.floating]): + return (x @ v) - (mu @ v) + + def rmat_op(v: NDArray[np.floating]): + return (x.T.conj() @ v) - (mu.T @ ones(v)) + + linop = LinearOperator( + dtype=x.dtype, + shape=x.shape, + matvec=mat_op, + matmat=mat_op, + rmatvec=rmat_op, + rmatmat=rmat_op, + ) + + u, s, v = svds(linop, solver=solver, k=n_pcs, v0=random_init) + # u_based_decision was changed in https://github.com/scikit-learn/scikit-learn/pull/27491 + u, v = svd_flip( + u, v, u_based_decision=pkg_version("scikit-learn") < Version("1.5.0rc1") + ) + idx = np.argsort(-s) + v = v[idx, :] + + X_pca = (u * s)[:, idx] + ev = s[idx] ** 2 / (x.shape[0] - 1) + + total_var = _get_mean_var(x)[1].sum() + ev_ratio = ev / total_var + + from sklearn.decomposition import PCA + + pca = PCA(n_components=n_pcs, svd_solver=solver, random_state=random_state) + pca.explained_variance_ = ev + pca.explained_variance_ratio_ = ev_ratio + pca.components_ = v + return X_pca, pca diff --git a/tests/test_pca.py b/tests/test_pca.py index 7e49c49cfb..f0bd88567c 100644 --- a/tests/test_pca.py +++ b/tests/test_pca.py @@ -1,5 +1,6 @@ from __future__ import annotations +import random import warnings from contextlib import nullcontext from functools import wraps @@ -9,10 +10,8 @@ import numpy as np import pytest from anndata import AnnData -from anndata.tests.helpers import ( - asarray, - assert_equal, -) +from anndata.tests import helpers +from anndata.tests.helpers import assert_equal from packaging.version import Version from scipy import sparse from scipy.sparse import issparse @@ -117,77 +116,58 @@ def pca_params( ): all_svd_solvers = {"auto", "full", "arpack", "randomized", "tsqr", "lobpcg"} - expected_warning = None + warn_pat_expected = None svd_solver = None if svd_solver_type is not None: - if array_type in DASK_CONVERTERS.values(): - svd_solver = ( - {"auto", "full", "tsqr", "randomized"} - if zero_center - else {"tsqr", "randomized"} - ) - elif array_type in {sparse.csr_matrix, sparse.csc_matrix}: - svd_solver = ( - {"lobpcg", "arpack"} if zero_center else {"arpack", "randomized"} - ) - elif array_type is asarray: - svd_solver = ( - {"auto", "full", "arpack", "randomized"} - if zero_center - else {"arpack", "randomized"} - ) - else: - pytest.fail(f"Unknown array type {array_type}") + match array_type, zero_center: + case (dc, True) if dc in DASK_CONVERTERS.values(): + svd_solver = {"auto", "full", "tsqr", "randomized"} + case (dc, False) if dc in DASK_CONVERTERS.values(): + svd_solver = {"tsqr", "randomized"} + case ((sparse.csr_matrix | sparse.csc_matrix), True): + svd_solver = {"arpack"} + case ((sparse.csr_matrix | sparse.csc_matrix), False): + svd_solver = {"arpack", "randomized"} + case (helpers.asarray, True): + svd_solver = {"auto", "full", "arpack", "randomized"} + case (helpers.asarray, False): + svd_solver = {"arpack", "randomized"} + case _: + pytest.fail(f"Unknown array type {array_type}") if svd_solver_type == "invalid": svd_solver = all_svd_solvers - svd_solver - expected_warning = "Ignoring" + warn_pat_expected = r"Ignoring" - svd_solver = np.random.choice(list(svd_solver)) + svd_solver = random.choice(list(svd_solver)) # explicit check for special case if ( - svd_solver == "randomized" + array_type in {sparse.csr_matrix, sparse.csc_matrix} and zero_center - and array_type in [sparse.csr_matrix, sparse.csc_matrix] + and svd_solver == "lobpcg" ): - expected_warning = "not work with sparse input" + warn_pat_expected = r"legacy code" - return (svd_solver, expected_warning) + return (svd_solver, warn_pat_expected) def test_pca_warnings(array_type, zero_center, pca_params): - svd_solver, expected_warning = pca_params + svd_solver, warn_pat_expected = pca_params A = array_type(A_list).astype("float32") adata = AnnData(A) - if expected_warning is not None: - with pytest.warns(UserWarning, match=expected_warning): - sc.pp.pca(adata, svd_solver=svd_solver, zero_center=zero_center) - return - - try: - with warnings.catch_warnings(): - warnings.simplefilter("error") + if warn_pat_expected is not None: + with pytest.warns((UserWarning, FutureWarning), match=warn_pat_expected): warnings.filterwarnings( - "ignore", - "pkg_resources is deprecated as an API", - DeprecationWarning, + "ignore", r".*Using a dense eigensolver instead of LOBPCG", UserWarning ) sc.pp.pca(adata, svd_solver=svd_solver, zero_center=zero_center) - except UserWarning: - # TODO: Fix this case, maybe by increasing test data size. - # https://github.com/scverse/scanpy/issues/2744 - if svd_solver == "lobpcg": - pytest.xfail(reason="lobpcg doesn’t work with this small test data") - raise - + return -# This warning test is out of the fixture because it is a special case in the logic of the function -def test_pca_warnings_sparse(): - for array_type in (sparse.csr_matrix, sparse.csc_matrix): - A = array_type(A_list).astype("float32") - adata = AnnData(A) - with pytest.warns(UserWarning, match="not work with sparse input"): - sc.pp.pca(adata, svd_solver="randomized", zero_center=True) + warnings.simplefilter("error") + warnings.filterwarnings( + "ignore", "pkg_resources is deprecated as an API", DeprecationWarning + ) + sc.pp.pca(adata, svd_solver=svd_solver, zero_center=zero_center) def test_pca_transform(array_type): @@ -206,22 +186,20 @@ def test_pca_transform_randomized(array_type): warnings.filterwarnings("error") with ( - pytest.warns( - UserWarning, match="svd_solver 'randomized' does not work with sparse input" - ) + pytest.warns(UserWarning, match="Ignoring.*'randomized'") if sparse.issparse(adata.X) else nullcontext() ): sc.pp.pca( adata, - n_comps=5, + n_comps=4, zero_center=True, svd_solver="randomized", dtype="float64", random_state=14, ) - assert np.linalg.norm(A_pca_abs - np.abs(adata.obsm["X_pca"])) < 2e-05 + assert np.linalg.norm(A_pca_abs[:, :4] - np.abs(adata.obsm["X_pca"])) < 2e-05 def test_pca_transform_no_zero_center(array_type): From 3020094708b498fb180b895cddb6c4b81ccb49e3 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 18 Oct 2024 13:18:03 +0200 Subject: [PATCH 060/118] Test all PCA param combinations (#3294) --- src/testing/scanpy/_pytest/params.py | 9 +- tests/test_pca.py | 162 +++++++++++++++++---------- 2 files changed, 106 insertions(+), 65 deletions(-) diff --git a/src/testing/scanpy/_pytest/params.py b/src/testing/scanpy/_pytest/params.py index af80d1709d..f405e33d5e 100644 --- a/src/testing/scanpy/_pytest/params.py +++ b/src/testing/scanpy/_pytest/params.py @@ -15,19 +15,22 @@ from .._pytest.marks import needs if TYPE_CHECKING: - from collections.abc import Iterable - from typing import Literal + from collections.abc import Callable, Iterable + from typing import Any, Literal from _pytest.mark.structures import ParameterSet def param_with( at: ParameterSet, + transform: Callable[..., Iterable[Any]] = lambda x: (x,), *, marks: Iterable[pytest.Mark | pytest.MarkDecorator] = (), id: str | None = None, ) -> ParameterSet: - return pytest.param(*at.values, marks=[*at.marks, *marks], id=id or at.id) + return pytest.param( + *transform(*at.values), marks=[*at.marks, *marks], id=id or at.id + ) MAP_ARRAY_TYPES: dict[ diff --git a/tests/test_pca.py b/tests/test_pca.py index f0bd88567c..fa294ef343 100644 --- a/tests/test_pca.py +++ b/tests/test_pca.py @@ -1,10 +1,9 @@ from __future__ import annotations -import random import warnings from contextlib import nullcontext from functools import wraps -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Literal, cast, get_args import anndata as ad import numpy as np @@ -20,18 +19,22 @@ from testing.scanpy import _helpers from testing.scanpy._helpers.data import pbmc3k_normalized from testing.scanpy._pytest.marks import needs +from testing.scanpy._pytest.params import ARRAY_TYPES as ARRAY_TYPES_ALL from testing.scanpy._pytest.params import ( - ARRAY_TYPES, ARRAY_TYPES_SPARSE_DASK_UNSUPPORTED, param_with, ) if TYPE_CHECKING: - from collections.abc import Callable - from typing import Literal + from collections.abc import Callable, Generator + + from anndata.typing import ArrayDataStructureType from scanpy._compat import DaskArray + ArrayType = Callable[[np.ndarray], ArrayDataStructureType] + + A_list = np.array( [ [0, 0, 7, 0, 0], @@ -83,75 +86,110 @@ def wrapper(a: np.ndarray) -> DaskArray: } -@pytest.fixture( - params=[ - param_with(at, marks=[needs.dask_ml]) if "dask" in at.id else at - for at in ARRAY_TYPES_SPARSE_DASK_UNSUPPORTED - ] -) -def array_type(request: pytest.FixtureRequest): +def maybe_convert_array_to_dask(array_type): # If one uses dask for PCA it will always require dask-ml. # dask-ml can’t do 2D-chunked arrays, so rechunk them. - if as_dask_array := DASK_CONVERTERS.get(request.param): - return as_dask_array + if as_dask_array := DASK_CONVERTERS.get(array_type): + return (as_dask_array,) # When not using dask, just return the array type - assert "dask" not in request.param.__name__, "add more branches or refactor" - return request.param + assert "dask" not in array_type.__name__, "add more branches or refactor" + return (array_type,) -@pytest.fixture(params=[None, "valid", "invalid"]) -def svd_solver_type(request: pytest.FixtureRequest): - return request.param +ARRAY_TYPES = [ + param_with(at, maybe_convert_array_to_dask, marks=[needs.dask_ml]) + if "dask" in cast(str, at.id) + else at + for at in ARRAY_TYPES_SPARSE_DASK_UNSUPPORTED +] -@pytest.fixture(params=[True, False], ids=["zero_center", "no_zero_center"]) -def zero_center(request: pytest.FixtureRequest): +@pytest.fixture(params=ARRAY_TYPES) +def array_type(request: pytest.FixtureRequest) -> ArrayType: return request.param -@pytest.fixture -def pca_params( - array_type, svd_solver_type: Literal[None, "valid", "invalid"], zero_center -): - all_svd_solvers = {"auto", "full", "arpack", "randomized", "tsqr", "lobpcg"} - - warn_pat_expected = None - svd_solver = None - if svd_solver_type is not None: - match array_type, zero_center: - case (dc, True) if dc in DASK_CONVERTERS.values(): - svd_solver = {"auto", "full", "tsqr", "randomized"} - case (dc, False) if dc in DASK_CONVERTERS.values(): - svd_solver = {"tsqr", "randomized"} - case ((sparse.csr_matrix | sparse.csc_matrix), True): - svd_solver = {"arpack"} - case ((sparse.csr_matrix | sparse.csc_matrix), False): - svd_solver = {"arpack", "randomized"} - case (helpers.asarray, True): - svd_solver = {"auto", "full", "arpack", "randomized"} - case (helpers.asarray, False): - svd_solver = {"arpack", "randomized"} - case _: - pytest.fail(f"Unknown array type {array_type}") - if svd_solver_type == "invalid": - svd_solver = all_svd_solvers - svd_solver - warn_pat_expected = r"Ignoring" - - svd_solver = random.choice(list(svd_solver)) - # explicit check for special case - if ( - array_type in {sparse.csr_matrix, sparse.csc_matrix} - and zero_center - and svd_solver == "lobpcg" - ): - warn_pat_expected = r"legacy code" +SVDSolver = Literal["auto", "full", "arpack", "randomized", "tsqr", "lobpcg"] - return (svd_solver, warn_pat_expected) +def gen_pca_params( + *, + array_type: ArrayType, + svd_solver_type: Literal[None, "valid", "invalid"], + zero_center: bool, +) -> Generator[tuple[SVDSolver, str | None] | tuple[None, None], None, None]: + if svd_solver_type is None: + yield None, None + return -def test_pca_warnings(array_type, zero_center, pca_params): - svd_solver, warn_pat_expected = pca_params + all_svd_solvers = set(get_args(SVDSolver)) + svd_solvers: set[SVDSolver] + match array_type, zero_center: + case (dc, True) if dc in DASK_CONVERTERS.values(): + svd_solvers = {"auto", "full", "tsqr", "randomized"} + case (dc, False) if dc in DASK_CONVERTERS.values(): + svd_solvers = {"tsqr", "randomized"} + case ((sparse.csr_matrix | sparse.csc_matrix), True): + svd_solvers = {"arpack"} + case ((sparse.csr_matrix | sparse.csc_matrix), False): + svd_solvers = {"arpack", "randomized"} + case (helpers.asarray, True): + svd_solvers = {"auto", "full", "arpack", "randomized"} + case (helpers.asarray, False): + svd_solvers = {"arpack", "randomized"} + case _: + pytest.fail(f"Unknown array type {array_type}") + + if svd_solver_type == "invalid": + svd_solvers = all_svd_solvers - svd_solvers + warn_pat_expected = r"Ignoring" + elif svd_solver_type == "valid": + warn_pat_expected = None + else: + pytest.fail(f"Unknown svd_solver_type {svd_solver_type}") + + for svd_solver in svd_solvers: + # explicit check for special case + if ( + array_type in {sparse.csr_matrix, sparse.csc_matrix} + and zero_center + and svd_solver == "lobpcg" + ): + pat = r"legacy code" + else: + pat = warn_pat_expected + yield (svd_solver, pat) + + +@pytest.mark.parametrize( + ("array_type", "zero_center", "svd_solver", "warn_pat_expected"), + [ + pytest.param( + array_type.values[0], + zero_center, + svd_solver, + warn_pat_expected, + marks=array_type.marks, + id=f"{array_type.id}-{'zero_center' if zero_center else 'no_zero_center'}-{svd_solver}-{warn_pat_expected}", + ) + for array_type in ARRAY_TYPES + for zero_center in [True, False] + for svd_solver_type in [None, "valid", "invalid"] + for svd_solver, warn_pat_expected in gen_pca_params( + array_type=array_type.values[0], + zero_center=zero_center, + svd_solver_type=svd_solver_type, + ) + ], +) +def test_pca_warnings( + *, + array_type: ArrayType, + zero_center: bool, + svd_solver: SVDSolver, + warn_pat_expected: str | None, +): A = array_type(A_list).astype("float32") adata = AnnData(A) @@ -322,9 +360,9 @@ def test_pca_n_pcs(): ) -# We use all ARRAY_TYPES here since this error should be raised before +# We use all possible array types here since this error should be raised before # PCA can realize that it got a Dask array -@pytest.mark.parametrize("array_type", ARRAY_TYPES) +@pytest.mark.parametrize("array_type", ARRAY_TYPES_ALL) def test_mask_highly_var_error(array_type): """Check if use_highly_variable=True throws an error if the annotation is missing.""" adata = AnnData(array_type(A_list).astype("float32")) From c2f940793ca1af8a82331ed4243f3a2aea821d0f Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 18 Oct 2024 16:39:11 +0200 Subject: [PATCH 061/118] Add explicit support to PCA for `'covariance_eigh'` svd_solver (#3296) --- docs/release-notes/3296.feature.md | 1 + src/scanpy/preprocessing/_pca/__init__.py | 8 ++++---- tests/test_pca.py | 4 +++- 3 files changed, 8 insertions(+), 5 deletions(-) create mode 100644 docs/release-notes/3296.feature.md diff --git a/docs/release-notes/3296.feature.md b/docs/release-notes/3296.feature.md new file mode 100644 index 0000000000..74b89945dd --- /dev/null +++ b/docs/release-notes/3296.feature.md @@ -0,0 +1 @@ +Add explicit support to {func}`scanpy.pp.pca` for `svd_solver='covariance_eigh'` {smaller}`P Angerer` diff --git a/src/scanpy/preprocessing/_pca/__init__.py b/src/scanpy/preprocessing/_pca/__init__.py index 8bc39cbf57..918073d8b7 100644 --- a/src/scanpy/preprocessing/_pca/__init__.py +++ b/src/scanpy/preprocessing/_pca/__init__.py @@ -44,7 +44,7 @@ SvdSolvTruncatedSVDDaskML = Literal["tsqr", "randomized"] SvdSolvDaskML = SvdSolvPCADaskML | SvdSolvTruncatedSVDDaskML -SvdSolvPCASklearn = Literal["auto", "full", "arpack", "randomized"] +SvdSolvPCASklearn = Literal["auto", "full", "arpack", "covariance_eigh", "randomized"] SvdSolvTruncatedSVDSklearn = Literal["arpack", "randomized"] SvdSolvPCASparseSklearn = Literal["arpack"] SvdSolvSkearn = SvdSolvPCASklearn | SvdSolvTruncatedSVDSklearn | SvdSolvPCASparseSklearn @@ -116,13 +116,13 @@ def pca( `'arpack'` for the ARPACK wrapper in SciPy (:func:`~scipy.sparse.linalg.svds`) Not available with *dask* arrays. + `'covariance_eigh'` + Classic eigendecomposition of the covariance matrix, suited for tall-and-skinny matrices. `'randomized'` for the randomized algorithm due to Halko (2009). For *dask* arrays, this will use :func:`~dask.array.linalg.svd_compressed`. `'auto'` chooses automatically depending on the size of the problem. - `'lobpcg'` - An alternative SciPy solver. Not available with dask arrays. `'tsqr'` Only available with *dask* arrays. "tsqr" algorithm from Benson et. al. (2013). @@ -133,7 +133,7 @@ def pca( Default value changed from `'auto'` to `'arpack'`. Efficient computation of the principal components of a sparse matrix - currently only works with the `'arpack`' or `'lobpcg'` solvers. + currently only works with the `'arpack`' or `'covariance_eigh`' solver. If X is a *dask* array, *dask-ml* classes :class:`~dask_ml.decomposition.PCA`, :class:`~dask_ml.decomposition.IncrementalPCA`, or diff --git a/tests/test_pca.py b/tests/test_pca.py index fa294ef343..5dca5f2b8a 100644 --- a/tests/test_pca.py +++ b/tests/test_pca.py @@ -16,6 +16,7 @@ from scipy.sparse import issparse import scanpy as sc +from scanpy.preprocessing._pca import SvdSolver as SvdSolverSupported from testing.scanpy import _helpers from testing.scanpy._helpers.data import pbmc3k_normalized from testing.scanpy._pytest.marks import needs @@ -110,7 +111,8 @@ def array_type(request: pytest.FixtureRequest) -> ArrayType: return request.param -SVDSolver = Literal["auto", "full", "arpack", "randomized", "tsqr", "lobpcg"] +SVDSolverDeprecated = Literal["lobpcg"] +SVDSolver = SvdSolverSupported | SVDSolverDeprecated def gen_pca_params( From 1448822e83b9854f4b1f4d7b696f8f8dcc78544b Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 18 Oct 2024 19:04:53 +0200 Subject: [PATCH 062/118] Implement sparse `covariance_eigh` PCA using Dask (#3263) Co-authored-by: Ilan Gold --- docs/release-notes/3263.feature.md | 1 + src/scanpy/preprocessing/_pca/__init__.py | 63 ++++-- src/scanpy/preprocessing/_pca/_dask_sparse.py | 206 ++++++++++++++++++ src/testing/scanpy/_helpers/__init__.py | 20 ++ tests/test_pca.py | 165 +++++++++++--- 5 files changed, 405 insertions(+), 50 deletions(-) create mode 100644 docs/release-notes/3263.feature.md create mode 100644 src/scanpy/preprocessing/_pca/_dask_sparse.py diff --git a/docs/release-notes/3263.feature.md b/docs/release-notes/3263.feature.md new file mode 100644 index 0000000000..8e924e1799 --- /dev/null +++ b/docs/release-notes/3263.feature.md @@ -0,0 +1 @@ +Support running {func}`scanpy.pp.pca` on sparse Dask arrays with the `'covariance_eigh'` solver {smaller}`P Angerer` diff --git a/src/scanpy/preprocessing/_pca/__init__.py b/src/scanpy/preprocessing/_pca/__init__.py index 918073d8b7..396781ce7a 100644 --- a/src/scanpy/preprocessing/_pca/__init__.py +++ b/src/scanpy/preprocessing/_pca/__init__.py @@ -44,12 +44,18 @@ SvdSolvTruncatedSVDDaskML = Literal["tsqr", "randomized"] SvdSolvDaskML = SvdSolvPCADaskML | SvdSolvTruncatedSVDDaskML -SvdSolvPCASklearn = Literal["auto", "full", "arpack", "covariance_eigh", "randomized"] +SvdSolvPCADenseSklearn = Literal[ + "auto", "full", "arpack", "covariance_eigh", "randomized" +] +SvdSolvPCASparseSklearn = Literal["arpack", "covariance_eigh"] SvdSolvTruncatedSVDSklearn = Literal["arpack", "randomized"] -SvdSolvPCASparseSklearn = Literal["arpack"] -SvdSolvSkearn = SvdSolvPCASklearn | SvdSolvTruncatedSVDSklearn | SvdSolvPCASparseSklearn +SvdSolvSkearn = ( + SvdSolvPCADenseSklearn | SvdSolvPCASparseSklearn | SvdSolvTruncatedSVDSklearn +) + +SvdSolvPCACustom = Literal["covariance_eigh"] -SvdSolver = SvdSolvDaskML | SvdSolvSkearn +SvdSolver = SvdSolvDaskML | SvdSolvSkearn | SvdSolvPCACustom @_doc_params( @@ -109,6 +115,7 @@ def pca( `None` See `chunked` and `zero_center` descriptions to determine which class will be used. Depending on the class and the type of X different values for default will be set. + For sparse *dask* arrays, will use `'covariance_eigh'`. If *scikit-learn* :class:`~sklearn.decomposition.PCA` is used, will give `'arpack'`, if *scikit-learn* :class:`~sklearn.decomposition.TruncatedSVD` is used, will give `'randomized'`, if *dask-ml* :class:`~dask_ml.decomposition.PCA` or :class:`~dask_ml.decomposition.IncrementalPCA` is used, will give `'auto'`, @@ -124,7 +131,7 @@ def pca( `'auto'` chooses automatically depending on the size of the problem. `'tsqr'` - Only available with *dask* arrays. "tsqr" + Only available with dense *dask* arrays. "tsqr" algorithm from Benson et. al. (2013). .. versionchanged:: 1.9.3 @@ -135,7 +142,8 @@ def pca( Efficient computation of the principal components of a sparse matrix currently only works with the `'arpack`' or `'covariance_eigh`' solver. - If X is a *dask* array, *dask-ml* classes :class:`~dask_ml.decomposition.PCA`, + If X is a sparse *dask* array, a custom `'covariance_eigh'` solver will be used. + If X is a dense *dask* array, *dask-ml* classes :class:`~dask_ml.decomposition.PCA`, :class:`~dask_ml.decomposition.IncrementalPCA`, or :class:`~dask_ml.decomposition.TruncatedSVD` will be used. Otherwise their *scikit-learn* counterparts :class:`~sklearn.decomposition.PCA`, @@ -308,21 +316,40 @@ def pca( X, n_comps, solver=svd_solver, random_state=random_state ) else: - if isinstance(X, DaskArray): - from dask_ml.decomposition import PCA - - svd_solver = _handle_dask_ml_args(svd_solver, PCA) - else: + if not isinstance(X, DaskArray): from sklearn.decomposition import PCA svd_solver = _handle_sklearn_args(svd_solver, PCA, sparse=issparse(X)) + pca_ = PCA( + n_components=n_comps, + svd_solver=svd_solver, + random_state=random_state, + ) + elif issparse(X._meta): + from ._dask_sparse import PCASparseDask - pca_ = PCA( - n_components=n_comps, svd_solver=svd_solver, random_state=random_state - ) + if random_state != 0: + msg = f"Ignoring {random_state=} when using a sparse dask array" + warnings.warn(msg) + if svd_solver not in {None, "covariance_eigh"}: + msg = f"Ignoring {svd_solver=} when using a sparse dask array" + warnings.warn(msg) + pca_ = PCASparseDask(n_components=n_comps) + else: + from dask_ml.decomposition import PCA + + svd_solver = _handle_dask_ml_args(svd_solver, PCA) + pca_ = PCA( + n_components=n_comps, + svd_solver=svd_solver, + random_state=random_state, + ) X_pca = pca_.fit_transform(X) else: if isinstance(X, DaskArray): + if issparse(X._meta): + msg = "Dask sparse arrays do not support zero-centering (yet)" + raise TypeError(msg) from dask_ml.decomposition import TruncatedSVD svd_solver = _handle_dask_ml_args(svd_solver, TruncatedSVD) @@ -436,7 +463,7 @@ def _handle_dask_ml_args( def _handle_dask_ml_args( svd_solver: str | None, method: type[dmld.TruncatedSVD] ) -> SvdSolvTruncatedSVDDaskML: ... -def _handle_dask_ml_args(svd_solver: str | None, method: MethodDaskML) -> str: +def _handle_dask_ml_args(svd_solver: str | None, method: MethodDaskML) -> SvdSolvDaskML: import dask_ml.decomposition as dmld args: tuple[SvdSolvDaskML, ...] @@ -461,14 +488,14 @@ def _handle_sklearn_args( @overload def _handle_sklearn_args( svd_solver: str | None, method: type[skld.PCA], *, sparse: Literal[False] -) -> SvdSolvPCASklearn: ... +) -> SvdSolvPCADenseSklearn: ... @overload def _handle_sklearn_args( svd_solver: str | None, method: type[skld.PCA], *, sparse: Literal[True] ) -> SvdSolvPCASparseSklearn: ... def _handle_sklearn_args( svd_solver: str | None, method: MethodSklearn, *, sparse: bool | None = None -) -> str: +) -> SvdSolvSkearn: import sklearn.decomposition as skld args: tuple[SvdSolvSkearn, ...] @@ -479,7 +506,7 @@ def _handle_sklearn_args( args = get_args(SvdSolvTruncatedSVDSklearn) default = "randomized" case (skld.PCA, False): - args = get_args(SvdSolvPCASklearn) + args = get_args(SvdSolvPCADenseSklearn) default = "arpack" case (skld.PCA, True): args = get_args(SvdSolvPCASparseSklearn) diff --git a/src/scanpy/preprocessing/_pca/_dask_sparse.py b/src/scanpy/preprocessing/_pca/_dask_sparse.py new file mode 100644 index 0000000000..6123dadec5 --- /dev/null +++ b/src/scanpy/preprocessing/_pca/_dask_sparse.py @@ -0,0 +1,206 @@ +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import TYPE_CHECKING, cast, overload + +import numpy as np +import scipy.linalg +from numpy.typing import NDArray + +from scanpy._utils._doctests import doctest_needs + +from .._utils import _get_mean_var + +if TYPE_CHECKING: + from typing import Literal + + from numpy.typing import DTypeLike + from scipy import sparse + + from ..._compat import DaskArray + + CSMatrix = sparse.csr_matrix | sparse.csc_matrix + + +@dataclass +class PCASparseDask: + n_components: int | None = None + + @doctest_needs("dask") + def fit(self, x: DaskArray) -> PCASparseDaskFit: + """Fit the model on `x`. + + This method transforms `self` into a `PCASparseDaskFit` object and returns it. + + Examples + -------- + >>> import dask.array as da + >>> import scipy.sparse as sp + >>> x = ( + ... da.array(sp.random(100, 200, density=0.3, dtype="float32").toarray()) + ... .rechunk((10, -1)) + ... .map_blocks(sp.csr_matrix) + ... ) + >>> x + dask.array + >>> pca_fit = PCASparseDask().fit(x) + >>> assert isinstance(pca_fit, PCASparseDaskFit) + >>> pca_fit.transform(x) + dask.array + """ + self.__class__ = PCASparseDaskFit + self = cast(PCASparseDaskFit, self) + + self.n_components_ = ( + min(x.shape) if self.n_components is None else self.n_components + ) + self.n_samples_ = x.shape[0] + self.n_features_in_ = x.shape[1] if x.ndim > 1 else 1 + self.dtype_ = x.dtype + covariance, self.mean_ = _cov_sparse_dask(x) + self.explained_variance_, self.components_ = scipy.linalg.eigh( + covariance, lower=False + ) + + # Arrange eigenvectors and eigenvalues in descending order + self.explained_variance_ = self.explained_variance_[::-1] + self.components_ = np.flip(self.components_, axis=1) + self.components_ = self.components_.T[: self.n_components_, :] + + self.explained_variance_ratio_ = self.explained_variance_ / np.sum( + self.explained_variance_ + ) + if self.n_components_ < min(self.n_samples_, self.n_features_in_): + self.noise_variance_ = self.explained_variance_[self.n_components_ :].mean() + else: + self.noise_variance_ = np.array([0.0]) + self.explained_variance_ = self.explained_variance_[: self.n_components_] + + self.explained_variance_ratio_ = self.explained_variance_ratio_[ + : self.n_components_ + ] + return self + + def fit_transform(self, x: DaskArray, y: DaskArray | None = None) -> DaskArray: + if y is None: + y = x + return self.fit(x).transform(y) + + +@dataclass +class PCASparseDaskFit(PCASparseDask): + n_components_: int = field(init=False) + n_samples_: int = field(init=False) + n_features_in_: int = field(init=False) + dtype_: np.dtype = field(init=False) + mean_: NDArray[np.floating] = field(init=False) + components_: NDArray[np.floating] = field(init=False) + explained_variance_: NDArray[np.floating] = field(init=False) + explained_variance_ratio_: NDArray[np.floating] = field(init=False) + noise_variance_: NDArray[np.floating] = field(init=False) + + def transform(self, x: DaskArray) -> DaskArray: + if TYPE_CHECKING: + # The type checker does not understand imports from dask.array + import dask.array.core as da + else: + import dask.array as da + + def transform_block( + x_part: CSMatrix, + mean_: NDArray[np.floating], + components_: NDArray[np.floating], + ): + pre_mean = mean_ @ components_.T + mean_impact = np.ones((x_part.shape[0], 1)) @ pre_mean.reshape(1, -1) + return (x_part @ components_.T) - mean_impact + + return da.map_blocks( + transform_block, + x, + mean_=self.mean_, + components_=self.components_, + chunks=(x.chunks[0], self.n_components_), + meta=np.zeros([0], dtype=x.dtype), + dtype=x.dtype, + ) + + +@overload +def _cov_sparse_dask( + x: DaskArray, *, return_gram: Literal[False] = False, dtype: DTypeLike | None = None +) -> tuple[NDArray[np.floating], NDArray[np.floating]]: ... +@overload +def _cov_sparse_dask( + x: DaskArray, *, return_gram: Literal[True], dtype: DTypeLike | None = None +) -> tuple[NDArray[np.floating], NDArray[np.floating], NDArray[np.floating]]: ... +def _cov_sparse_dask( + x: DaskArray, *, return_gram: bool = False, dtype: DTypeLike | None = None +) -> ( + tuple[NDArray[np.floating], NDArray[np.floating], NDArray[np.floating]] + | tuple[NDArray[np.floating], NDArray[np.floating]] +): + """\ + Computes the covariance matrix and row/col means of matrix `x`. + + Parameters + ---------- + + x + A sparse matrix + return_gram + If `True`, the gram matrix will be returned and a copy will be created + to store the results of the covariance, + while if `False`, the local gram matrix result will be overwritten. + (only used for unit testing at the moment) + dtype + The data type of the result (excluding the means) + + Returns + ------- + + :math:`\\cov(X, X)` + The covariance matrix of `x` in the form :math:`\\cov(X, X) = \\E(XX) - \\E(X)\\E(X)`. + :math:`\\gram(X, X)` + When return_gram is `True`, the gram matrix of `x` in the form :math:`\\frac{1}{n} X.T \\dot X`. + :math:`\\mean(X)` + The row means of `x`. + """ + if TYPE_CHECKING: + import dask.array.core as da + import dask.base as dask + else: + import dask + import dask.array as da + + if dtype is None: + dtype = np.float64 if np.issubdtype(x.dtype, np.integer) else x.dtype + else: + dtype = np.dtype(dtype) + + def gram_block(x_part: CSMatrix): + gram_matrix: CSMatrix = x_part.T @ x_part + return gram_matrix.toarray()[None, ...] # need new axis for summing + + gram_matrix_dask: DaskArray = da.map_blocks( + gram_block, + x, + new_axis=(1,), + chunks=((1,) * x.blocks.size, (x.shape[1],), (x.shape[1],)), + meta=np.array([], dtype=x.dtype), + dtype=x.dtype, + ).sum(axis=0) + mean_x_dask, _ = _get_mean_var(x) + gram_matrix, mean_x = cast( + tuple[NDArray, NDArray[np.float64]], + dask.compute(gram_matrix_dask, mean_x_dask), + ) + gram_matrix = gram_matrix.astype(dtype) + gram_matrix /= x.shape[0] + + cov_result = gram_matrix.copy() if return_gram else gram_matrix + cov_result -= mean_x[:, None] @ mean_x[None, :] + + if return_gram: + return cov_result, gram_matrix, mean_x + return cov_result, mean_x diff --git a/src/testing/scanpy/_helpers/__init__.py b/src/testing/scanpy/_helpers/__init__.py index 449eef9c57..0c59eb592f 100644 --- a/src/testing/scanpy/_helpers/__init__.py +++ b/src/testing/scanpy/_helpers/__init__.py @@ -5,6 +5,8 @@ from __future__ import annotations import warnings +from contextlib import AbstractContextManager +from dataclasses import dataclass from itertools import permutations from typing import TYPE_CHECKING @@ -14,6 +16,8 @@ import scanpy as sc if TYPE_CHECKING: + from collections.abc import MutableSequence + from scanpy._compat import DaskArray # TODO: Report more context on the fields being compared on error @@ -138,3 +142,19 @@ def as_sparse_dask_array(*args, **kwargs) -> DaskArray: from anndata.tests.helpers import as_sparse_dask_array return as_sparse_dask_array(*args, **kwargs) + + +@dataclass(init=False) +class MultiContext(AbstractContextManager): + contexts: MutableSequence[AbstractContextManager] + + def __init__(self, *contexts: AbstractContextManager): + self.contexts = list(contexts) + + def __enter__(self): + for ctx in self.contexts: + ctx.__enter__() + + def __exit__(self, exc_type, exc_value, traceback): + for ctx in reversed(self.contexts): + ctx.__exit__(exc_type, exc_value, traceback) diff --git a/tests/test_pca.py b/tests/test_pca.py index 5dca5f2b8a..1439ea788d 100644 --- a/tests/test_pca.py +++ b/tests/test_pca.py @@ -3,7 +3,7 @@ import warnings from contextlib import nullcontext from functools import wraps -from typing import TYPE_CHECKING, Literal, cast, get_args +from typing import TYPE_CHECKING, Literal, get_args import anndata as ad import numpy as np @@ -16,23 +16,20 @@ from scipy.sparse import issparse import scanpy as sc +from scanpy._compat import DaskArray, pkg_version from scanpy.preprocessing._pca import SvdSolver as SvdSolverSupported +from scanpy.preprocessing._pca._dask_sparse import _cov_sparse_dask from testing.scanpy import _helpers from testing.scanpy._helpers.data import pbmc3k_normalized from testing.scanpy._pytest.marks import needs from testing.scanpy._pytest.params import ARRAY_TYPES as ARRAY_TYPES_ALL -from testing.scanpy._pytest.params import ( - ARRAY_TYPES_SPARSE_DASK_UNSUPPORTED, - param_with, -) +from testing.scanpy._pytest.params import param_with if TYPE_CHECKING: from collections.abc import Callable, Generator from anndata.typing import ArrayDataStructureType - from scanpy._compat import DaskArray - ArrayType = Callable[[np.ndarray], ArrayDataStructureType] @@ -70,6 +67,18 @@ ) +if pkg_version("anndata") < Version("0.9"): + + def to_memory(self: AnnData, *, copy: bool = False) -> AnnData: + """Compatibility version of AnnData.to_memory() that works with old AnnData versions""" + adata = self + if adata.isbacked: + adata = adata.to_memory() + return adata.copy() if copy else adata +else: + to_memory = AnnData.to_memory + + def _chunked_1d( f: Callable[[np.ndarray], DaskArray], ) -> Callable[[np.ndarray], DaskArray]: @@ -99,10 +108,12 @@ def maybe_convert_array_to_dask(array_type): ARRAY_TYPES = [ - param_with(at, maybe_convert_array_to_dask, marks=[needs.dask_ml]) - if "dask" in cast(str, at.id) - else at - for at in ARRAY_TYPES_SPARSE_DASK_UNSUPPORTED + param_with( + at, + maybe_convert_array_to_dask, + marks=[needs.dask_ml] if at.id == "dask_array_dense" else [], + ) + for at in ARRAY_TYPES_ALL ] @@ -120,18 +131,24 @@ def gen_pca_params( array_type: ArrayType, svd_solver_type: Literal[None, "valid", "invalid"], zero_center: bool, -) -> Generator[tuple[SVDSolver, str | None] | tuple[None, None], None, None]: +) -> Generator[tuple[SVDSolver | None, str | None, str | None], None, None]: + if array_type is DASK_CONVERTERS[_helpers.as_sparse_dask_array] and not zero_center: + xfail_reason = "Sparse-in-dask with zero_center=False not implemented yet" + yield None, None, xfail_reason + return if svd_solver_type is None: - yield None, None + yield None, None, None return all_svd_solvers = set(get_args(SVDSolver)) svd_solvers: set[SVDSolver] match array_type, zero_center: - case (dc, True) if dc in DASK_CONVERTERS.values(): + case (dc, True) if dc is DASK_CONVERTERS[_helpers.as_dense_dask_array]: svd_solvers = {"auto", "full", "tsqr", "randomized"} - case (dc, False) if dc in DASK_CONVERTERS.values(): + case (dc, False) if dc is DASK_CONVERTERS[_helpers.as_dense_dask_array]: svd_solvers = {"tsqr", "randomized"} + case (dc, True) if dc is DASK_CONVERTERS[_helpers.as_sparse_dask_array]: + svd_solvers = {"covariance_eigh"} case ((sparse.csr_matrix | sparse.csc_matrix), True): svd_solvers = {"arpack"} case ((sparse.csr_matrix | sparse.csc_matrix), False): @@ -141,15 +158,15 @@ def gen_pca_params( case (helpers.asarray, False): svd_solvers = {"arpack", "randomized"} case _: - pytest.fail(f"Unknown array type {array_type}") + pytest.fail(f"Unknown {array_type=} ({zero_center=})") if svd_solver_type == "invalid": svd_solvers = all_svd_solvers - svd_solvers - warn_pat_expected = r"Ignoring" + warn_pat_expected = r"Ignoring svd_solver" elif svd_solver_type == "valid": warn_pat_expected = None else: - pytest.fail(f"Unknown svd_solver_type {svd_solver_type}") + pytest.fail(f"Unknown {svd_solver_type=}") for svd_solver in svd_solvers: # explicit check for special case @@ -161,7 +178,7 @@ def gen_pca_params( pat = r"legacy code" else: pat = warn_pat_expected - yield (svd_solver, pat) + yield (svd_solver, pat, None) @pytest.mark.parametrize( @@ -172,13 +189,20 @@ def gen_pca_params( zero_center, svd_solver, warn_pat_expected, - marks=array_type.marks, - id=f"{array_type.id}-{'zero_center' if zero_center else 'no_zero_center'}-{svd_solver}-{warn_pat_expected}", + marks=( + array_type.marks + if xfail_reason is None + else [pytest.mark.xfail(reason=xfail_reason)] + ), + id=( + f"{array_type.id}-{'zero_center' if zero_center else 'no_zero_center'}-" + f"{svd_solver or svd_solver_type}-{'xfail' if xfail_reason else warn_pat_expected}" + ), ) for array_type in ARRAY_TYPES for zero_center in [True, False] for svd_solver_type in [None, "valid", "invalid"] - for svd_solver, warn_pat_expected in gen_pca_params( + for svd_solver, warn_pat_expected, xfail_reason in gen_pca_params( array_type=array_type.values[0], zero_center=zero_center, svd_solver_type=svd_solver_type, @@ -217,6 +241,7 @@ def test_pca_transform(array_type): warnings.filterwarnings("error") sc.pp.pca(adata, n_comps=4, zero_center=True, dtype="float64") + adata = to_memory(adata) assert np.linalg.norm(A_pca_abs[:, :4] - np.abs(adata.obsm["X_pca"])) < 2e-05 @@ -225,11 +250,20 @@ def test_pca_transform_randomized(array_type): A_pca_abs = np.abs(A_pca) warnings.filterwarnings("error") - with ( - pytest.warns(UserWarning, match="Ignoring.*'randomized'") - if sparse.issparse(adata.X) - else nullcontext() - ): + if isinstance(adata.X, DaskArray) and issparse(adata.X._meta): + patterns = ( + r"Ignoring random_state=14 when using a sparse dask array", + r"Ignoring svd_solver='randomized' when using a sparse dask array", + ) + ctx = _helpers.MultiContext( + *(pytest.warns(UserWarning, match=pattern) for pattern in patterns) + ) + elif sparse.issparse(adata.X): + ctx = pytest.warns(UserWarning, match=r"Ignoring.*'randomized") + else: + ctx = nullcontext() + + with ctx: sc.pp.pca( adata, n_comps=4, @@ -242,9 +276,12 @@ def test_pca_transform_randomized(array_type): assert np.linalg.norm(A_pca_abs[:, :4] - np.abs(adata.obsm["X_pca"])) < 2e-05 -def test_pca_transform_no_zero_center(array_type): +def test_pca_transform_no_zero_center(request: pytest.FixtureRequest, array_type): adata = AnnData(array_type(A_list).astype("float32")) A_svd_abs = np.abs(A_svd) + if isinstance(adata.X, DaskArray) and issparse(adata.X._meta): + reason = "TruncatedSVD is not supported for sparse Dask yet" + request.applymarker(pytest.mark.xfail(reason=reason)) warnings.filterwarnings("error") sc.pp.pca(adata, n_comps=4, zero_center=False, dtype="float64", random_state=14) @@ -308,14 +345,23 @@ def test_pca_reproducible(array_type): pbmc = pbmc3k_normalized() pbmc.X = array_type(pbmc.X) - a = sc.pp.pca(pbmc, copy=True, dtype=np.float64, random_state=42) - b = sc.pp.pca(pbmc, copy=True, dtype=np.float64, random_state=42) - c = sc.pp.pca(pbmc, copy=True, dtype=np.float64, random_state=0) + with ( + pytest.warns(UserWarning, match=r"Ignoring random_state.*sparse dask array") + if isinstance(pbmc.X, DaskArray) and issparse(pbmc.X._meta) + else nullcontext() + ): + a = sc.pp.pca(pbmc, copy=True, dtype=np.float64, random_state=42) + b = sc.pp.pca(pbmc, copy=True, dtype=np.float64, random_state=42) + c = sc.pp.pca(pbmc, copy=True, dtype=np.float64, random_state=0) assert_equal(a, b) + # Test that changing random seed changes result # Does not show up reliably with 32 bit computation - assert not np.array_equal(a.obsm["X_pca"], c.obsm["X_pca"]) + # sparse-in-dask doesn’t use a random seed, so it also doesn’t work there. + if not (isinstance(pbmc.X, DaskArray) and issparse(pbmc.X._meta)): + a, c = map(to_memory, [a, c]) + assert not np.array_equal(a.obsm["X_pca"], c.obsm["X_pca"]) def test_pca_chunked(): @@ -404,6 +450,7 @@ def test_mask_var_argument_equivalence(float_dtype, array_type): adata_w_mask.var["mask"] = mask_var sc.pp.pca(adata_w_mask, mask_var="mask", dtype=float_dtype) + adata, adata_w_mask = map(to_memory, [adata, adata_w_mask]) assert np.allclose( adata.X.toarray() if issparse(adata.X) else adata.X, adata_w_mask.X.toarray() if issparse(adata_w_mask.X) else adata_w_mask.X, @@ -470,8 +517,11 @@ def test_mask_defaults(array_type, float_dtype): with_var = sc.pp.pca(adata, copy=True, dtype=float_dtype) assert without_var.uns["pca"]["params"]["mask_var"] is None assert with_var.uns["pca"]["params"]["mask_var"] == "highly_variable" + without_var, with_var = map(to_memory, [without_var, with_var]) assert not np.array_equal(without_var.obsm["X_pca"], with_var.obsm["X_pca"]) + with_no_mask = sc.pp.pca(adata, mask_var=None, copy=True, dtype=float_dtype) + with_no_mask = to_memory(with_no_mask) assert np.array_equal(without_var.obsm["X_pca"], with_no_mask.obsm["X_pca"]) @@ -499,3 +549,54 @@ def test_pca_layer(): ) np.testing.assert_equal(X_adata.obsm["X_pca"], layer_adata.obsm["X_pca"]) np.testing.assert_equal(X_adata.varm["PCs"], layer_adata.varm["PCs"]) + + +# Skipping these tests during min-deps testing shouldn't be an issue because the sparse-in-dask feature is not available on anndata<0.10 anyway +needs_anndata_dask = pytest.mark.skipif( + pkg_version("anndata") < Version("0.10"), + reason="Old AnnData doesn’t have dask test helpers", +) + + +@needs.dask +@needs_anndata_dask +@pytest.mark.parametrize( + "other_array_type", + [lambda x: x.toarray(), DASK_CONVERTERS[_helpers.as_sparse_dask_array]], + ids=["dense-mem", "sparse-dask"], +) +def test_covariance_eigh_impls(other_array_type): + warnings.filterwarnings("error") + + adata_sparse_mem = pbmc3k_normalized()[:200, :100].copy() + adata_other = adata_sparse_mem.copy() + adata_other.X = other_array_type(adata_other.X) + + sc.pp.pca(adata_sparse_mem, svd_solver="covariance_eigh") + sc.pp.pca(adata_other, svd_solver="covariance_eigh") + + to_memory(adata_other) + np.testing.assert_allclose( + np.abs(adata_sparse_mem.obsm["X_pca"]), np.abs(adata_other.obsm["X_pca"]) + ) + + +@needs.dask +@needs_anndata_dask +@pytest.mark.parametrize( + ("dtype", "dtype_arg", "rtol"), + [ + pytest.param(np.float32, None, 1e-5, id="float32"), + pytest.param(np.float32, np.float64, None, id="float32-float64"), + pytest.param(np.float64, None, None, id="float64"), + pytest.param(np.int64, None, None, id="int64"), + ], +) +def test_cov_sparse_dask(dtype, dtype_arg, rtol): + x_arr = A_list.astype(dtype) + x = DASK_CONVERTERS[_helpers.as_sparse_dask_array](x_arr) + cov, gram, mean = _cov_sparse_dask(x, return_gram=True, dtype=dtype_arg) + np.testing.assert_allclose(mean, np.mean(x_arr, axis=0)) + np.testing.assert_allclose(gram, (x_arr.T @ x_arr) / x.shape[0]) + tol_args = dict(rtol=rtol) if rtol is not None else {} + np.testing.assert_allclose(cov, np.cov(x_arr, rowvar=False, bias=True), **tol_args) From 392015405c088c81ed2038b6697b248087507648 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Mon, 21 Oct 2024 14:29:41 +0200 Subject: [PATCH 063/118] Fix HVG with 1-obs batches (#3286) --- docs/release-notes/3286.bugfix.md | 1 + src/scanpy/preprocessing/_utils.py | 3 ++- tests/test_highly_variable_genes.py | 8 ++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 docs/release-notes/3286.bugfix.md diff --git a/docs/release-notes/3286.bugfix.md b/docs/release-notes/3286.bugfix.md new file mode 100644 index 0000000000..164758a2fa --- /dev/null +++ b/docs/release-notes/3286.bugfix.md @@ -0,0 +1 @@ +Fix {func}`scanpy.pp.highly_variable_genes` for batches of size 1 {smaller}`P Angerer` diff --git a/src/scanpy/preprocessing/_utils.py b/src/scanpy/preprocessing/_utils.py index 64adb036d9..f5ba280cfd 100644 --- a/src/scanpy/preprocessing/_utils.py +++ b/src/scanpy/preprocessing/_utils.py @@ -40,7 +40,8 @@ def _get_mean_var( mean_sq = axis_mean(elem_mul(X, X), axis=axis, dtype=np.float64) var = mean_sq - mean**2 # enforce R convention (unbiased estimator) for variance - var *= X.shape[axis] / (X.shape[axis] - 1) + if X.shape[axis] != 1: + var *= X.shape[axis] / (X.shape[axis] - 1) return mean, var diff --git a/tests/test_highly_variable_genes.py b/tests/test_highly_variable_genes.py index 0f08b853e0..7d9fdac9fa 100644 --- a/tests/test_highly_variable_genes.py +++ b/tests/test_highly_variable_genes.py @@ -557,6 +557,14 @@ def test_batches(): assert np.all(np.isin(colnames, hvg1.columns)) +def test_degenerate_batches(): + adata = AnnData( + X=np.random.randn(10, 100), + obs=dict(batch=pd.Categorical([*([1] * 4), *([2] * 5), 3])), + ) + sc.pp.highly_variable_genes(adata, batch_key="batch") + + @needs.skmisc def test_seurat_v3_mean_var_output_with_batchkey(): pbmc = pbmc3k() From f804367b0e249e8d672f973093f9d6a9e228410e Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Mon, 21 Oct 2024 16:26:01 +0200 Subject: [PATCH 064/118] Allow specifying a collection of colors to scatterplots (#3299) Co-authored-by: Ilan Gold Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- docs/release-notes/3299.bugfix.md | 1 + src/scanpy/plotting/_anndata.py | 135 +++++++++++------- .../expected.png | Bin 0 -> 32286 bytes tests/test_plotting.py | 31 ++-- tests/test_plotting_utils.py | 33 ++++- 5 files changed, 125 insertions(+), 75 deletions(-) create mode 100644 docs/release-notes/3299.bugfix.md create mode 100644 tests/_images/scatter_HES_percent_mito_n_genes_bulk_labels/expected.png diff --git a/docs/release-notes/3299.bugfix.md b/docs/release-notes/3299.bugfix.md new file mode 100644 index 0000000000..1b0b512ad2 --- /dev/null +++ b/docs/release-notes/3299.bugfix.md @@ -0,0 +1 @@ +Fix {func}`scanpy.pl.scatter`’s `color` parameter to take collections as advertised {smaller}`P Angerer` diff --git a/src/scanpy/plotting/_anndata.py b/src/scanpy/plotting/_anndata.py index aadd0ac6ac..f3474fe27b 100755 --- a/src/scanpy/plotting/_anndata.py +++ b/src/scanpy/plotting/_anndata.py @@ -6,7 +6,7 @@ from collections.abc import Collection, Mapping, Sequence from itertools import product from types import NoneType -from typing import TYPE_CHECKING, get_args +from typing import TYPE_CHECKING, cast, get_args import matplotlib as mpl import numpy as np @@ -31,6 +31,7 @@ doc_vboundnorm, ) from ._utils import ( + ColorLike, _deprecated_scale, _dk, check_colornorm, @@ -47,12 +48,12 @@ from cycler import Cycler from matplotlib.axes import Axes from matplotlib.colors import Colormap, ListedColormap, Normalize + from numpy.typing import NDArray from seaborn import FacetGrid from seaborn.matrix import ClusterGrid from .._utils import Empty from ._utils import ( - ColorLike, DensityNorm, _FontSize, _FontWeight, @@ -90,7 +91,7 @@ def scatter( x: str | None = None, y: str | None = None, *, - color: str | Collection[str] | None = None, + color: str | ColorLike | Collection[str | ColorLike] | None = None, use_raw: bool | None = None, layers: str | Collection[str] | None = None, sort_order: bool = True, @@ -110,7 +111,7 @@ def scatter( left_margin: float | None = None, size: int | float | None = None, marker: str | Sequence[str] = ".", - title: str | None = None, + title: str | Collection[str] | None = None, show: bool | None = None, save: str | bool | None = None, ax: Axes | None = None, @@ -148,33 +149,25 @@ def scatter( ------- If `show==False` a :class:`~matplotlib.axes.Axes` or a list of it. """ + # color can be a obs column name or a matplotlib color specification (or a collection thereof) + if color is not None: + color = cast( + Collection[str | ColorLike], + [color] if isinstance(color, str) or is_color_like(color) else color, + ) args = locals() - if _check_use_raw(adata, use_raw): - var_index = adata.raw.var.index - else: - var_index = adata.var.index + if basis is not None: return _scatter_obs(**args) if x is None or y is None: raise ValueError("Either provide a `basis` or `x` and `y`.") - if ( - (x in adata.obs.columns or x in var_index) - and (y in adata.obs.columns or y in var_index) - and (color is None or color in adata.obs.columns or color in var_index) - ): + if _check_if_annotations(adata, "obs", x=x, y=y, colors=color, use_raw=use_raw): return _scatter_obs(**args) - if ( - (x in adata.var.columns or x in adata.obs.index) - and (y in adata.var.columns or y in adata.obs.index) - and (color is None or color in adata.var.columns or color in adata.obs.index) - ): - adata_T = adata.T - axs = _scatter_obs( - adata=adata_T, - **{name: val for name, val in args.items() if name != "adata"}, - ) + if _check_if_annotations(adata, "var", x=x, y=y, colors=color, use_raw=use_raw): + args_t = {**args, "adata": adata.T} + axs = _scatter_obs(**args_t) # store .uns annotations that were added to the new adata object - adata.uns = adata_T.uns + adata.uns = args_t["adata"].uns return axs raise ValueError( "`x`, `y`, and potential `color` inputs must all " @@ -182,35 +175,74 @@ def scatter( ) +def _check_if_annotations( + adata: AnnData, + axis_name: Literal["obs", "var"], + *, + x: str | None = None, + y: str | None = None, + colors: Collection[str | ColorLike] | None = None, + use_raw: bool | None = None, +) -> bool: + """Checks if `x`, `y`, and `colors` are annotations of `adata`. + In the case of `colors`, valid matplotlib colors are also accepted. + + If `axis_name` is `obs`, checks in `adata.obs.columns` and `adata.var_names`, + if `axis_name` is `var`, checks in `adata.var.columns` and `adata.obs_names`. + """ + annotations: pd.Index[str] = getattr(adata, axis_name).columns + other_ax_obj = ( + adata.raw if _check_use_raw(adata, use_raw) and axis_name == "obs" else adata + ) + names: pd.Index[str] = getattr( + other_ax_obj, "var" if axis_name == "obs" else "obs" + ).index + + def is_annotation(needle: pd.Index) -> NDArray[np.bool]: + return needle.isin({None}) | needle.isin(annotations) | needle.isin(names) + + if not is_annotation(pd.Index([x, y])).all(): + return False + + color_idx = pd.Index(colors if colors is not None else []) + # Colors are valid + color_valid: NDArray[np.bool] = np.fromiter( + map(is_color_like, color_idx), dtype=np.bool, count=len(color_idx) + ) + # Annotation names are valid too + color_valid[~color_valid] = is_annotation(color_idx[~color_valid]) + return bool(color_valid.all()) + + def _scatter_obs( *, adata: AnnData, - x=None, - y=None, - color=None, - use_raw=None, - layers=None, - sort_order=True, - alpha=None, - basis=None, - groups=None, - components=None, + x: str | None = None, + y: str | None = None, + color: Collection[str | ColorLike] | None = None, + use_raw: bool | None = None, + layers: str | Collection[str] | None = None, + sort_order: bool = True, + alpha: float | None = None, + basis: _Basis | None = None, + groups: str | Iterable[str] | None = None, + components: str | Collection[str] | None = None, projection: Literal["2d", "3d"] = "2d", legend_loc: _LegendLoc | None = "right margin", - legend_fontsize=None, - legend_fontweight=None, - legend_fontoutline=None, - color_map=None, - palette=None, - frameon=None, - right_margin=None, - left_margin=None, + legend_fontsize: int | float | _FontSize | None = None, + legend_fontweight: int | _FontWeight | None = None, + legend_fontoutline: float | None = None, + color_map: str | Colormap | None = None, + palette: Cycler | ListedColormap | ColorLike | Sequence[ColorLike] | None = None, + frameon: bool | None = None, + right_margin: float | None = None, + left_margin: float | None = None, size: int | float | None = None, - marker=".", - title=None, - show=None, - save=None, - ax=None, + marker: str | Sequence[str] = ".", + title: str | Collection[str] | None = None, + show: bool | None = None, + save: str | bool | None = None, + ax: Axes | None = None, ) -> Axes | list[Axes] | None: """See docstring of scatter.""" sanitize_anndata(adata) @@ -245,14 +277,7 @@ def _scatter_obs( if isinstance(components, str): components = components.split(",") components = np.array(components).astype(int) - 1 - # color can be a obs column name or a matplotlib color specification - keys = ( - ["grey"] - if color is None - else [color] - if isinstance(color, str) or is_color_like(color) - else color - ) + keys = ["grey"] if color is None else color if title is not None and isinstance(title, str): title = [title] highlights = adata.uns.get("highlights", []) diff --git a/tests/_images/scatter_HES_percent_mito_n_genes_bulk_labels/expected.png b/tests/_images/scatter_HES_percent_mito_n_genes_bulk_labels/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..2609a53567e96d603c53f09bde0b205ccbfb8633 GIT binary patch literal 32286 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 F{{rDuc})NS literal 0 HcmV?d00001 diff --git a/tests/test_plotting.py b/tests/test_plotting.py index b34db78780..efdfe26fcd 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -1337,7 +1337,9 @@ def test_scatter_specify_layer_and_raw(): sc.pl.umap(pbmc, color="HES4", use_raw=True, layer="layer") -@pytest.mark.parametrize("color", ["n_genes", "bulk_labels"]) +@pytest.mark.parametrize( + "color", ["n_genes", "bulk_labels", ["n_genes", "bulk_labels"]] +) def test_scatter_no_basis_per_obs(image_comparer, color): """Test scatterplot of per-obs points with no basis""" @@ -1353,7 +1355,8 @@ def test_scatter_no_basis_per_obs(image_comparer, color): # palette only applies to categorical, i.e. color=='bulk_labels' palette="Set2", ) - save_and_compare_images(f"scatter_HES_percent_mito_{color}") + color_str = color if isinstance(color, str) else "_".join(color) + save_and_compare_images(f"scatter_HES_percent_mito_{color_str}") def test_scatter_no_basis_per_var(image_comparer): @@ -1373,29 +1376,19 @@ def pbmc_filtered() -> Callable[[], AnnData]: return pbmc.copy -def test_scatter_no_basis_raw(check_same_image, pbmc_filtered, tmpdir): - adata = pbmc_filtered() - +@pytest.mark.parametrize("use_raw", [True, None]) +def test_scatter_no_basis_raw(check_same_image, pbmc_filtered, tmp_path, use_raw): """Test scatterplots of raw layer with no basis.""" - path1 = tmpdir / "scatter_EGFL7_F12_FAM185A_rawNone.png" - path2 = tmpdir / "scatter_EGFL7_F12_FAM185A_rawTrue.png" - path3 = tmpdir / "scatter_EGFL7_F12_FAM185A_rawToAdata.png" + adata = pbmc_filtered() - sc.pl.scatter(adata, x="EGFL7", y="F12", color="FAM185A", use_raw=None) - plt.savefig(path1) - plt.close() + sc.pl.scatter(adata.raw.to_adata(), x="EGFL7", y="F12", color="FAM185A") + plt.savefig(path1 := tmp_path / "scatter-raw-to-adata.png") - # is equivalent to: - sc.pl.scatter(adata, x="EGFL7", y="F12", color="FAM185A", use_raw=True) - plt.savefig(path2) + sc.pl.scatter(adata, x="EGFL7", y="F12", color="FAM185A", use_raw=use_raw) + plt.savefig(path2 := tmp_path / f"scatter-{use_raw=}.png") plt.close() - # and also to: - sc.pl.scatter(adata.raw.to_adata(), x="EGFL7", y="F12", color="FAM185A") - plt.savefig(path3) - check_same_image(path1, path2, tol=15) - check_same_image(path1, path3, tol=15) @pytest.mark.parametrize( diff --git a/tests/test_plotting_utils.py b/tests/test_plotting_utils.py index 6b53cd5b50..2090ffde38 100644 --- a/tests/test_plotting_utils.py +++ b/tests/test_plotting_utils.py @@ -1,6 +1,7 @@ from __future__ import annotations -from typing import cast +from string import ascii_lowercase, ascii_uppercase +from typing import TYPE_CHECKING, cast import numpy as np import pytest @@ -8,8 +9,13 @@ from matplotlib import colormaps from matplotlib.colors import ListedColormap +from scanpy.plotting._anndata import _check_if_annotations from scanpy.plotting._utils import _validate_palette +if TYPE_CHECKING: + from typing import Any, Literal + + viridis = cast(ListedColormap, colormaps["viridis"]) @@ -27,3 +33,28 @@ def test_validate_palette_no_mod(palette, typ): adata = AnnData(uns=dict(test_colors=palette)) _validate_palette(adata, "test") assert palette is adata.uns["test_colors"], "Palette should not be modified" + + +@pytest.mark.parametrize( + ("axis_name", "args", "expected"), + [ + pytest.param("obs", {}, True, id="valid-nothing"), + pytest.param("obs", dict(x="B", colors=["obs_a"]), True, id="valid-basic"), + pytest.param("var", dict(colors=["A", "C", "obs_a"]), False, id="invalid-axis"), + pytest.param("obs", dict(x="A"), True, id="valid-raw"), + pytest.param("obs", dict(x="A", use_raw=False), False, id="invalid-noraw"), + pytest.param("obs", dict(colors=[(0, 0, 0), "red"]), True, id="valid-color"), + ], +) +def test_check_all_in_axis( + *, axis_name: Literal["obs", "var"], args: dict[str, Any], expected: bool +): + raw = AnnData( + np.random.randn(10, 20), + dict(obs_a=range(10), obs_names=list(ascii_lowercase[:10])), + dict(var_a=range(20), var_names=list(ascii_uppercase[:20])), + ) + adata = raw[:, 1:].copy() + adata.raw = raw + + assert _check_if_annotations(adata, axis_name, **args) is expected From 3b68bab81fd649317be0145ae9e2b74d625a03fd Mon Sep 17 00:00:00 2001 From: Ilan Gold Date: Tue, 22 Oct 2024 10:49:31 +0200 Subject: [PATCH 065/118] (fix): correct anndata release for `io` usage (#3298) --- src/scanpy/__init__.py | 2 +- src/scanpy/readwrite.py | 2 +- src/testing/scanpy/_pytest/fixtures/data.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/scanpy/__init__.py b/src/scanpy/__init__.py index ae56a974f3..bbcc86437b 100644 --- a/src/scanpy/__init__.py +++ b/src/scanpy/__init__.py @@ -33,7 +33,7 @@ import anndata -if Version(anndata.__version__) >= Version("0.11.0rc0"): +if Version(anndata.__version__) >= Version("0.11.0rc2"): from anndata.io import ( read_csv, read_excel, diff --git a/src/scanpy/readwrite.py b/src/scanpy/readwrite.py index 3fbf8ef61c..cb75eb10cc 100644 --- a/src/scanpy/readwrite.py +++ b/src/scanpy/readwrite.py @@ -12,7 +12,7 @@ import pandas as pd from packaging.version import Version -if Version(anndata.__version__) >= Version("0.11.0rc0"): +if Version(anndata.__version__) >= Version("0.11.0rc2"): from anndata.io import ( read_csv, read_excel, diff --git a/src/testing/scanpy/_pytest/fixtures/data.py b/src/testing/scanpy/_pytest/fixtures/data.py index 4e5762f6cb..4d44d8239b 100644 --- a/src/testing/scanpy/_pytest/fixtures/data.py +++ b/src/testing/scanpy/_pytest/fixtures/data.py @@ -17,7 +17,7 @@ BaseCompressedSparseDataset as SparseDataset, ) - if Version(anndata_version) >= Version("0.11.0rc0"): + if Version(anndata_version) >= Version("0.11.0rc2"): from anndata.io import sparse_dataset else: from anndata.experimental import sparse_dataset From c2a615bfd16ead37c048aa8fb3a0205866936704 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 22 Oct 2024 13:30:46 +0200 Subject: [PATCH 066/118] [pre-commit.ci] pre-commit autoupdate (#3274) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cd0dd7072f..75b40177d2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.8 + rev: v0.7.0 hooks: - id: ruff types_or: [python, pyi, jupyter] @@ -20,7 +20,7 @@ repos: - --sort-by-bibkey - --drop=abstract - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: v5.0.0 hooks: - id: trailing-whitespace exclude: tests/_data From f8608291dde7b27a107fe0983e16242ea133e4fc Mon Sep 17 00:00:00 2001 From: Ilan Gold Date: Tue, 22 Oct 2024 14:24:32 +0200 Subject: [PATCH 067/118] (fix): clarify sparse pca usage (#3306) * (fix): clarify sparse pca usage * (chore): clarify release note * (fix): docstring grammar * do spaces correctly * Update src/scanpy/preprocessing/_pca/_dask_sparse.py --------- Co-authored-by: Philipp A. --- docs/release-notes/3267.feature.md | 2 +- src/scanpy/preprocessing/_pca/__init__.py | 1 + src/scanpy/preprocessing/_pca/_dask_sparse.py | 13 +++++++++++ tests/test_pca.py | 23 +++++++++++++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/3267.feature.md b/docs/release-notes/3267.feature.md index ea4a5c6080..6ea7fb20a2 100644 --- a/docs/release-notes/3267.feature.md +++ b/docs/release-notes/3267.feature.md @@ -1 +1 @@ -Use upstreamed {class}`~sklearn.decomposition.PCA` implementation for {class}`~scipy.sparse.sparray` and {class}`~scipy.sparse.spmatrix` (see {ref}`sklearn:changes_1_4`) {smaller}`P Angerer` +Use upstreamed {class}`~sklearn.decomposition.PCA` implementation for {class}`~scipy.sparse.csr_array` and {class}`~scipy.sparse.csr_matrix` (see {ref}`sklearn:changes_1_4`) {smaller}`P Angerer` diff --git a/src/scanpy/preprocessing/_pca/__init__.py b/src/scanpy/preprocessing/_pca/__init__.py index 396781ce7a..354848ea7d 100644 --- a/src/scanpy/preprocessing/_pca/__init__.py +++ b/src/scanpy/preprocessing/_pca/__init__.py @@ -125,6 +125,7 @@ def pca( Not available with *dask* arrays. `'covariance_eigh'` Classic eigendecomposition of the covariance matrix, suited for tall-and-skinny matrices. + With dask, array must be CSR and chunked as (N, adata.shape[1]). `'randomized'` for the randomized algorithm due to Halko (2009). For *dask* arrays, this will use :func:`~dask.array.linalg.svd_compressed`. diff --git a/src/scanpy/preprocessing/_pca/_dask_sparse.py b/src/scanpy/preprocessing/_pca/_dask_sparse.py index 6123dadec5..c2bff7ccca 100644 --- a/src/scanpy/preprocessing/_pca/_dask_sparse.py +++ b/src/scanpy/preprocessing/_pca/_dask_sparse.py @@ -48,6 +48,19 @@ def fit(self, x: DaskArray) -> PCASparseDaskFit: >>> pca_fit.transform(x) dask.array """ + if x._meta.format != "csr": + msg = ( + "Only dask arrays with CSR-meta format are supported. " + f"Got {x._meta.format} as meta." + ) + raise ValueError(msg) + if x.chunksize[1] != x.shape[1]: + msg = ( + "Only dask arrays with chunking along the first axis are supported. " + f"Got chunksize {x.chunksize} with shape {x.shape}. " + "Rechunking should be simple and cost nothing from AnnData's on-disk format when the on-disk layout has this chunking." + ) + raise ValueError(msg) self.__class__ = PCASparseDaskFit self = cast(PCASparseDaskFit, self) diff --git a/tests/test_pca.py b/tests/test_pca.py index 1439ea788d..6fc8eafd43 100644 --- a/tests/test_pca.py +++ b/tests/test_pca.py @@ -581,6 +581,29 @@ def test_covariance_eigh_impls(other_array_type): ) +@needs.dask +@needs_anndata_dask +@pytest.mark.parametrize( + ("msg_re", "op"), + [ + ( + r"Only dask arrays with CSR-meta", + lambda a: a.map_blocks( + sparse.csc_matrix, meta=sparse.csc_matrix(np.array([])) + ), + ), + (r"Only dask arrays with chunking", lambda a: a.rechunk((a.shape[0], 100))), + ], + ids=["as-csc", "bad-chunking"], +) +def test_sparse_dask_input_errors(msg_re: str, op: Callable[[DaskArray], DaskArray]): + adata_sparse = pbmc3k_normalized() + adata_sparse.X = op(DASK_CONVERTERS[_helpers.as_sparse_dask_array](adata_sparse.X)) + + with pytest.raises(ValueError, match=msg_re): + sc.pp.pca(adata_sparse, svd_solver="covariance_eigh") + + @needs.dask @needs_anndata_dask @pytest.mark.parametrize( From a38bf01893f70f8f0dacf1dd15bdeca28f8fe037 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Tue, 22 Oct 2024 15:53:21 +0200 Subject: [PATCH 068/118] Fix sc.pl.highest_expr_genes with a categorical column (#3302) --- docs/release-notes/3302.bugfix.md | 1 + src/scanpy/plotting/_qc.py | 2 +- tests/_images/highest_expr_genes/expected.png | Bin 0 -> 11545 bytes tests/test_plotting.py | 11 +++++++++++ 4 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 docs/release-notes/3302.bugfix.md create mode 100644 tests/_images/highest_expr_genes/expected.png diff --git a/docs/release-notes/3302.bugfix.md b/docs/release-notes/3302.bugfix.md new file mode 100644 index 0000000000..00d2468dad --- /dev/null +++ b/docs/release-notes/3302.bugfix.md @@ -0,0 +1 @@ +Fix {func}`scanpy.pl.highest_expr_genes` when used with a categorical gene symbol column {smaller}`P Angerer` diff --git a/src/scanpy/plotting/_qc.py b/src/scanpy/plotting/_qc.py index e37276f4b6..dc89e3c064 100644 --- a/src/scanpy/plotting/_qc.py +++ b/src/scanpy/plotting/_qc.py @@ -86,7 +86,7 @@ def highest_expr_genes( columns = ( adata.var_names[top_idx] if gene_symbols is None - else adata.var[gene_symbols][top_idx] + else adata.var[gene_symbols].iloc[top_idx].astype("string") ) counts_top_genes = pd.DataFrame( counts_top_genes, index=adata.obs_names, columns=columns diff --git a/tests/_images/highest_expr_genes/expected.png b/tests/_images/highest_expr_genes/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..1df4b95ff29b5ec5ee094de121b2b19493af1041 GIT binary patch literal 11545 zcmch7cRZEx+rLd@ud-8SNFkhz?7dgnWbc`hEk&~T4k3h;P4>>-duC_v{an7^=k@&g z`}6mQ&g;av&wXE?YrMx5q^u}~i%o%zgoK1EBQ359ukG+Ng@pnC^3ZM(!wbKQ#0wWS zdovd|BPUZN1tS*+8+#WUOJlm%rcTb5_I6wx{2Wi%=qy}Z9Gnr49@+liA8^<^nLoOx zh&m1zx#b}J(isT}gX!i6SwVfQ4GD?ugN(R{`kUm(eJ}+0Tn) z+@YCx7!N+7-8K%!|)$o}%BKF71{jQRl|U%W3W<`bvC z(rJg4TTwCG7J2{5v@G(2R01Y#@jrc<%PODQNf7jVNB-8!OUS7*8I#r{yy+wUe*66} zhqD9A))2~%@{EgV*B4A-f=BT#&lMH%7TdyBHj3&bi$+m*#$JV~XlO{pap>K7YV#tW za{5cIv81wA^=8tap{~Hv*;)H@D#glXqMxSmDwisUd4wt|2}hb zeR_dJf{lKDylsB4+Mmql=qC|O<~UdHOZLp%#AIjOJgwMmTYszW+Do04RM7o^j*abe z@vFA7vFnrF#pGvhJ?Y4!h0{q|`_`j{>BCn27Tl{Yh!SmfL<*jNgO7fZRL84Dcr#ao&l4YO9U&&USp!+T>3xJ6G+= zLhw}0+bGZTBNc7!PRIiD+RGyyh{{8)!oNXGsdMumX|qd8qHi8quljYmYVOJT>~+sn zrLziajK|qpj>qNUD4RiTvP!0;3=^N%1)tCK#{=8RvfU}?-b&MhJU3y7i`!1S1{dkG zhSi%ol!d!z8R&K?gL-AQldTnwi=20E4?K_hvo!E?ZQ+&n=*HoIVFbMM!T9=0;W`Q9 z!{KXU_un%a_#3{~GjJq~lUjEyEC!IvB~z`Fg)+W+$C%eTN0PB{mBCoM!^A19h^fX86A0yj6eA?KYphr?Pd z4}@o1sm(D3l?AA_sNt?6piACPp63W?3fv);Xdg!fNQ zSJHO(_oF5}yUEko(nZvep9dUaJkC=NhA+FL@3oPl$zT4(c_A(-NzT}q9%A~nurRbh zr~Ie$iXxn66Dqzy{my)orJda}yj(1h*U|Cw-}UjnSfurUDuL2)+!$e3RZ~0t8>JK& z8v1$?ON+-JLjk=PeR{6)3+4N@Lb*TL-i#}|hi}nS$m{z0l!=IlPB!hm<;=_&B{KhI?&HE}Lgpzk4U+Ym~QWC$*D#5GP&&Y;QWdFv0ecWAaBffKo z*>&p^9?E7;fNrHzKx8D*kQI-FghX_7w6dn=2knBgKGq?tQtsf4ehWCg$PY%1BU3fM zD!sH0(50NOmp4=Aa%=k&!c#@ukN$O}3cicyGRK3Qyja(&qi10W3KKdDBxX|VD>4u! zW7lq$d-S{c>hiqOVIF0rH_d#u*7G*4P;#MOwbR~T8Hn}YGQvWud!!ST1b-{0H9VUP zIe$R#UT;mU4O|%+8F}oskl$1Q8YZTimX;J$&Sbegrp4oxZJWYbQqP9|sk*f{nf=o4 z?p2eCJ~?NS=1mKa3@V)%`uqD$Oid$VVp_t4uiBM_FPoul^#n; zTo7OGPHIzA5^RCCS^tsN3$BAO?@7M*_%We_XBC{JT~`8E+nU$ISx=k_qjEt>(sfng z<%>4&3ry?)loUlKOH8Lqsu)=YJrP#~wTg;L`;ybZ;Gjyb`hY;K<<1NI2LYn<%2-eU zc$jHxx<^Mmwp{Gh!4Frq|Meg%x`acU@bmNA+26k?c%!wPtw)NZReMebr~f+q+HDt6 zw_$!-^Q+)qG%uOw!cW`Oz-Yfvxugv`ThhOO*XeLSeKJZ~K5`1#D-(NBUfv2R5?8%` z#ggrSZriQ5NN26Z_O8Yo)e8KTSI#S_Jv3ArBJNA^IsFZk zJI_~Vy*eAMdty7m4L6%0`0i_Xkj zMyS2j!5sYD++2aP)l8(XU%wKNk(m|OJ>2j2$HaeaS>?KWUc@)e#Hzbiri}H&teXM@ zpXT2PwMknj^*43aCr_UIn-TH2S9YtR(9`i$E$x|G;dGf4&0BHpRAKL09Sj#V_JtU& z+`7BCL@`T1|(ee#}0(EW>M{&=<9qh7&d-QX1h z`%{+|Q9Jc%GOUOBuHsiZRJTI{7sDDY(F){os2@CgmUPoj-4CtG>}PwRVZJ$@cH{Rv z;|4f^@+CdpcVIwOF--`!{-^1mcupgfU^4c-b}T7Gb4Z>OhU8UyeLHQ$+9SC?j5&_w z!oKy?HrN5z7c0WZ;Tsr6iFQGBJZ^XijuxS>SPFSkFCD(n3EfIhN|OaQ5d}pj^hR4V?UL5%+oD#bi7RQ| zsm;ye)n^i>rFitV_T_H!`ueHe)qxNVF0QEA%PqI53P=CxYBxExsv`n~_)6hj8M;yHeVh68@HLNh&VfQ|A0@csH;l_Pq>i&k>=-WTLRud zfevq(&3NO{=H%u&Ic;~jAUfsR^Zggqui5LaFSmn2LnYIdr3ZgNBMA^~fWKltz>~tF z&Tt-F(BWOXX(s9#(=3lUO*=`lJO#clgb zt+n7tZOipI;;R2rEuZ5cn1s%k1s(B-Lz^4>0{MC_b*?#CU6S)_xPq5tyit6gxtz#l z#&?pIFi}s4Xck=D*{sWP&d+ldfB#TLqIvg>a=ZMOsb7zu()&hKOgx9(1&JH##johARF1g(vNqur#f*$lF*;!fXqZ?TSy2LXW@(kX6KbKwK1isNE8@CSHt_Yfe>j-m`F}k~1r1()aUtBkEu(uQuHUTUf;^?)aq=Zb}+8x`2 zD%y_k61C_o9wH9xQPSP8CMfw&B+o0Hmaw%8Vv$iXPP!^c9|~u$&x#tkmWJ+lW6DX0 zH}7UU(1=jZVb=Bwsj8}u)x7;RiNQC(mY3IgD~z2^pv>n(>z@Iq7=J?+b5CrvExI+j z87tbu!$WZi2^Bp(_RT?kMEh{QR!4WYME-DwWozqyENQO({bh0RwjpGYAaHVj#O#>QSqhEOcI2s@iQEZ@bKgx5nn`J(M&?iUWpQP8^l4Dy!;aOL=xU2-5*U)`Ti`N_Yz~Fq+xhr zi%LZ}9|=p??fx?)uTR>9caD#9a&vF_q>FtVn40>hVVb)!yfk!&gLtG#@!T}5nhZ;z z)fTg(r)OEK?u?X>knpAoYK~{#iAzfUbU$1t!&{I=P8nfsNsf#ZRZ}AdimZz|QR9AZX;`aYV>sh8);$h^*kc1?OKEi5 z;O?3i%VRj%+I3!nySuxeDR@3DFPmj#WZdDlAjsD&aQcJvu0a7l$v=C{#KCJY?=hRk zTvWS0vWw#T$YGt%@L9Z7-xm>&)1|m%fwz(M_0K=xQcCLSQG1>pM1)!g`{Z6+c(91* zzI=HXz_~@KHaA7cfl|?^++cB8WNj%az4H22Q3Ki`#46H2*7%=p8+m&R*9X%=Y)U7qwo9k#_+S5xsoz4V>B>+`z) zH5cX>S%45QugJ8l2VZYw@Z0h$2Ozn*EgVe#B$wv_{!HV2;rL&i>ztQ2*`$;1Q164x z{sb}6nBwzoM3k>>`lHtD3kQcEqZnhv2Mdj_(y?5;N|}T0dW|ccYo5dT{bNv&U&BVA zP!EU*>HkjNTi;mCD`CE`j?^3=wSQ&pOijy7aB?T@R)G8O)S|kpM0n08ChY`8pIM7) zd%}KST8vE97r8ZWhO~_SURR^rLCe95OiAemhWet^iWDjf0OCitS)CvLwSBEEaJ$^JUfs%y6<{0&n}HlJX(v!*)iqQ#R=WBH@4>FP)25OFTfZKE zx!Eegbcd!7xbpFwzEDPcKs++lS=UC3Xt~U~9LAB<>ZAFqSlQ#ZsLUq+q08UBjd4SF z4s@R+d=3vMu$!v5SCCW^!LC!rX+6S*0onmlpWQBlyms^JGbhD zr2_xN@91L0Wy#O^Bv)F^MdyL;SH9h61n`!ogK;9;M&KU!g=Z&Md9~1a>^_G8#iydo zeH@9GQy%6?&-+?k+Gp{fWYRwQ+rA_9A(>C(!S?T??0r;p6xzW?5#3=yY;0`h{Nc~E z!l~KWjKFOH=q%^vr0z|8bFyU+W_&;Ba>;siYhGD(%{2|hm#HKW(~;+SUSXkPqV{yD zH92H6s7k8(TNP(fJTn*qK|U-Z*2Y|hoiRwcfX)Z9Glf_3=Fh)cQf3-?=R$ewzCvxpsJzKQervy)k}aB+d!tQ%K;ij`9q@G z!x5dDv-SLeha4jkj#QSE%RO{ASFw0Z0l@+~A1~xtH6#QIA7~O+S64973Y39^NW-rL z5F-4$W_ZxeC)ESte7eg1lmzo{9~HC zs)Ys1=3@7+1iPJfVykj;vCwK;vwT>jNVDWs-t*eem;l-(!yA}DRx|L}MZcLCz#1c4 z`{6Khdp_3H3Cm`wI{gFqqO77KA|{54i;LUb)+T3vmN#q#kHs1zJ0R9&5QfP%As_Q) zPVq;KD>}=*>;5ZU+(x39)Ct-+Ax|CnuEXa}&d$hp1l_r-UvD~1-c(9qUX?_W;3evp zygXUf$~mhAK6@D@r4{e16>p?IIOGrlwf|gg&|OoL%tzvo*<9p>Xx!SJii3{HJZ7HP z|6VNjrfvVYNPLE9f7s#u0b5REI^xPGqq4G6VViDkZSDD=XMvVSFef8GtiuE&pnQV3fCpoPG>WF@<s`iK&FWs2sd_-!h!`CKpwFxc(t-IfK;Lf5Ou3a*I{TtzNT|}MZD9+%L*%=?cZ10&$Jm= zyDF$S8KOF{u(9b8h{VoLS;)iH$?`{aSBFLXZ+7TlSlo;*J5e+@=25HD@xISB<_65{ zdsRTN)O7LU5uRryB$Px11ohD@YVDn!8Nk0mRs#6cvd|Jd{j`42hl!Ax!2-wTs`)1= zr>P>K1yFas4Oli!D>3V3W>ZhWEU_ z)o_olbM?rCdl;^N`4v8{~(IPe{>>(ygge!9N%^b~|^MQcB=?fpCu1dR7N; z%y+s>&NcY!Sllgoa80W|RmhR`Iq(MynWU7|elxLBg$w5R?{~bAqI@6gZ3RX|ToBX^ z4GkcwemsBsg!fW*@7l3e)Zb$a>nw(>nDO*cYCQ9*i3>AzGx;x#qd>LXJ`Ig@Hg@_R z-$r(VlBd*r#~=Cx(WnFP)}YcnTLTu1Md|5-Gy-;KHj2v1W&9LBNr|TG7cnt0eY_|3 zp)XSkzb8#t$<4u^%eyDCIbnpFA&fX^2|-J9 zD*$HM14hP-{;AYY)K6{hfSPjHj-*4HZI#c8>}@%&i}_!O_p$DB(_ZmBw!`F3h$OVQ z^z?L_$+B*bk`HusG{0Tm?2_v->uA$!rgBdBh6T zm3BehxG<;x;DKY{X+ce*M-QtpBBT~LlbA-T5;IVM|R~&Tc zs$A>Ufl@tl+j?;Sep8lnJX#YV0k{M}w4EJ?kBwgh-y4oqI;>H?&RQ6P5m@QELG~Y@ zxc|U#J*-2HQ%RJ9h|pGz`EyWEx>A}Dh&gDb+99gBCGC6Pl$pN@RE%6VQP1~H`*Og| z1Pt1b4}Vg#ui3>=P*5OCK+|g&Y#s)15+1AIm!A1AkkLa$LzYi!r6J#bqGmz;`Ew*> zWMq9xl6+Os4iT%%jaw}IZ{F$ASui1{vUa9NshRT0uqGn$R_Oj{6^W_og_Y&`)p`=e zpHIkb+D3jMUWAi|$T^+t7(qi=bNybGT}2~Nw6fAe4o0&ksy zYhDx(a+caoJ_VQ~_TQl%A}RJ?Buqj|3KYKIsuViXfx9P;U^AE`zx1*b>C60briKyk zpE}tuMES7zz~t^p72GI89zj-{$iuEWtomhB;0r$6SOH=QJ9}-8`q}H9Mw~~|6hXNY zQ4NNM6D5|a1N>TM-{BJ5aEaVF1FwX`jnVyjRQwk<#}5px^!HLuh&9CJad1sQk*EQ4 z1w5Qg2rssBHmfqQfPpI6EKzWLR_U@YV`Q_`*|FIcMdT-^SzPWXFU~YGA*;2tvPsfpU*lmg!D=ae=88V7;E$0sJ{kYrwjlk=fTzT0EZ+xHrDCJj!;#VmXT>N zi4OhyXzHp*z`6y~C^5{XKlKJ_-PB%Sk$)*M*E<(B^A~xvK3BTU#8YekY_WZz$&--48 z^vgvnW|+N2v?6881$+gV61~RNs<}5(DiWDr8XPJ3VqgM{C!dwZ*{ZBkrclPY5^Nyl zmXvS<&gf`wuQ%j$I9OG&o2lsl49t*n(~|J7YdSLopVVZ%u(+A9Fn44cl(M@%Wh2{i zoOCQXRreT8wCR^gh^%C_ly6)4sEdlC4CW}sO?1aiHw;4J0Y`miQ%*D0<5%fHD9=z) z?qH1;k11VBmKR8e-C5guM_EB+eDoW=pY~-kimxDIieWFTDEI_lq%FOPzkPyq<6FUZ zDK$N?&2Qg}(2L*CcAyYBpHr79XQI-t^+?zlEkad(`LY9)%pTrZk3~puZAn{GK^Y@1 zW$yP;Bv1V(WG6+`L{SM#&}qyyx$(bXV__L~MzcU9RP^;Zs3#K<(w3Gi3=9ma1AJ<8 z(JY*uBvhuUbUoU{j@iL{jj@vSE>Z9B#eO2`AzA=e#;UsA4kh zx2<0_Wf<2(#e^pTENa=(8!!Nv`1tN5$S=ntr(y@pV0}jM%|BtI5zkex+N3JO3i{WW zo>;KzpU1EMD<)i;kek6m7%^p!;_V+%FL~d|pHSlk!6O`8@xIV87Xq!ww%lQ>qwQIx z-c&&uS=j|}rMY=|_fHnX-kB<29=fMi^TZ6Tvkw`N2Q8v)26v~uD72sr2nYb9#TmLF zWS^yt&4F~y{sYJ4=Y5)Eo*0hVo=7)40)U?#95|JPP9FdlAlodsN1|W-I%K=Wjr$r2Aq`#Ni!JE-aNB*x3`Kq1=kYS%oEuVvw$o%(@d>Amhc}zP<5o7eMG4 z*xZCw0R}dA2ol5Z}P6G4mMNG-e0MLnOx3L|biT zyK(*W;jsc{4FDg_LBtUqCV0;Jx6o1-92Y8JSAxr^5e-a)CVQ`a%24WOtxRbi#{FT{ z$Z8K~UruF!-Dt{dXa%#z#M~Tprp*ltt!#(SajGMVi9J-O*f>B6;|&F;DMFL)!xtXQ z<7UTYR(EA}thL1ZNETv;Un#=~NJtk3icv(Y`_f$q9;ZB9wQym^d|7^>w$8(&Zt*Zk zMPh(~^>f_vRq^j`mdQ@hp={l+DNkNzRmE(oTI^wvUSEW0-majjLdwB+l7&HT0xBJ6(F@-2wA{@_S=6!7X%K-==5nrPiY$@G)r>>WZW*-}uM51-ZFF zfq_^sCwjV*c;TWAv$L~i0l8oeA_P7%Q3<+}1c-`2?}wcNaL=M;8DIe+pymwDrD4F8r{L+$bzyO3Y6wRSaxQD*0MlBAWCa=v{F{1f+RaA?TH ztqw98_+oD)gWSy;4v<_9N<$VBP0_BDGHlx{g@_#>Fn^bpBI4p!O0I!7Az4{lKc)zQ zfT;i+h9i74A3**sH#b6D@|_0QHg`7}KJ05~N<^d-FV64iz(vi5^E6;tg~nq?MCf8i z3|#uR;Bm7bSzA~bHu#~Fkdf^T$hrLtub|{Cb(%p5F1w@gRWE{*pFaUKEq7PU$65Dy zdYdhZI-@g1HuArJqJQ?Pt!bXui0B#~A7YnYTukWg?agv@aX4y#X?VCkOhY-B8*Aj= z(n0~jQdd_G-dy(Y`OCfB|Do)N%fRiag(uIq0B0Arsk5gjsHoFIBA`M7PT|}u|0pB8wO1sM%w*XE2O7=&Oa$r{}8{0mS_4NV4HeO0W-N@>` z-BuC!j3DL{lasGRIg3zY1vol7D&iiQ-gY$qSHyGn&*pMGb9kE$rD0k=iOCjxVtU{? zetsyHI)FI9jifo$Qde)jnQ>s*BSAoofE(J()Qo3dd0p&EJ++-MQBmxnJXcIXv;Y@8 z0e23zERH&B|I3KK6%{cF3#Ua#lR$jgCwOhfo|~FxOv0v5Xr0 z!mD#>J6#o{kn~i>^sJ_M8y2Q)CQ5?fy(6qog>CM?f9e(vD3Hrx?zzzQg>zzJVta4z z3Zwy?6pXU%*WMt~-#AljFMp!>gfE5fBZ_|=k~Vu^)pnA+lHX?BI!?#0^$Le z8>Ag95d8JW-C$*^_I&GEp+Q{_7y)aub;27X1yK`mY%d$3RlF>*h|swN+4k&cQ||e5 zpB74Nhzs~s{Xi(o&+_x~7XEfb!Fw4*H1E;y&`@}E^m|Zsg|9DuwH>_`O?n0>?p9Dx z(80zieyMghz>>Fn9ZWaV3K*H)@o1g5H^|iwrp3~gl_A!78u?%>x>VOevA*7%V9=ZY zUHV8sfC_R6#=>@~=WqAJ46P!4B#;y1AQb^7(wF`*c>={bLy!Lb*VV-xnuBO2S8myE(Lp?bg~GPM zEs!<9lmT$k%v0wx!-U`=Q0lGE zk;?3*J3rs$@-U{IqOkzB2?KfZd&fe@t0ma=r~rKv8gxwA@7-2PIH~vdr9vyFXW^kw zcAD_B{>98pm{-Ne%i+$9t+3h_$_m1P)?8nmPgS`F4-Kh%U7yc#d0%-zHodHHNT0l9 zhh+lT_xWMegdr*>25k5?CLR@?u<&dqb6Z!JJcnM@d%&OFi9Gs~nB}ilz`=g`%Pd6e zh?I=%r~RxDhe548uqqhqLcId}w_$nW#(vlT?OtrrPrt^xW#yffmF021SuUS~h?$zw z<)*;B5pw};sB39ee`k+BCMPCtf`%E-@0>k)qzAYVMu%$EyZAHbQ6VLZxR>8sTP1@Z z`mPB+(z5^E^9|Mw<>EMKv}y*{Tp}lC2sgQmF8L=Wmsx-SazA}aL_+fSs2En|;IxC; zc&R&tvWvHm zn+dtLy9+I#Qbr{w%Y(>OTwFZRWFjq%_50m1gpuWATq0}5+UV3MXiv zVB&~DbRr@mz*9^yPxFk04aLte?aKR^T#oNkHOt*>D1a&gdq2OVUpxlwBbGz26Nar0 znuy>|Jt~_{*=NVa)?&j36o9+E5IyjYZxRzmSRUB$@~FbQ&BUGsC`7=Q6?tc^}1Mf>7xVz@oR#kod8F$)t!4L7vheW^i!$i}6%i$w){t5{lx5qK1C|12&d_!T Date: Wed, 23 Oct 2024 14:24:36 -0400 Subject: [PATCH 069/118] Fix some `Returns` docstrs re: `inplace` semantics (#3311) * fix comment typo * fix docstrs re: `Returns`/`inplace` semantics --- src/scanpy/preprocessing/_combat.py | 4 ++-- src/scanpy/preprocessing/_highly_variable_genes.py | 2 +- src/scanpy/tools/_marker_gene_overlap.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/scanpy/preprocessing/_combat.py b/src/scanpy/preprocessing/_combat.py index ef193d38b4..caeb9a0b45 100644 --- a/src/scanpy/preprocessing/_combat.py +++ b/src/scanpy/preprocessing/_combat.py @@ -171,7 +171,7 @@ def combat( Returns ------- - Returns :class:`numpy.ndarray` if `inplace=True`, else returns `None` and sets the following field in the `adata` object: + Returns :class:`numpy.ndarray` if `inplace=False`, else returns `None` and sets the following field in the `adata` object: `adata.X` : :class:`numpy.ndarray` (dtype `float`) Corrected data matrix. @@ -261,7 +261,7 @@ def combat( # we now apply the parametric adjustment to the standardized data from above # loop over all batches in the data for j, batch_idxs in enumerate(batch_info): - # we basically substract the additive batch effect, rescale by the ratio + # we basically subtract the additive batch effect, rescale by the ratio # of multiplicative batch effect to pooled variance and add the overall gene # wise mean dsq = np.sqrt(delta_star[j, :]) diff --git a/src/scanpy/preprocessing/_highly_variable_genes.py b/src/scanpy/preprocessing/_highly_variable_genes.py index af71728d2c..fa7971d21e 100644 --- a/src/scanpy/preprocessing/_highly_variable_genes.py +++ b/src/scanpy/preprocessing/_highly_variable_genes.py @@ -615,7 +615,7 @@ def highly_variable_genes( Returns ------- - Returns a :class:`pandas.DataFrame` with calculated metrics if `inplace=True`, else returns an `AnnData` object where it sets the following field: + Returns a :class:`pandas.DataFrame` with calculated metrics if `inplace=False`, else returns an `AnnData` object where it sets the following field: `adata.var['highly_variable']` : :class:`pandas.Series` (dtype `bool`) boolean indicator of highly-variable genes diff --git a/src/scanpy/tools/_marker_gene_overlap.py b/src/scanpy/tools/_marker_gene_overlap.py index a1d71cf993..83a19c86a4 100644 --- a/src/scanpy/tools/_marker_gene_overlap.py +++ b/src/scanpy/tools/_marker_gene_overlap.py @@ -135,7 +135,7 @@ def marker_gene_overlap( Returns ------- - Returns :class:`pandas.DataFrame` if `inplace=True`, else returns an `AnnData` object where it sets the following field: + Returns :class:`pandas.DataFrame` if `inplace=False`, else returns an `AnnData` object where it sets the following field: `adata.uns[key_added]` : :class:`pandas.DataFrame` (dtype `float`) Marker gene overlap scores. Default for `key_added` is `'marker_gene_overlap'`. From 6990065f4859f8b25106c9c6d7166d44d4533b33 Mon Sep 17 00:00:00 2001 From: Jesko Wagner <35219306+jeskowagner@users.noreply.github.com> Date: Thu, 24 Oct 2024 10:55:17 +0100 Subject: [PATCH 070/118] Catch PerfectSeparationWarning during regress_out (#3275) * catch PerfectSeparationWarning during regress_out * add 3260 release note * format * pre-commit Signed-off-by: zethson * rename release note --------- Signed-off-by: zethson Co-authored-by: zethson Co-authored-by: Intron7 --- docs/release-notes/3275.bugfix.md | 1 + src/scanpy/preprocessing/_simple.py | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 docs/release-notes/3275.bugfix.md diff --git a/docs/release-notes/3275.bugfix.md b/docs/release-notes/3275.bugfix.md new file mode 100644 index 0000000000..4465c7651d --- /dev/null +++ b/docs/release-notes/3275.bugfix.md @@ -0,0 +1 @@ +Catch `PerfectSeparationWarning` during {func}`~scanpy.pp.regress_out` {smaller}`J Wagner` diff --git a/src/scanpy/preprocessing/_simple.py b/src/scanpy/preprocessing/_simple.py index 495ec08aad..35eab78b59 100644 --- a/src/scanpy/preprocessing/_simple.py +++ b/src/scanpy/preprocessing/_simple.py @@ -811,7 +811,7 @@ def _regress_out_chunk(data): responses_chunk_list = [] import statsmodels.api as sm - from statsmodels.tools.sm_exceptions import PerfectSeparationError + import statsmodels.tools.sm_exceptions as sme for col_index in range(data_chunk.shape[1]): # if all values are identical, the statsmodel.api.GLM throws an error; @@ -825,11 +825,17 @@ def _regress_out_chunk(data): else: regres = regressors try: - result = sm.GLM( - data_chunk[:, col_index], regres, family=sm.families.Gaussian() - ).fit() - new_column = result.resid_response - except PerfectSeparationError: # this emulates R's behavior + err_classes = (sme.PerfectSeparationError,) + with warnings.catch_warnings(): + if hasattr(sme, "PerfectSeparationWarning"): + # See issue #3260 - for statsmodels>=0.14.0 + warnings.simplefilter("error", sme.PerfectSeparationWarning) + err_classes = (*err_classes, sme.PerfectSeparationWarning) + result = sm.GLM( + data_chunk[:, col_index], regres, family=sm.families.Gaussian() + ).fit() + new_column = result.resid_response + except err_classes: # this emulates R's behavior logg.warning("Encountered PerfectSeparationError, setting to 0 as in R.") new_column = np.zeros(data_chunk.shape[0]) From 9658e07dd9c2a9b18f6ce29bb80fd9598b446350 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 25 Oct 2024 12:14:16 +0200 Subject: [PATCH 071/118] Refactor regress_out (#3316) --- src/scanpy/preprocessing/_simple.py | 68 +++++++++++++++++------------ 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/src/scanpy/preprocessing/_simple.py b/src/scanpy/preprocessing/_simple.py index 35eab78b59..2b44797069 100644 --- a/src/scanpy/preprocessing/_simple.py +++ b/src/scanpy/preprocessing/_simple.py @@ -7,6 +7,7 @@ import warnings from functools import singledispatch +from itertools import repeat from typing import TYPE_CHECKING import numba @@ -46,6 +47,7 @@ from numbers import Number from typing import Literal + import pandas as pd from numpy.typing import NDArray from .._compat import DaskArray @@ -730,6 +732,8 @@ def regress_out( `adata.X` | `adata.layers[layer]` : :class:`numpy.ndarray` | :class:`scipy.sparse._csr.csr_matrix` (dtype `float`) Corrected count data matrix. """ + from joblib import Parallel, delayed + start = logg.info(f"regressing out {keys}") adata = adata.copy() if copy else adata @@ -744,7 +748,7 @@ def regress_out( raise_not_implemented_error_if_backed_type(X, "regress_out") if issparse(X): - logg.info(" sparse input is densified and may " "lead to high memory use") + logg.info(" sparse input is densified and may lead to high memory use") X = X.toarray() n_jobs = sett.n_jobs if n_jobs is None else n_jobs @@ -775,25 +779,27 @@ def regress_out( # add column of ones at index 0 (first column) regressors.insert(0, "ones", 1.0) - len_chunk = np.ceil(min(1000, X.shape[1]) / n_jobs).astype(int) - n_chunks = np.ceil(X.shape[1] / len_chunk).astype(int) + len_chunk = int(np.ceil(min(1000, X.shape[1]) / n_jobs)) + n_chunks = int(np.ceil(X.shape[1] / len_chunk)) - tasks = [] # split the adata.X matrix by columns in chunks of size n_chunk # (the last chunk could be of smaller size than the others) chunk_list = np.array_split(X, n_chunks, axis=1) - if variable_is_categorical: - regressors_chunk = np.array_split(regressors, n_chunks, axis=1) - for idx, data_chunk in enumerate(chunk_list): - # each task is a tuple of a data_chunk eg. (adata.X[:,0:100]) and - # the regressors. This data will be passed to each of the jobs. - regres = regressors_chunk[idx] if variable_is_categorical else regressors - tasks.append(tuple((data_chunk, regres, variable_is_categorical))) - - from joblib import Parallel, delayed + regressors_chunk = ( + np.array_split(regressors, n_chunks, axis=1) + if variable_is_categorical + else repeat(regressors) + ) + # each task is passed a data chunk (e.g. `adata.X[:, 0:100]``) and the regressors. + # This data will be passed to each of the jobs. # TODO: figure out how to test that this doesn't oversubscribe resources - res = Parallel(n_jobs=n_jobs)(delayed(_regress_out_chunk)(task) for task in tasks) + res = Parallel(n_jobs=n_jobs)( + delayed(_regress_out_chunk)( + data_chunk, regres, variable_is_categorical=variable_is_categorical + ) + for data_chunk, regres in zip(chunk_list, regressors_chunk, strict=False) + ) # res is a list of vectors (each corresponding to a regressed gene column). # The transpose is needed to get the matrix in the shape needed @@ -802,17 +808,22 @@ def regress_out( return adata if copy else None -def _regress_out_chunk(data): - # data is a tuple containing the selected columns from adata.X - # and the regressors dataFrame - data_chunk = data[0] - regressors = data[1] - variable_is_categorical = data[2] - - responses_chunk_list = [] +def _regress_out_chunk( + data_chunk: NDArray[np.floating], + regressors: pd.DataFrame | NDArray[np.floating], + *, + variable_is_categorical: bool, +) -> NDArray[np.floating]: import statsmodels.api as sm import statsmodels.tools.sm_exceptions as sme + Psw = ( + sme.PerfectSeparationWarning + if hasattr(sme, "PerfectSeparationWarning") + else None + ) + + responses_chunk_list = [] for col_index in range(data_chunk.shape[1]): # if all values are identical, the statsmodel.api.GLM throws an error; # but then no regression is necessary anyways... @@ -824,19 +835,18 @@ def _regress_out_chunk(data): regres = np.c_[np.ones(regressors.shape[0]), regressors[:, col_index]] else: regres = regressors + try: - err_classes = (sme.PerfectSeparationError,) with warnings.catch_warnings(): - if hasattr(sme, "PerfectSeparationWarning"): - # See issue #3260 - for statsmodels>=0.14.0 - warnings.simplefilter("error", sme.PerfectSeparationWarning) - err_classes = (*err_classes, sme.PerfectSeparationWarning) + # See issue #3260 - for statsmodels>=0.14.0 + if Psw: + warnings.simplefilter("error", Psw) result = sm.GLM( data_chunk[:, col_index], regres, family=sm.families.Gaussian() ).fit() new_column = result.resid_response - except err_classes: # this emulates R's behavior - logg.warning("Encountered PerfectSeparationError, setting to 0 as in R.") + except (sme.PerfectSeparationError, *([Psw] if Psw else [])): + logg.warning("Encountered perfect separation, setting to 0 as in R.") new_column = np.zeros(data_chunk.shape[0]) responses_chunk_list.append(new_column) From ced5008d767538f3d0211ebaebb1010a6ea4f8a2 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 25 Oct 2024 13:31:34 +0200 Subject: [PATCH 072/118] Enforce `np.bool_` usage via Ruff (#3321) --- pyproject.toml | 1 + src/scanpy/plotting/_anndata.py | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index dff45651fb..dda000d790 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -258,6 +258,7 @@ required-imports = ["from __future__ import annotations"] "pandas.api.types.is_categorical_dtype".msg = "Use isinstance(s.dtype, CategoricalDtype) instead" "pandas.value_counts".msg = "Use pd.Series(a).value_counts() instead" "legacy_api_wrap.legacy_api".msg = "Use scanpy._compat.old_positionals instead" +"numpy.bool".msg = "Use `np.bool_` instead for numpy>=1.24<2 compatibility" [tool.ruff.lint.flake8-type-checking] exempt-modules = [] strict = true diff --git a/src/scanpy/plotting/_anndata.py b/src/scanpy/plotting/_anndata.py index f3474fe27b..c1918878c8 100755 --- a/src/scanpy/plotting/_anndata.py +++ b/src/scanpy/plotting/_anndata.py @@ -198,7 +198,7 @@ def _check_if_annotations( other_ax_obj, "var" if axis_name == "obs" else "obs" ).index - def is_annotation(needle: pd.Index) -> NDArray[np.bool]: + def is_annotation(needle: pd.Index) -> NDArray[np.bool_]: return needle.isin({None}) | needle.isin(annotations) | needle.isin(names) if not is_annotation(pd.Index([x, y])).all(): @@ -206,8 +206,8 @@ def is_annotation(needle: pd.Index) -> NDArray[np.bool]: color_idx = pd.Index(colors if colors is not None else []) # Colors are valid - color_valid: NDArray[np.bool] = np.fromiter( - map(is_color_like, color_idx), dtype=np.bool, count=len(color_idx) + color_valid: NDArray[np.bool_] = np.fromiter( + map(is_color_like, color_idx), dtype=np.bool_, count=len(color_idx) ) # Annotation names are valid too color_valid[~color_valid] = is_annotation(color_idx[~color_valid]) From 233fed1a2b03cc7f05d267e360102eb4ce5a9227 Mon Sep 17 00:00:00 2001 From: Emmanuel Ferdman Date: Mon, 28 Oct 2024 09:44:58 +0200 Subject: [PATCH 073/118] Update `test_rank_genes_groups.py` reference (#3285) --- src/scanpy/tools/_rank_genes_groups.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scanpy/tools/_rank_genes_groups.py b/src/scanpy/tools/_rank_genes_groups.py index d864b01b88..5381ea6228 100644 --- a/src/scanpy/tools/_rank_genes_groups.py +++ b/src/scanpy/tools/_rank_genes_groups.py @@ -582,7 +582,7 @@ def rank_genes_groups( Notes ----- There are slight inconsistencies depending on whether sparse - or dense data are passed. See `here `__. + or dense data are passed. See `here `__. Examples -------- From 44bd465e4129cf6819394953118ebe4d68e15363 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 31 Oct 2024 14:24:33 +0100 Subject: [PATCH 074/118] Support `layer` in `sc.pl.highest_expr_genes` (#3324) --- docs/release-notes/3324.feature.md | 1 + src/scanpy/plotting/_qc.py | 11 +++++++---- tests/test_plotting.py | 10 ++++++++-- 3 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 docs/release-notes/3324.feature.md diff --git a/docs/release-notes/3324.feature.md b/docs/release-notes/3324.feature.md new file mode 100644 index 0000000000..03d14dceb6 --- /dev/null +++ b/docs/release-notes/3324.feature.md @@ -0,0 +1 @@ +Support `layer` parameter in {func}`scanpy.pl.highest_expr_genes` {smaller}`P Angerer` diff --git a/src/scanpy/plotting/_qc.py b/src/scanpy/plotting/_qc.py index dc89e3c064..cd3f764468 100644 --- a/src/scanpy/plotting/_qc.py +++ b/src/scanpy/plotting/_qc.py @@ -24,11 +24,12 @@ def highest_expr_genes( adata: AnnData, n_top: int = 30, *, + layer: str | None = None, + gene_symbols: str | None = None, + log: bool = False, show: bool | None = None, save: str | bool | None = None, ax: Axes | None = None, - gene_symbols: str | None = None, - log: bool = False, **kwds, ): """\ @@ -56,11 +57,13 @@ def highest_expr_genes( Annotated data matrix. n_top Number of top - {show_save_ax} + layer + Layer from which to pull data. gene_symbols Key for field in .var that stores gene symbols if you do not want to use .var_names. log Plot x-axis in log scale + {show_save_ax} **kwds Are passed to :func:`~seaborn.boxplot`. @@ -72,7 +75,7 @@ def highest_expr_genes( from scipy.sparse import issparse # compute the percentage of each gene per cell - norm_dict = normalize_total(adata, target_sum=100, inplace=False) + norm_dict = normalize_total(adata, target_sum=100, layer=layer, inplace=False) # identify the genes with the highest mean if issparse(norm_dict["X"]): diff --git a/tests/test_plotting.py b/tests/test_plotting.py index 43bd2f810a..2f0f5f60cd 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -37,13 +37,19 @@ @pytest.mark.parametrize("col", [None, "symb"]) -def test_highest_expr_genes(image_comparer, col): +@pytest.mark.parametrize("layer", [None, "layer_name"]) +def test_highest_expr_genes(image_comparer, col, layer): save_and_compare_images = partial(image_comparer, ROOT, tol=5) adata = pbmc3k() + if layer is not None: + adata.layers[layer] = adata.X + del adata.X # check that only existing categories are shown adata.var["symb"] = adata.var_names.astype("category") - sc.pl.highest_expr_genes(adata, 20, gene_symbols=col, show=False) + + sc.pl.highest_expr_genes(adata, 20, gene_symbols=col, layer=layer, show=False) + save_and_compare_images("highest_expr_genes") From 5a02a0773ab6bee1ae7c8eaceff4da28c577ae78 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 31 Oct 2024 14:48:48 +0100 Subject: [PATCH 075/118] =?UTF-8?q?Align=20`get.obs=5Fdf`=E2=80=99s=20docs?= =?UTF-8?q?=20with=20its=20code=20(#3328)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/scanpy/_utils/__init__.py | 4 ++-- src/scanpy/get/get.py | 20 ++++++++++++-------- src/scanpy/tools/_rank_genes_groups.py | 2 +- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/scanpy/_utils/__init__.py b/src/scanpy/_utils/__init__.py index 883f8b97b9..5a8b0288b8 100644 --- a/src/scanpy/_utils/__init__.py +++ b/src/scanpy/_utils/__init__.py @@ -42,7 +42,7 @@ from anndata._core.sparse_dataset import SparseDataset if TYPE_CHECKING: - from collections.abc import Callable, Mapping + from collections.abc import Callable, Iterable, Mapping from pathlib import Path from typing import Any, Literal, TypeVar @@ -805,7 +805,7 @@ def _check_nonnegative_integers_dask(X: DaskArray) -> DaskArray: def select_groups( adata: AnnData, - groups_order_subset: list[str] | Literal["all"] = "all", + groups_order_subset: Iterable[str] | Literal["all"] = "all", key: str = "groups", ) -> tuple[list[str], NDArray[np.bool_]]: """Get subset of groups in adata.obs[key].""" diff --git a/src/scanpy/get/get.py b/src/scanpy/get/get.py index 0c1272ae62..f3172ed45e 100644 --- a/src/scanpy/get/get.py +++ b/src/scanpy/get/get.py @@ -11,7 +11,7 @@ from scipy.sparse import spmatrix if TYPE_CHECKING: - from collections.abc import Iterable + from collections.abc import Collection, Iterable from typing import Any, Literal from anndata._core.sparse_dataset import BaseCompressedSparseDataset @@ -116,7 +116,7 @@ def _check_indices( alt_index: pd.Index, *, dim: Literal["obs", "var"], - keys: list[str], + keys: Iterable[str], alias_index: pd.Index | None = None, use_raw: bool = False, ) -> tuple[list[str], list[str], list[str]]: @@ -159,7 +159,7 @@ def _check_indices( # use only unique keys, otherwise duplicated keys will # further duplicate when reordering the keys later in the function - for key in np.unique(keys): + for key in dict.fromkeys(keys): if key in dim_df.columns: col_keys.append(key) if key in alt_names.index: @@ -191,7 +191,7 @@ def _check_indices( def _get_array_values( X, dim_names: pd.Index, - keys: list[str], + keys: Iterable[str], *, axis: Literal[0, 1], backed: bool, @@ -221,7 +221,7 @@ def _get_array_values( def obs_df( adata: AnnData, - keys: Iterable[str] = (), + keys: Collection[str] = (), obsm_keys: Iterable[tuple[str, int]] = (), *, layer: str | None = None, @@ -238,7 +238,7 @@ def obs_df( keys Keys from either `.var_names`, `.var[gene_symbols]`, or `.obs.columns`. obsm_keys - Tuple of `(key from obsm, column index of obsm[key])`. + Tuples of `(key from obsm, column index of obsm[key])`. layer Layer of `adata` to use as expression values. gene_symbols @@ -278,6 +278,8 @@ def obs_df( >>> grouped = genedf.groupby("louvain", observed=True) >>> mean, var = grouped.mean(), grouped.var() """ + if isinstance(keys, str): + keys = [keys] if use_raw: assert ( layer is None @@ -336,7 +338,7 @@ def obs_df( def var_df( adata: AnnData, - keys: Iterable[str] = (), + keys: Collection[str] = (), varm_keys: Iterable[tuple[str, int]] = (), *, layer: str | None = None, @@ -351,7 +353,7 @@ def var_df( keys Keys from either `.obs_names`, or `.var.columns`. varm_keys - Tuple of `(key from varm, column index of varm[key])`. + Tuples of `(key from varm, column index of varm[key])`. layer Layer of `adata` to use as expression values. @@ -361,6 +363,8 @@ def var_df( and `varm_keys`. """ # Argument handling + if isinstance(keys, str): + keys = [keys] var_cols, obs_idx_keys, _ = _check_indices( adata.var, adata.obs_names, dim="var", keys=keys ) diff --git a/src/scanpy/tools/_rank_genes_groups.py b/src/scanpy/tools/_rank_genes_groups.py index 5381ea6228..3a737bb487 100644 --- a/src/scanpy/tools/_rank_genes_groups.py +++ b/src/scanpy/tools/_rank_genes_groups.py @@ -98,7 +98,7 @@ class _RankGenes: def __init__( self, adata: AnnData, - groups: list[str] | Literal["all"], + groups: Iterable[str] | Literal["all"], groupby: str, *, mask_var: NDArray[np.bool_] | None = None, From 9d6687484c9be58752ac9fc7bad14234d1db2361 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 5 Nov 2024 08:42:01 +0100 Subject: [PATCH 076/118] [pre-commit.ci] pre-commit autoupdate (#3329) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 75b40177d2..25b824a582 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.7.0 + rev: v0.7.2 hooks: - id: ruff types_or: [python, pyi, jupyter] From ccfe2c9df60dfb52f73f5f45faa4b9127f3774c0 Mon Sep 17 00:00:00 2001 From: Ilan Gold Date: Tue, 5 Nov 2024 15:12:54 +0100 Subject: [PATCH 077/118] (fix): sort pca test args (#3333) Co-authored-by: Philipp A. --- src/scanpy/_utils/__init__.py | 26 +++++++++++++----- src/scanpy/get/_aggregated.py | 10 +++---- src/scanpy/neighbors/__init__.py | 10 ++++--- src/scanpy/neighbors/_types.py | 2 +- src/scanpy/plotting/_anndata.py | 17 +++++++----- src/scanpy/preprocessing/_pca/__init__.py | 32 +++++++++++++---------- src/scanpy/tools/_draw_graph.py | 9 +++---- src/scanpy/tools/_rank_genes_groups.py | 8 +++--- tests/test_aggregated.py | 6 ++--- tests/test_pca.py | 16 ++++++++---- 10 files changed, 81 insertions(+), 55 deletions(-) diff --git a/src/scanpy/_utils/__init__.py b/src/scanpy/_utils/__init__.py index 5a8b0288b8..8e886d1ff1 100644 --- a/src/scanpy/_utils/__init__.py +++ b/src/scanpy/_utils/__init__.py @@ -15,11 +15,11 @@ from collections import namedtuple from contextlib import contextmanager, suppress from enum import Enum -from functools import partial, singledispatch, wraps -from operator import mul, truediv +from functools import partial, reduce, singledispatch, wraps +from operator import mul, or_, truediv from textwrap import dedent -from types import MethodType, ModuleType -from typing import TYPE_CHECKING, overload +from types import MethodType, ModuleType, UnionType +from typing import TYPE_CHECKING, Literal, Union, get_args, get_origin, overload from weakref import WeakSet import h5py @@ -42,9 +42,9 @@ from anndata._core.sparse_dataset import SparseDataset if TYPE_CHECKING: - from collections.abc import Callable, Iterable, Mapping + from collections.abc import Callable, Iterable, KeysView, Mapping from pathlib import Path - from typing import Any, Literal, TypeVar + from typing import Any, TypeVar from anndata import AnnData from numpy.typing import DTypeLike, NDArray @@ -55,6 +55,7 @@ # e.g. https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html # maybe in the future random.Generator AnyRandom = int | np.random.RandomState | None +LegacyUnionType = type(Union[int, str]) # noqa: UP007 class Empty(Enum): @@ -532,6 +533,19 @@ def update_params( return updated_params +# `get_args` returns `tuple[Any]` so I don’t think it’s possible to get the correct type here +def get_literal_vals(typ: UnionType | Any) -> KeysView[Any]: + """Get all literal values from a Literal or Union of … of Literal type.""" + if isinstance(typ, UnionType | LegacyUnionType): + return reduce( + or_, (dict.fromkeys(get_literal_vals(t)) for t in get_args(typ)) + ).keys() + if get_origin(typ) is Literal: + return dict.fromkeys(get_args(typ)).keys() + msg = f"{typ} is not a valid Literal" + raise TypeError(msg) + + # -------------------------------------------------------------------------------- # Others # -------------------------------------------------------------------------------- diff --git a/src/scanpy/get/_aggregated.py b/src/scanpy/get/_aggregated.py index e95fedf9dc..2d2739491e 100644 --- a/src/scanpy/get/_aggregated.py +++ b/src/scanpy/get/_aggregated.py @@ -1,7 +1,7 @@ from __future__ import annotations from functools import singledispatch -from typing import TYPE_CHECKING, Literal, get_args +from typing import TYPE_CHECKING, Literal import numpy as np import pandas as pd @@ -9,7 +9,7 @@ from scipy import sparse from sklearn.utils.sparsefuncs import csc_median_axis_0 -from .._utils import _resolve_axis +from .._utils import _resolve_axis, get_literal_vals from .get import _check_mask if TYPE_CHECKING: @@ -19,7 +19,7 @@ Array = np.ndarray | sparse.csc_matrix | sparse.csr_matrix -# Used with get_args +# Used with get_literal_vals AggType = Literal["count_nonzero", "mean", "sum", "var", "median"] @@ -347,8 +347,8 @@ def aggregate_array( result = {} funcs = set([func] if isinstance(func, str) else func) - if unknown := funcs - set(get_args(AggType)): - raise ValueError(f"func {unknown} is not one of {get_args(AggType)}") + if unknown := funcs - get_literal_vals(AggType): + raise ValueError(f"func {unknown} is not one of {get_literal_vals(AggType)}") if "sum" in funcs: # sum is calculated separately from the rest agg = groupby.sum() diff --git a/src/scanpy/neighbors/__init__.py b/src/scanpy/neighbors/__init__.py index 7b1c3f2506..379f34227b 100644 --- a/src/scanpy/neighbors/__init__.py +++ b/src/scanpy/neighbors/__init__.py @@ -4,7 +4,7 @@ from collections.abc import Mapping from textwrap import indent from types import MappingProxyType -from typing import TYPE_CHECKING, NamedTuple, TypedDict, get_args +from typing import TYPE_CHECKING, NamedTuple, TypedDict from warnings import warn import numpy as np @@ -16,7 +16,7 @@ from .. import logging as logg from .._compat import old_positionals from .._settings import settings -from .._utils import NeighborsView, _doc_params +from .._utils import NeighborsView, _doc_params, get_literal_vals from . import _connectivity from ._common import ( _get_indices_distances_from_sparse_matrix, @@ -652,7 +652,9 @@ def _handle_transformer( raise ValueError(msg) method = "umap" transformer = "rapids" - elif method not in (methods := set(get_args(_Method))) and method is not None: + elif ( + method not in (methods := get_literal_vals(_Method)) and method is not None + ): msg = f"`method` needs to be one of {methods}." raise ValueError(msg) @@ -704,7 +706,7 @@ def _handle_transformer( elif isinstance(transformer, str): msg = ( f"Unknown transformer: {transformer}. " - f"Try passing a class or one of {set(get_args(_KnownTransformer))}" + f"Try passing a class or one of {get_literal_vals(_KnownTransformer)}" ) raise ValueError(msg) # else `transformer` is probably an instance diff --git a/src/scanpy/neighbors/_types.py b/src/scanpy/neighbors/_types.py index d98ec76af3..39f50284ec 100644 --- a/src/scanpy/neighbors/_types.py +++ b/src/scanpy/neighbors/_types.py @@ -11,7 +11,7 @@ from scipy.sparse import spmatrix -# These two are used with get_args elsewhere +# These two are used with get_literal_vals elsewhere _Method = Literal["umap", "gauss"] _KnownTransformer = Literal["pynndescent", "sklearn", "rapids"] diff --git a/src/scanpy/plotting/_anndata.py b/src/scanpy/plotting/_anndata.py index c1918878c8..0ae810b2c7 100755 --- a/src/scanpy/plotting/_anndata.py +++ b/src/scanpy/plotting/_anndata.py @@ -6,7 +6,7 @@ from collections.abc import Collection, Mapping, Sequence from itertools import product from types import NoneType -from typing import TYPE_CHECKING, cast, get_args +from typing import TYPE_CHECKING, cast import matplotlib as mpl import numpy as np @@ -22,7 +22,13 @@ from .. import logging as logg from .._compat import old_positionals from .._settings import settings -from .._utils import _check_use_raw, _doc_params, _empty, sanitize_anndata +from .._utils import ( + _check_use_raw, + _doc_params, + _empty, + get_literal_vals, + sanitize_anndata, +) from . import _utils from ._docs import ( doc_common_plot_args, @@ -65,9 +71,6 @@ _VarNames = str | Sequence[str] -VALID_LEGENDLOCS = frozenset(get_args(_utils._LegendLoc)) - - @old_positionals( "color", "use_raw", @@ -268,9 +271,9 @@ def _scatter_obs( if use_raw and layers not in [("X", "X", "X"), (None, None, None)]: ValueError("`use_raw` must be `False` if layers are used.") - if legend_loc not in VALID_LEGENDLOCS: + if legend_loc not in (valid_legend_locs := get_literal_vals(_utils._LegendLoc)): raise ValueError( - f"Invalid `legend_loc`, need to be one of: {VALID_LEGENDLOCS}." + f"Invalid `legend_loc`, need to be one of: {valid_legend_locs}." ) if components is None: components = "1,2" if "2d" in projection else "1,2,3" diff --git a/src/scanpy/preprocessing/_pca/__init__.py b/src/scanpy/preprocessing/_pca/__init__.py index 354848ea7d..dba47d821c 100644 --- a/src/scanpy/preprocessing/_pca/__init__.py +++ b/src/scanpy/preprocessing/_pca/__init__.py @@ -1,7 +1,7 @@ from __future__ import annotations import warnings -from typing import TYPE_CHECKING, Literal, get_args, overload +from typing import TYPE_CHECKING, Literal, overload from warnings import warn import anndata as ad @@ -14,13 +14,14 @@ from ... import logging as logg from ..._compat import DaskArray, pkg_version from ..._settings import settings -from ..._utils import _doc_params, _empty, is_backed_type +from ..._utils import _doc_params, _empty, get_literal_vals, is_backed_type from ...get import _check_mask, _get_obs_rep from .._docs import doc_mask_var_hvg from ._compat import _pca_compat_sparse if TYPE_CHECKING: from collections.abc import Container + from collections.abc import Set as AbstractSet from typing import LiteralString, TypeVar import dask_ml.decomposition as dmld @@ -44,10 +45,11 @@ SvdSolvTruncatedSVDDaskML = Literal["tsqr", "randomized"] SvdSolvDaskML = SvdSolvPCADaskML | SvdSolvTruncatedSVDDaskML -SvdSolvPCADenseSklearn = Literal[ - "auto", "full", "arpack", "covariance_eigh", "randomized" -] -SvdSolvPCASparseSklearn = Literal["arpack", "covariance_eigh"] +if pkg_version("scikit-learn") >= Version("1.5") or TYPE_CHECKING: + SvdSolvPCASparseSklearn = Literal["arpack", "covariance_eigh"] +else: + SvdSolvPCASparseSklearn = Literal["arpack"] +SvdSolvPCADenseSklearn = Literal["auto", "full", "randomized"] | SvdSolvPCASparseSklearn SvdSolvTruncatedSVDSklearn = Literal["arpack", "randomized"] SvdSolvSkearn = ( SvdSolvPCADenseSklearn | SvdSolvPCASparseSklearn | SvdSolvTruncatedSVDSklearn @@ -299,7 +301,9 @@ def pca( if issparse(X) and ( pkg_version("scikit-learn") < Version("1.4") or svd_solver == "lobpcg" ): - if svd_solver not in {"lobpcg", "arpack"}: + if svd_solver not in ( + {"lobpcg"} | get_literal_vals(SvdSolvPCASparseSklearn) + ): if svd_solver is not None: msg = ( f"Ignoring {svd_solver=} and using 'arpack', " @@ -467,14 +471,14 @@ def _handle_dask_ml_args( def _handle_dask_ml_args(svd_solver: str | None, method: MethodDaskML) -> SvdSolvDaskML: import dask_ml.decomposition as dmld - args: tuple[SvdSolvDaskML, ...] + args: AbstractSet[SvdSolvDaskML] default: SvdSolvDaskML match method: case dmld.PCA | dmld.IncrementalPCA: - args = get_args(SvdSolvPCADaskML) + args = get_literal_vals(SvdSolvPCADaskML) default = "auto" case dmld.TruncatedSVD: - args = get_args(SvdSolvTruncatedSVDDaskML) + args = get_literal_vals(SvdSolvTruncatedSVDDaskML) default = "tsqr" case _: msg = f"Unknown {method=} in _handle_dask_ml_args" @@ -499,18 +503,18 @@ def _handle_sklearn_args( ) -> SvdSolvSkearn: import sklearn.decomposition as skld - args: tuple[SvdSolvSkearn, ...] + args: AbstractSet[SvdSolvSkearn] default: SvdSolvSkearn suffix = "" match (method, sparse): case (skld.TruncatedSVD, None): - args = get_args(SvdSolvTruncatedSVDSklearn) + args = get_literal_vals(SvdSolvTruncatedSVDSklearn) default = "randomized" case (skld.PCA, False): - args = get_args(SvdSolvPCADenseSklearn) + args = get_literal_vals(SvdSolvPCADenseSklearn) default = "arpack" case (skld.PCA, True): - args = get_args(SvdSolvPCASparseSklearn) + args = get_literal_vals(SvdSolvPCASparseSklearn) default = "arpack" suffix = " (with sparse input)" case _: diff --git a/src/scanpy/tools/_draw_graph.py b/src/scanpy/tools/_draw_graph.py index 4e8c91fb1f..3f0e65c061 100644 --- a/src/scanpy/tools/_draw_graph.py +++ b/src/scanpy/tools/_draw_graph.py @@ -2,14 +2,14 @@ import random from importlib.util import find_spec -from typing import TYPE_CHECKING, Literal, get_args +from typing import TYPE_CHECKING, Literal import numpy as np from .. import _utils from .. import logging as logg from .._compat import old_positionals -from .._utils import _choose_graph +from .._utils import _choose_graph, get_literal_vals from ._utils import get_init_pos_from_paga if TYPE_CHECKING: @@ -24,7 +24,6 @@ _Layout = Literal["fr", "drl", "kk", "grid_fr", "lgl", "rt", "rt_circular", "fa"] -_LAYOUTS = get_args(_Layout) @old_positionals( @@ -124,8 +123,8 @@ def draw_graph( `draw_graph` parameters. """ start = logg.info(f"drawing single-cell graph using layout {layout!r}") - if layout not in _LAYOUTS: - raise ValueError(f"Provide a valid layout, one of {_LAYOUTS}.") + if layout not in (layouts := get_literal_vals(_Layout)): + raise ValueError(f"Provide a valid layout, one of {layouts}.") adata = adata.copy() if copy else adata if adjacency is None: adjacency = _choose_graph(adata, obsp, neighbors_key) diff --git a/src/scanpy/tools/_rank_genes_groups.py b/src/scanpy/tools/_rank_genes_groups.py index 3a737bb487..f8ab13e9fd 100644 --- a/src/scanpy/tools/_rank_genes_groups.py +++ b/src/scanpy/tools/_rank_genes_groups.py @@ -3,7 +3,7 @@ from __future__ import annotations from math import floor -from typing import TYPE_CHECKING, Literal, get_args +from typing import TYPE_CHECKING, Literal import numpy as np import pandas as pd @@ -14,6 +14,7 @@ from .._compat import old_positionals from .._utils import ( check_nonnegative_integers, + get_literal_vals, raise_not_implemented_error_if_backed_type, ) from ..get import _check_mask @@ -28,7 +29,7 @@ _CorrMethod = Literal["benjamini-hochberg", "bonferroni"] -# Used with get_args +# Used with get_literal_vals _Method = Literal["logreg", "t-test", "wilcoxon", "t-test_overestim_var"] @@ -607,8 +608,7 @@ def rank_genes_groups( rankby_abs = not kwds.pop("only_positive") # backwards compat start = logg.info("ranking genes") - avail_methods = set(get_args(_Method)) - if method not in avail_methods: + if method not in (avail_methods := get_literal_vals(_Method)): raise ValueError(f"Method must be one of {avail_methods}.") avail_corr = {"benjamini-hochberg", "bonferroni"} diff --git a/tests/test_aggregated.py b/tests/test_aggregated.py index ce680b8df5..5bd87e231d 100644 --- a/tests/test_aggregated.py +++ b/tests/test_aggregated.py @@ -1,7 +1,5 @@ from __future__ import annotations -from typing import get_args - import anndata as ad import numpy as np import pandas as pd @@ -10,14 +8,14 @@ from scipy import sparse import scanpy as sc -from scanpy._utils import _resolve_axis +from scanpy._utils import _resolve_axis, get_literal_vals from scanpy.get._aggregated import AggType from testing.scanpy._helpers import assert_equal from testing.scanpy._helpers.data import pbmc3k_processed from testing.scanpy._pytest.params import ARRAY_TYPES_MEM -@pytest.fixture(params=get_args(AggType)) +@pytest.fixture(params=get_literal_vals(AggType)) def metric(request: pytest.FixtureRequest) -> AggType: return request.param diff --git a/tests/test_pca.py b/tests/test_pca.py index 6fc8eafd43..0130b6ac35 100644 --- a/tests/test_pca.py +++ b/tests/test_pca.py @@ -3,7 +3,7 @@ import warnings from contextlib import nullcontext from functools import wraps -from typing import TYPE_CHECKING, Literal, get_args +from typing import TYPE_CHECKING, Literal import anndata as ad import numpy as np @@ -17,6 +17,7 @@ import scanpy as sc from scanpy._compat import DaskArray, pkg_version +from scanpy._utils import get_literal_vals from scanpy.preprocessing._pca import SvdSolver as SvdSolverSupported from scanpy.preprocessing._pca._dask_sparse import _cov_sparse_dask from testing.scanpy import _helpers @@ -125,6 +126,10 @@ def array_type(request: pytest.FixtureRequest) -> ArrayType: SVDSolverDeprecated = Literal["lobpcg"] SVDSolver = SvdSolverSupported | SVDSolverDeprecated +SKLEARN_ADDITIONAL: frozenset[SvdSolverSupported] = frozenset( + {"covariance_eigh"} if pkg_version("scikit-learn") >= Version("1.5") else () +) + def gen_pca_params( *, @@ -140,7 +145,7 @@ def gen_pca_params( yield None, None, None return - all_svd_solvers = set(get_args(SVDSolver)) + all_svd_solvers = get_literal_vals(SVDSolver) svd_solvers: set[SVDSolver] match array_type, zero_center: case (dc, True) if dc is DASK_CONVERTERS[_helpers.as_dense_dask_array]: @@ -150,11 +155,11 @@ def gen_pca_params( case (dc, True) if dc is DASK_CONVERTERS[_helpers.as_sparse_dask_array]: svd_solvers = {"covariance_eigh"} case ((sparse.csr_matrix | sparse.csc_matrix), True): - svd_solvers = {"arpack"} + svd_solvers = {"arpack"} | SKLEARN_ADDITIONAL case ((sparse.csr_matrix | sparse.csc_matrix), False): svd_solvers = {"arpack", "randomized"} case (helpers.asarray, True): - svd_solvers = {"auto", "full", "arpack", "randomized"} + svd_solvers = {"auto", "full", "arpack", "randomized"} | SKLEARN_ADDITIONAL case (helpers.asarray, False): svd_solvers = {"arpack", "randomized"} case _: @@ -168,7 +173,8 @@ def gen_pca_params( else: pytest.fail(f"Unknown {svd_solver_type=}") - for svd_solver in svd_solvers: + # sorted to prevent https://github.com/pytest-dev/pytest-xdist/issues/432 + for svd_solver in sorted(svd_solvers): # explicit check for special case if ( array_type in {sparse.csr_matrix, sparse.csc_matrix} From d244371c63463a7e32d4972cf234b5925cf1df36 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Tue, 5 Nov 2024 17:34:34 +0100 Subject: [PATCH 078/118] Add PYI lints (#3339) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- benchmarks/benchmarks/_utils.py | 7 +++-- pyproject.toml | 3 ++ src/scanpy/_settings.py | 4 +-- src/scanpy/_utils/__init__.py | 31 +++++++++++++------ src/scanpy/cli.py | 4 +-- src/scanpy/get/_aggregated.py | 2 +- src/scanpy/plotting/_anndata.py | 8 ++--- src/scanpy/plotting/_stacked_violin.py | 8 ++--- src/scanpy/plotting/_tools/__init__.py | 4 +-- src/scanpy/plotting/_tools/paga.py | 4 +-- src/scanpy/plotting/_tools/scatterplots.py | 2 +- src/scanpy/preprocessing/_scale.py | 1 - .../preprocessing/_scrublet/sparse_utils.py | 2 +- src/scanpy/tools/_marker_gene_overlap.py | 4 +-- src/scanpy/tools/_rank_genes_groups.py | 2 +- src/scanpy/tools/_tsne.py | 6 ++-- 16 files changed, 53 insertions(+), 39 deletions(-) diff --git a/benchmarks/benchmarks/_utils.py b/benchmarks/benchmarks/_utils.py index 810ace74fd..93bb4623f9 100644 --- a/benchmarks/benchmarks/_utils.py +++ b/benchmarks/benchmarks/_utils.py @@ -14,7 +14,8 @@ import scanpy as sc if TYPE_CHECKING: - from collections.abc import Callable, Sequence, Set + from collections.abc import Callable, Sequence + from collections.abc import Set as AbstractSet from typing import Literal, Protocol, TypeVar from anndata import AnnData @@ -22,7 +23,7 @@ C = TypeVar("C", bound=Callable) class ParamSkipper(Protocol): - def __call__(self, **skipped: Set) -> Callable[[C], C]: ... + def __call__(self, **skipped: AbstractSet) -> Callable[[C], C]: ... Dataset = Literal["pbmc68k_reduced", "pbmc3k", "bmmc", "lung93k"] KeyX = Literal[None, "off-axis"] @@ -195,7 +196,7 @@ def param_skipper( b 5 """ - def skip(**skipped: Set) -> Callable[[C], C]: + def skip(**skipped: AbstractSet) -> Callable[[C], C]: skipped_combs = [ tuple(record.values()) for record in ( diff --git a/pyproject.toml b/pyproject.toml index dda000d790..e983d04a97 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -232,6 +232,7 @@ select = [ "TID251", # Banned imports "ICN", # Follow import conventions "PTH", # Pathlib instead of os.path + "PYI", # Typing "PLR0917", # Ban APIs with too many positional parameters "FBT", # No positional boolean parameters "PT", # Pytest style @@ -246,6 +247,8 @@ ignore = [ "E262", # allow I, O, l as variable names -> I is the identity matrix, i, j, k, l is reasonable indexing notation "E741", + # `Literal["..."] | str` is useful for autocompletion + "PYI051", ] [tool.ruff.lint.per-file-ignores] # Do not assign a lambda expression, use a def diff --git a/src/scanpy/_settings.py b/src/scanpy/_settings.py index fa44fc8492..54b51b6420 100644 --- a/src/scanpy/_settings.py +++ b/src/scanpy/_settings.py @@ -19,7 +19,7 @@ # Collected from the print_* functions in matplotlib.backends _Format = ( - Literal["png", "jpg", "tif", "tiff"] + Literal["png", "jpg", "tif", "tiff"] # noqa: PYI030 | Literal["pdf", "ps", "eps", "svg", "svgz", "pgf"] | Literal["raw", "rgba"] ) @@ -340,7 +340,7 @@ def max_memory(self) -> int | float: return self._max_memory @max_memory.setter - def max_memory(self, max_memory: int | float): + def max_memory(self, max_memory: float): _type_check(max_memory, "max_memory", (int, float)) self._max_memory = max_memory diff --git a/src/scanpy/_utils/__init__.py b/src/scanpy/_utils/__init__.py index 8e886d1ff1..066e23f667 100644 --- a/src/scanpy/_utils/__init__.py +++ b/src/scanpy/_utils/__init__.py @@ -12,14 +12,21 @@ import re import sys import warnings -from collections import namedtuple from contextlib import contextmanager, suppress from enum import Enum from functools import partial, reduce, singledispatch, wraps from operator import mul, or_, truediv from textwrap import dedent from types import MethodType, ModuleType, UnionType -from typing import TYPE_CHECKING, Literal, Union, get_args, get_origin, overload +from typing import ( + TYPE_CHECKING, + Literal, + NamedTuple, + Union, + get_args, + get_origin, + overload, +) from weakref import WeakSet import h5py @@ -297,6 +304,11 @@ def get_igraph_from_adjacency(adjacency, directed=None): # -------------------------------------------------------------------------------- +class AssoResult(NamedTuple): + asso_names: list[str] + asso_matrix: NDArray[np.floating] + + def compute_association_matrix_of_groups( adata: AnnData, prediction: str, @@ -305,7 +317,7 @@ def compute_association_matrix_of_groups( normalization: Literal["prediction", "reference"] = "prediction", threshold: float = 0.01, max_n_names: int | None = 2, -): +) -> AssoResult: """Compute overlaps between groups. See ``identify_groups`` for identifying the groups. @@ -347,8 +359,8 @@ def compute_association_matrix_of_groups( f"Ignoring category {cat!r} " "as it’s in `settings.categories_to_ignore`." ) - asso_names = [] - asso_matrix = [] + asso_names: list[str] = [] + asso_matrix: list[list[float]] = [] for ipred_group, pred_group in enumerate(adata.obs[prediction].cat.categories): if "?" in pred_group: pred_group = str(ipred_group) @@ -381,13 +393,12 @@ def compute_association_matrix_of_groups( if asso_matrix[-1][i] > threshold ] asso_names += ["\n".join(name_list_pred[:max_n_names])] - Result = namedtuple( - "compute_association_matrix_of_groups", ["asso_names", "asso_matrix"] - ) - return Result(asso_names=asso_names, asso_matrix=np.array(asso_matrix)) + return AssoResult(asso_names=asso_names, asso_matrix=np.array(asso_matrix)) -def get_associated_colors_of_groups(reference_colors, asso_matrix): +def get_associated_colors_of_groups( + reference_colors: Mapping[int, str], asso_matrix: NDArray[np.floating] +) -> list[dict[str, float]]: return [ { reference_colors[i_ref]: asso_matrix[i_pred, i_ref] diff --git a/src/scanpy/cli.py b/src/scanpy/cli.py index 04b75c8b74..c934292dba 100644 --- a/src/scanpy/cli.py +++ b/src/scanpy/cli.py @@ -11,7 +11,7 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: - from collections.abc import Generator, Mapping, Sequence + from collections.abc import Iterator, Mapping, Sequence from subprocess import CompletedProcess from typing import Any @@ -64,7 +64,7 @@ def __delitem__(self, k: str) -> None: # These methods retrieve the command list or help with doing it - def __iter__(self) -> Generator[str, None, None]: + def __iter__(self) -> Iterator[str]: yield from self.parser_map yield from self.commands diff --git a/src/scanpy/get/_aggregated.py b/src/scanpy/get/_aggregated.py index 2d2739491e..13ca54b5c4 100644 --- a/src/scanpy/get/_aggregated.py +++ b/src/scanpy/get/_aggregated.py @@ -160,7 +160,7 @@ def median(self) -> Array: return np.array(medians) -def _power(X: Array, power: float | int) -> Array: +def _power(X: Array, power: float) -> Array: """\ Generate elementwise power of a matrix. diff --git a/src/scanpy/plotting/_anndata.py b/src/scanpy/plotting/_anndata.py index 0ae810b2c7..a93d55699b 100755 --- a/src/scanpy/plotting/_anndata.py +++ b/src/scanpy/plotting/_anndata.py @@ -104,7 +104,7 @@ def scatter( components: str | Collection[str] | None = None, projection: Literal["2d", "3d"] = "2d", legend_loc: _LegendLoc | None = "right margin", - legend_fontsize: int | float | _FontSize | None = None, + legend_fontsize: float | _FontSize | None = None, legend_fontweight: int | _FontWeight | None = None, legend_fontoutline: float | None = None, color_map: str | Colormap | None = None, @@ -112,7 +112,7 @@ def scatter( frameon: bool | None = None, right_margin: float | None = None, left_margin: float | None = None, - size: int | float | None = None, + size: float | None = None, marker: str | Sequence[str] = ".", title: str | Collection[str] | None = None, show: bool | None = None, @@ -232,7 +232,7 @@ def _scatter_obs( components: str | Collection[str] | None = None, projection: Literal["2d", "3d"] = "2d", legend_loc: _LegendLoc | None = "right margin", - legend_fontsize: int | float | _FontSize | None = None, + legend_fontsize: float | _FontSize | None = None, legend_fontweight: int | _FontWeight | None = None, legend_fontoutline: float | None = None, color_map: str | Colormap | None = None, @@ -240,7 +240,7 @@ def _scatter_obs( frameon: bool | None = None, right_margin: float | None = None, left_margin: float | None = None, - size: int | float | None = None, + size: float | None = None, marker: str | Sequence[str] = ".", title: str | Collection[str] | None = None, show: bool | None = None, diff --git a/src/scanpy/plotting/_stacked_violin.py b/src/scanpy/plotting/_stacked_violin.py index 691dd863d0..e47680facc 100644 --- a/src/scanpy/plotting/_stacked_violin.py +++ b/src/scanpy/plotting/_stacked_violin.py @@ -273,7 +273,7 @@ def style( cmap: Colormap | str | None | Empty = _empty, stripplot: bool | Empty = _empty, jitter: float | bool | Empty = _empty, - jitter_size: int | float | Empty = _empty, + jitter_size: float | Empty = _empty, linewidth: float | None | Empty = _empty, row_palette: str | None | Empty = _empty, density_norm: DensityNorm | Empty = _empty, @@ -470,8 +470,8 @@ def _make_rows_of_violinplots( _matrix, colormap_array, _color_df, - x_spacer_size: float | int, - y_spacer_size: float | int, + x_spacer_size: float, + y_spacer_size: float, x_axis_order, ): import seaborn as sns # Slow import, only import if called @@ -699,7 +699,7 @@ def stacked_violin( cmap: Colormap | str | None = StackedViolin.DEFAULT_COLORMAP, stripplot: bool = StackedViolin.DEFAULT_STRIPPLOT, jitter: float | bool = StackedViolin.DEFAULT_JITTER, - size: int | float = StackedViolin.DEFAULT_JITTER_SIZE, + size: float = StackedViolin.DEFAULT_JITTER_SIZE, row_palette: str | None = StackedViolin.DEFAULT_ROW_PALETTE, density_norm: DensityNorm | Empty = _empty, yticklabels: bool = StackedViolin.DEFAULT_PLOT_YTICKLABELS, diff --git a/src/scanpy/plotting/_tools/__init__.py b/src/scanpy/plotting/_tools/__init__.py index 837d3791e8..a421f6b94a 100644 --- a/src/scanpy/plotting/_tools/__init__.py +++ b/src/scanpy/plotting/_tools/__init__.py @@ -1209,7 +1209,7 @@ def rank_genes_groups_violin( split: bool = True, density_norm: DensityNorm = "width", strip: bool = True, - jitter: int | float | bool = True, + jitter: float | bool = True, size: int = 1, ax: Axes | None = None, show: bool | None = None, @@ -1428,7 +1428,7 @@ def embedding_density( *, key: str | None = None, groupby: str | None = None, - group: str | Sequence[str] | None | None = "all", + group: str | Sequence[str] | None = "all", color_map: Colormap | str = "YlOrRd", bg_dotsize: int | None = 80, fg_dotsize: int | None = 180, diff --git a/src/scanpy/plotting/_tools/paga.py b/src/scanpy/plotting/_tools/paga.py index 29408735b6..7e62d46eac 100644 --- a/src/scanpy/plotting/_tools/paga.py +++ b/src/scanpy/plotting/_tools/paga.py @@ -73,7 +73,7 @@ def paga_compare( components=None, projection: Literal["2d", "3d"] = "2d", legend_loc: _LegendLoc | None = "on data", - legend_fontsize: int | float | _FontSize | None = None, + legend_fontsize: float | _FontSize | None = None, legend_fontweight: int | _FontWeight = "bold", legend_fontoutline=None, color_map=None, @@ -1053,7 +1053,7 @@ def paga_path( show_node_names: bool = True, show_yticks: bool = True, show_colorbar: bool = True, - legend_fontsize: int | float | _FontSize | None = None, + legend_fontsize: float | _FontSize | None = None, legend_fontweight: int | _FontWeight | None = None, normalize_to_zero_one: bool = False, as_heatmap: bool = True, diff --git a/src/scanpy/plotting/_tools/scatterplots.py b/src/scanpy/plotting/_tools/scatterplots.py index 7f69a76025..4ce39f7211 100644 --- a/src/scanpy/plotting/_tools/scatterplots.py +++ b/src/scanpy/plotting/_tools/scatterplots.py @@ -94,7 +94,7 @@ def embedding( na_in_legend: bool = True, size: float | Sequence[float] | None = None, frameon: bool | None = None, - legend_fontsize: int | float | _FontSize | None = None, + legend_fontsize: float | _FontSize | None = None, legend_fontweight: int | _FontWeight = "bold", legend_loc: _LegendLoc | None = "right margin", legend_fontoutline: int | None = None, diff --git a/src/scanpy/preprocessing/_scale.py b/src/scanpy/preprocessing/_scale.py index be452c356d..a7a16bbcc4 100644 --- a/src/scanpy/preprocessing/_scale.py +++ b/src/scanpy/preprocessing/_scale.py @@ -148,7 +148,6 @@ def scale_array( | tuple[ np.ndarray | DaskArray, NDArray[np.float64] | DaskArray, NDArray[np.float64] ] - | DaskArray ): if copy: X = X.copy() diff --git a/src/scanpy/preprocessing/_scrublet/sparse_utils.py b/src/scanpy/preprocessing/_scrublet/sparse_utils.py index b4ff1a36b0..cc0b1bc815 100644 --- a/src/scanpy/preprocessing/_scrublet/sparse_utils.py +++ b/src/scanpy/preprocessing/_scrublet/sparse_utils.py @@ -17,7 +17,7 @@ def sparse_multiply( E: sparse.csr_matrix | sparse.csc_matrix | NDArray[np.float64], - a: float | int | NDArray[np.float64], + a: float | NDArray[np.float64], ) -> sparse.csr_matrix | sparse.csc_matrix: """multiply each row of E by a scalar""" diff --git a/src/scanpy/tools/_marker_gene_overlap.py b/src/scanpy/tools/_marker_gene_overlap.py index 83a19c86a4..eb07b84885 100644 --- a/src/scanpy/tools/_marker_gene_overlap.py +++ b/src/scanpy/tools/_marker_gene_overlap.py @@ -4,7 +4,7 @@ from __future__ import annotations -from collections.abc import Set +from collections.abc import Set as AbstractSet from typing import TYPE_CHECKING import numpy as np @@ -187,7 +187,7 @@ def marker_gene_overlap( if normalize is not None and method != "overlap_count": raise ValueError("Can only normalize with method=`overlap_count`.") - if not all(isinstance(val, Set) for val in reference_markers.values()): + if not all(isinstance(val, AbstractSet) for val in reference_markers.values()): try: reference_markers = { key: set(val) for key, val in reference_markers.items() diff --git a/src/scanpy/tools/_rank_genes_groups.py b/src/scanpy/tools/_rank_genes_groups.py index f8ab13e9fd..9a2896196a 100644 --- a/src/scanpy/tools/_rank_genes_groups.py +++ b/src/scanpy/tools/_rank_genes_groups.py @@ -749,7 +749,7 @@ def filter_rank_genes_groups( use_raw: bool | None = None, key_added: str = "rank_genes_groups_filtered", min_in_group_fraction: float = 0.25, - min_fold_change: int | float = 1, + min_fold_change: float = 1, max_out_group_fraction: float = 0.5, compare_abs: bool = False, ) -> None: diff --git a/src/scanpy/tools/_tsne.py b/src/scanpy/tools/_tsne.py index 23d490218b..ac0e6a6317 100644 --- a/src/scanpy/tools/_tsne.py +++ b/src/scanpy/tools/_tsne.py @@ -34,10 +34,10 @@ def tsne( n_pcs: int | None = None, *, use_rep: str | None = None, - perplexity: float | int = 30, + perplexity: float = 30, metric: str = "euclidean", - early_exaggeration: float | int = 12, - learning_rate: float | int = 1000, + early_exaggeration: float = 12, + learning_rate: float = 1000, random_state: AnyRandom = 0, use_fast_tsne: bool = False, n_jobs: int | None = None, From f3e5d4e07100ba5ab8fcbc71d4c92f5a873a74a2 Mon Sep 17 00:00:00 2001 From: Ilan Gold Date: Thu, 7 Nov 2024 12:44:51 +0100 Subject: [PATCH 079/118] (feat): `calculate_qc_metrics` with `dask` (#3307) Co-authored-by: Philipp A. --- docs/release-notes/3307.feature.md | 1 + src/scanpy/_utils/__init__.py | 23 +++- src/scanpy/preprocessing/_qc.py | 87 +++++++------ src/testing/scanpy/_helpers/__init__.py | 24 +++- tests/test_qc_metrics.py | 159 +++++++++++++++++------- 5 files changed, 208 insertions(+), 86 deletions(-) create mode 100644 docs/release-notes/3307.feature.md diff --git a/docs/release-notes/3307.feature.md b/docs/release-notes/3307.feature.md new file mode 100644 index 0000000000..1505befb40 --- /dev/null +++ b/docs/release-notes/3307.feature.md @@ -0,0 +1 @@ +Add support {class}`dask.array.Array` to {func}`scanpy.pp.calculate_qc_metrics` {smaller}`I Gold` diff --git a/src/scanpy/_utils/__init__.py b/src/scanpy/_utils/__init__.py index 066e23f667..d97b23f7ae 100644 --- a/src/scanpy/_utils/__init__.py +++ b/src/scanpy/_utils/__init__.py @@ -54,7 +54,7 @@ from typing import Any, TypeVar from anndata import AnnData - from numpy.typing import DTypeLike, NDArray + from numpy.typing import ArrayLike, DTypeLike, NDArray from ..neighbors import NeighborsParams, RPForestDict @@ -738,6 +738,27 @@ def _( ) +@singledispatch +def axis_nnz(X: ArrayLike, axis: Literal[0, 1]) -> np.ndarray: + return np.count_nonzero(X, axis=axis) + + +@axis_nnz.register(sparse.spmatrix) +def _(X: sparse.spmatrix, axis: Literal[0, 1]) -> np.ndarray: + return X.getnnz(axis=axis) + + +@axis_nnz.register(DaskArray) +def _(X: DaskArray, axis: Literal[0, 1]) -> DaskArray: + return X.map_blocks( + partial(axis_nnz, axis=axis), + dtype=np.int64, + meta=np.array([], dtype=np.int64), + drop_axis=0, + chunks=len(X.to_delayed()) * (X.chunksize[int(not axis)],), + ) + + @overload def axis_sum( X: sparse.spmatrix, diff --git a/src/scanpy/preprocessing/_qc.py b/src/scanpy/preprocessing/_qc.py index 508beb7861..72b0e9cd50 100644 --- a/src/scanpy/preprocessing/_qc.py +++ b/src/scanpy/preprocessing/_qc.py @@ -1,15 +1,19 @@ from __future__ import annotations +from functools import singledispatch from typing import TYPE_CHECKING from warnings import warn import numba import numpy as np import pandas as pd -from scipy.sparse import csr_matrix, issparse, isspmatrix_coo, isspmatrix_csr -from sklearn.utils.sparsefuncs import mean_variance_axis +from scipy.sparse import csr_matrix, issparse, isspmatrix_coo, isspmatrix_csr, spmatrix -from .._utils import _doc_params +from scanpy.preprocessing._distributed import materialize_as_ndarray +from scanpy.preprocessing._utils import _get_mean_var + +from .._compat import DaskArray +from .._utils import _doc_params, axis_nnz, axis_sum from ._docs import ( doc_adata_basic, doc_expr_reps, @@ -23,7 +27,6 @@ from collections.abc import Collection from anndata import AnnData - from scipy.sparse import spmatrix def _choose_mtx_rep(adata, *, use_raw: bool = False, layer: str | None = None): @@ -104,15 +107,14 @@ def describe_obs( if issparse(X): X.eliminate_zeros() obs_metrics = pd.DataFrame(index=adata.obs_names) - if issparse(X): - obs_metrics[f"n_{var_type}_by_{expr_type}"] = X.getnnz(axis=1) - else: - obs_metrics[f"n_{var_type}_by_{expr_type}"] = np.count_nonzero(X, axis=1) + obs_metrics[f"n_{var_type}_by_{expr_type}"] = materialize_as_ndarray( + axis_nnz(X, axis=1) + ) if log1p: obs_metrics[f"log1p_n_{var_type}_by_{expr_type}"] = np.log1p( obs_metrics[f"n_{var_type}_by_{expr_type}"] ) - obs_metrics[f"total_{expr_type}"] = np.ravel(X.sum(axis=1)) + obs_metrics[f"total_{expr_type}"] = np.ravel(axis_sum(X, axis=1)) if log1p: obs_metrics[f"log1p_total_{expr_type}"] = np.log1p( obs_metrics[f"total_{expr_type}"] @@ -126,7 +128,7 @@ def describe_obs( ) for qc_var in qc_vars: obs_metrics[f"total_{expr_type}_{qc_var}"] = np.ravel( - X[:, adata.var[qc_var].values].sum(axis=1) + axis_sum(X[:, adata.var[qc_var].values], axis=1) ) if log1p: obs_metrics[f"log1p_total_{expr_type}_{qc_var}"] = np.log1p( @@ -141,6 +143,7 @@ def describe_obs( adata.obs[obs_metrics.columns] = obs_metrics else: return obs_metrics + return None @_doc_params( @@ -191,13 +194,9 @@ def describe_var( if issparse(X): X.eliminate_zeros() var_metrics = pd.DataFrame(index=adata.var_names) - if issparse(X): - # Current memory bottleneck for csr matrices: - var_metrics["n_cells_by_{expr_type}"] = X.getnnz(axis=0) - var_metrics["mean_{expr_type}"] = mean_variance_axis(X, axis=0)[0] - else: - var_metrics["n_cells_by_{expr_type}"] = np.count_nonzero(X, axis=0) - var_metrics["mean_{expr_type}"] = X.mean(axis=0) + var_metrics["n_cells_by_{expr_type}"], var_metrics["mean_{expr_type}"] = ( + materialize_as_ndarray((axis_nnz(X, axis=0), _get_mean_var(X, axis=0)[0])) + ) if log1p: var_metrics["log1p_mean_{expr_type}"] = np.log1p( var_metrics["mean_{expr_type}"] @@ -205,7 +204,7 @@ def describe_var( var_metrics["pct_dropout_by_{expr_type}"] = ( 1 - var_metrics["n_cells_by_{expr_type}"] / X.shape[0] ) * 100 - var_metrics["total_{expr_type}"] = np.ravel(X.sum(axis=0)) + var_metrics["total_{expr_type}"] = np.ravel(axis_sum(X, axis=0)) if log1p: var_metrics["log1p_total_{expr_type}"] = np.log1p( var_metrics["total_{expr_type}"] @@ -217,8 +216,8 @@ def describe_var( var_metrics.columns = new_colnames if inplace: adata.var[var_metrics.columns] = var_metrics - else: - return var_metrics + return None + return var_metrics @_doc_params( @@ -387,9 +386,18 @@ def top_proportions_sparse_csr(data, indptr, n): return values -def top_segment_proportions( - mtx: np.ndarray | spmatrix, ns: Collection[int] -) -> np.ndarray: +def check_ns(func): + def check_ns_inner(mtx: np.ndarray | spmatrix | DaskArray, ns: Collection[int]): + if not (max(ns) <= mtx.shape[1] and min(ns) > 0): + raise IndexError("Positions outside range of features.") + return func(mtx, ns) + + return check_ns_inner + + +@singledispatch +@check_ns +def top_segment_proportions(mtx: np.ndarray, ns: Collection[int]) -> np.ndarray: """ Calculates total percentage of counts in top ns genes. @@ -402,20 +410,6 @@ def top_segment_proportions( 1-indexed, e.g. `ns=[50]` will calculate cumulative proportion up to the 50th most expressed gene. """ - # Pretty much just does dispatch - if not (max(ns) <= mtx.shape[1] and min(ns) > 0): - raise IndexError("Positions outside range of features.") - if issparse(mtx): - if not isspmatrix_csr(mtx): - mtx = csr_matrix(mtx) - return top_segment_proportions_sparse_csr(mtx.data, mtx.indptr, np.array(ns)) - else: - return top_segment_proportions_dense(mtx, ns) - - -def top_segment_proportions_dense( - mtx: np.ndarray | spmatrix, ns: Collection[int] -) -> np.ndarray: # Currently ns is considered to be 1 indexed ns = np.sort(ns) sums = mtx.sum(axis=1) @@ -432,6 +426,25 @@ def top_segment_proportions_dense( return values / sums[:, None] +@top_segment_proportions.register(DaskArray) +@check_ns +def _(mtx: DaskArray, ns: Collection[int]) -> DaskArray: + if not isinstance(mtx._meta, csr_matrix | np.ndarray): + msg = f"DaskArray must have csr matrix or ndarray meta, got {mtx._meta}." + raise ValueError(msg) + return mtx.map_blocks( + lambda x: top_segment_proportions(x, ns), meta=np.array([]) + ).compute() + + +@top_segment_proportions.register(spmatrix) +@check_ns +def _(mtx: spmatrix, ns: Collection[int]) -> DaskArray: + if not isspmatrix_csr(mtx): + mtx = csr_matrix(mtx) + return top_segment_proportions_sparse_csr(mtx.data, mtx.indptr, np.array(ns)) + + @numba.njit(cache=True, parallel=True) def top_segment_proportions_sparse_csr(data, indptr, ns): # work around https://github.com/numba/numba/issues/5056 diff --git a/src/testing/scanpy/_helpers/__init__.py b/src/testing/scanpy/_helpers/__init__.py index 0c59eb592f..3cff738132 100644 --- a/src/testing/scanpy/_helpers/__init__.py +++ b/src/testing/scanpy/_helpers/__init__.py @@ -5,8 +5,9 @@ from __future__ import annotations import warnings -from contextlib import AbstractContextManager +from contextlib import AbstractContextManager, contextmanager from dataclasses import dataclass +from importlib.util import find_spec from itertools import permutations from typing import TYPE_CHECKING @@ -158,3 +159,24 @@ def __enter__(self): def __exit__(self, exc_type, exc_value, traceback): for ctx in reversed(self.contexts): ctx.__exit__(exc_type, exc_value, traceback) + + +@contextmanager +def maybe_dask_process_context(): + """ + Running numba with dask's threaded scheduler causes crashes, + so we need to switch to single-threaded (or processes, which is slower) + scheduler for tests that use numba. + """ + if not find_spec("dask"): + yield + return + + import dask.config + + prev_scheduler = dask.config.get("scheduler", "threads") + dask.config.set(scheduler="single-threaded") + try: + yield + finally: + dask.config.set(scheduler=prev_scheduler) diff --git a/tests/test_qc_metrics.py b/tests/test_qc_metrics.py index 83971fa2ce..7ca6534b7c 100644 --- a/tests/test_qc_metrics.py +++ b/tests/test_qc_metrics.py @@ -4,19 +4,25 @@ import pandas as pd import pytest from anndata import AnnData +from anndata.tests.helpers import assert_equal from scipy import sparse import scanpy as sc +from scanpy._compat import DaskArray +from scanpy._utils import axis_sum from scanpy.preprocessing._qc import ( describe_obs, describe_var, top_proportions, top_segment_proportions, ) +from testing.scanpy._helpers import as_sparse_dask_array, maybe_dask_process_context +from testing.scanpy._pytest.marks import needs +from testing.scanpy._pytest.params import ARRAY_TYPES @pytest.fixture -def anndata(): +def adata() -> AnnData: a = np.random.binomial(100, 0.005, (1000, 1000)) adata = AnnData( sparse.csr_matrix(a), @@ -26,6 +32,22 @@ def anndata(): return adata +def prepare_adata(adata: AnnData) -> AnnData: + if isinstance(adata.X, DaskArray): + adata.X = adata.X.rechunk((100, -1)) + adata.var["mito"] = np.concatenate( + (np.ones(100, dtype=bool), np.zeros(900, dtype=bool)) + ) + adata.var["negative"] = False + return adata + + +@pytest.fixture(params=ARRAY_TYPES) +def adata_prepared(request: pytest.FixtureRequest, adata: AnnData) -> AnnData: + adata.X = request.param(adata.X) + return prepare_adata(adata) + + @pytest.mark.parametrize( "a", [np.ones((100, 100)), sparse.csr_matrix(np.ones((100, 100)))], @@ -67,58 +89,101 @@ def test_top_segments(cls): # While many of these are trivial, # they’re also just making sure the metrics are there -def test_qc_metrics(): - adata = AnnData(X=sparse.csr_matrix(np.random.binomial(100, 0.005, (1000, 1000)))) - adata.var["mito"] = np.concatenate( - (np.ones(100, dtype=bool), np.zeros(900, dtype=bool)) +def test_qc_metrics(adata_prepared: AnnData): + with maybe_dask_process_context(): + sc.pp.calculate_qc_metrics( + adata_prepared, qc_vars=["mito", "negative"], inplace=True + ) + X = ( + adata_prepared.X.compute() + if isinstance(adata_prepared.X, DaskArray) + else adata_prepared.X ) - adata.var["negative"] = False - sc.pp.calculate_qc_metrics(adata, qc_vars=["mito", "negative"], inplace=True) - assert (adata.obs["n_genes_by_counts"] < adata.shape[1]).all() + max_X = X.max(axis=0) + if isinstance(max_X, sparse.spmatrix): + max_X = max_X.toarray() + elif isinstance(max_X, DaskArray): + max_X = max_X.compute() + assert (adata_prepared.obs["n_genes_by_counts"] < adata_prepared.shape[1]).all() + assert ( + adata_prepared.obs["n_genes_by_counts"] + >= adata_prepared.obs["log1p_n_genes_by_counts"] + ).all() + assert ( + adata_prepared.obs["total_counts"] + == np.ravel(axis_sum(adata_prepared.X, axis=1)) + ).all() assert ( - adata.obs["n_genes_by_counts"] >= adata.obs["log1p_n_genes_by_counts"] + adata_prepared.obs["total_counts"] >= adata_prepared.obs["log1p_total_counts"] ).all() - assert (adata.obs["total_counts"] == np.ravel(adata.X.sum(axis=1))).all() - assert (adata.obs["total_counts"] >= adata.obs["log1p_total_counts"]).all() assert ( - adata.obs["total_counts_mito"] >= adata.obs["log1p_total_counts_mito"] + adata_prepared.obs["total_counts_mito"] + >= adata_prepared.obs["log1p_total_counts_mito"] ).all() - assert (adata.obs["total_counts_negative"] == 0).all() + assert (adata_prepared.obs["total_counts_negative"] == 0).all() assert ( - adata.obs["pct_counts_in_top_50_genes"] - <= adata.obs["pct_counts_in_top_100_genes"] + adata_prepared.obs["pct_counts_in_top_50_genes"] + <= adata_prepared.obs["pct_counts_in_top_100_genes"] ).all() - for col in filter(lambda x: "negative" not in x, adata.obs.columns): - assert (adata.obs[col] >= 0).all() # Values should be positive or zero - assert (adata.obs[col] != 0).any().all() # Nothing should be all zeros + for col in filter(lambda x: "negative" not in x, adata_prepared.obs.columns): + assert (adata_prepared.obs[col] >= 0).all() # Values should be positive or zero + assert (adata_prepared.obs[col] != 0).any().all() # Nothing should be all zeros if col.startswith("pct_counts_in_top"): - assert (adata.obs[col] <= 100).all() - assert (adata.obs[col] >= 0).all() - for col in adata.var.columns: - assert (adata.var[col] >= 0).all() - assert (adata.var["mean_counts"] < np.ravel(adata.X.max(axis=0).todense())).all() - assert (adata.var["mean_counts"] >= adata.var["log1p_mean_counts"]).all() - assert (adata.var["total_counts"] >= adata.var["log1p_total_counts"]).all() - # Should return the same thing if run again - old_obs, old_var = adata.obs.copy(), adata.var.copy() - sc.pp.calculate_qc_metrics(adata, qc_vars=["mito", "negative"], inplace=True) - assert set(adata.obs.columns) == set(old_obs.columns) - assert set(adata.var.columns) == set(old_var.columns) - for col in adata.obs: - assert np.allclose(adata.obs[col], old_obs[col]) - for col in adata.var: - assert np.allclose(adata.var[col], old_var[col]) - # with log1p=False - adata = AnnData(X=sparse.csr_matrix(np.random.binomial(100, 0.005, (1000, 1000)))) - adata.var["mito"] = np.concatenate( - (np.ones(100, dtype=bool), np.zeros(900, dtype=bool)) - ) - adata.var["negative"] = False + assert (adata_prepared.obs[col] <= 100).all() + assert (adata_prepared.obs[col] >= 0).all() + for col in adata_prepared.var.columns: + assert (adata_prepared.var[col] >= 0).all() + assert (adata_prepared.var["mean_counts"] < np.ravel(max_X)).all() + assert ( + adata_prepared.var["mean_counts"] >= adata_prepared.var["log1p_mean_counts"] + ).all() + assert ( + adata_prepared.var["total_counts"] >= adata_prepared.var["log1p_total_counts"] + ).all() + + +def test_qc_metrics_idempotent(adata_prepared: AnnData): + with maybe_dask_process_context(): + sc.pp.calculate_qc_metrics( + adata_prepared, qc_vars=["mito", "negative"], inplace=True + ) + old_obs, old_var = adata_prepared.obs.copy(), adata_prepared.var.copy() + sc.pp.calculate_qc_metrics( + adata_prepared, qc_vars=["mito", "negative"], inplace=True + ) + assert set(adata_prepared.obs.columns) == set(old_obs.columns) + assert set(adata_prepared.var.columns) == set(old_var.columns) + for col in adata_prepared.obs: + assert np.allclose(adata_prepared.obs[col], old_obs[col]) + for col in adata_prepared.var: + assert np.allclose(adata_prepared.var[col], old_var[col]) + + +def test_qc_metrics_no_log1p(adata_prepared: AnnData): + with maybe_dask_process_context(): + sc.pp.calculate_qc_metrics( + adata_prepared, qc_vars=["mito", "negative"], log1p=False, inplace=True + ) + assert not np.any(adata_prepared.obs.columns.str.startswith("log1p_")) + assert not np.any(adata_prepared.var.columns.str.startswith("log1p_")) + + +@needs.dask +@pytest.mark.anndata_dask_support +@pytest.mark.parametrize("log1p", [True, False], ids=["log1p", "no_log1p"]) +def test_dask_against_in_memory(adata, log1p): + adata_as_dask = adata.copy() + adata_as_dask.X = as_sparse_dask_array(adata.X) + adata = prepare_adata(adata) + adata_as_dask = prepare_adata(adata_as_dask) + with maybe_dask_process_context(): + sc.pp.calculate_qc_metrics( + adata_as_dask, qc_vars=["mito", "negative"], log1p=log1p, inplace=True + ) sc.pp.calculate_qc_metrics( - adata, qc_vars=["mito", "negative"], log1p=False, inplace=True + adata, qc_vars=["mito", "negative"], log1p=log1p, inplace=True ) - assert not np.any(adata.obs.columns.str.startswith("log1p_")) - assert not np.any(adata.var.columns.str.startswith("log1p_")) + assert_equal(adata, adata_as_dask) def adata_mito(): @@ -166,8 +231,8 @@ def test_qc_metrics_percentage(): # In response to #421 sc.pp.calculate_qc_metrics(adata_dense, percent_top=[20, 30, 1001]) -def test_layer_raw(anndata): - adata = anndata.copy() +def test_layer_raw(adata: AnnData): + adata = adata.copy() adata.raw = adata.copy() adata.layers["counts"] = adata.X.copy() obs_orig, var_orig = sc.pp.calculate_qc_metrics(adata) @@ -180,8 +245,8 @@ def test_layer_raw(anndata): assert np.allclose(var_orig, var_raw) -def test_inner_methods(anndata): - adata = anndata.copy() +def test_inner_methods(adata: AnnData): + adata = adata.copy() full_inplace = adata.copy() partial_inplace = adata.copy() obs_orig, var_orig = sc.pp.calculate_qc_metrics(adata) From cad568af577e661c4b8f096352485afae80a5ac3 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 7 Nov 2024 15:39:45 +0100 Subject: [PATCH 080/118] Fix docs (#3343) --- src/scanpy/readwrite.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scanpy/readwrite.py b/src/scanpy/readwrite.py index cb75eb10cc..3c958a1e50 100644 --- a/src/scanpy/readwrite.py +++ b/src/scanpy/readwrite.py @@ -131,7 +131,7 @@ def read( See the h5py :ref:`dataset_compression`. (Default: `settings.cache_compression`) kwargs - Parameters passed to :func:`~anndata.read_loom`. + Parameters passed to :func:`~anndata.io.read_loom`. Returns ------- From ee134c5b2173dbe5e707f56127ff7134e2871123 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 8 Nov 2024 18:17:44 +0100 Subject: [PATCH 081/118] move all `njit` calls into a decorator (#3335) --- docs/release-notes/3335.feature.md | 1 + pyproject.toml | 2 + src/scanpy/_compat.py | 108 +++++++++++++++++- src/scanpy/_utils/compute/is_constant.py | 23 ++-- .../experimental/pp/_highly_variable_genes.py | 5 +- src/scanpy/metrics/_gearys_c.py | 13 +-- src/scanpy/metrics/_morans_i.py | 12 +- .../preprocessing/_highly_variable_genes.py | 5 +- src/scanpy/preprocessing/_qc.py | 4 +- src/scanpy/preprocessing/_scale.py | 6 +- src/scanpy/preprocessing/_simple.py | 3 +- src/scanpy/preprocessing/_utils.py | 5 +- 12 files changed, 150 insertions(+), 37 deletions(-) create mode 100644 docs/release-notes/3335.feature.md diff --git a/docs/release-notes/3335.feature.md b/docs/release-notes/3335.feature.md new file mode 100644 index 0000000000..77a1723a8e --- /dev/null +++ b/docs/release-notes/3335.feature.md @@ -0,0 +1 @@ +Run numba functions single-threaded when called from inside of a ThreadPool {smaller}`P Angerer` diff --git a/pyproject.toml b/pyproject.toml index e983d04a97..526eca781d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -262,6 +262,8 @@ required-imports = ["from __future__ import annotations"] "pandas.value_counts".msg = "Use pd.Series(a).value_counts() instead" "legacy_api_wrap.legacy_api".msg = "Use scanpy._compat.old_positionals instead" "numpy.bool".msg = "Use `np.bool_` instead for numpy>=1.24<2 compatibility" +"numba.jit".msg = "Use `scanpy._compat.njit` instead" +"numba.njit".msg = "Use `scanpy._compat.njit` instead" [tool.ruff.lint.flake8-type-checking] exempt-modules = [] strict = true diff --git a/src/scanpy/_compat.py b/src/scanpy/_compat.py index e247524c31..c5fa4dbe84 100644 --- a/src/scanpy/_compat.py +++ b/src/scanpy/_compat.py @@ -1,17 +1,23 @@ from __future__ import annotations +import os import sys +import warnings from dataclasses import dataclass, field -from functools import cache, partial +from functools import cache, partial, wraps from importlib.util import find_spec from pathlib import Path -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Literal, ParamSpec, TypeVar, cast, overload from packaging.version import Version if TYPE_CHECKING: + from collections.abc import Callable from importlib.metadata import PackageMetadata +P = ParamSpec("P") +R = TypeVar("R") + if TYPE_CHECKING: # type checkers are confused and can only see …core.Array @@ -90,3 +96,101 @@ def pkg_version(package: str) -> Version: # but this code makes it possible to run scanpy without it. def old_positionals(*old_positionals: str): return lambda func: func + + +@overload +def njit(fn: Callable[P, R], /) -> Callable[P, R]: ... +@overload +def njit() -> Callable[[Callable[P, R]], Callable[P, R]]: ... +def njit( + fn: Callable[P, R] | None = None, / +) -> Callable[P, R] | Callable[[Callable[P, R]], Callable[P, R]]: + """\ + Jit-compile a function using numba. + + On call, this function dispatches to a parallel or sequential numba function, + depending on if it has been called from a thread pool. + + See + """ + + def decorator(f: Callable[P, R], /) -> Callable[P, R]: + import numba + + fns: dict[bool, Callable[P, R]] = { + parallel: numba.njit(f, cache=True, parallel=parallel) # noqa: TID251 + for parallel in (True, False) + } + + @wraps(f) + def wrapper(*args: P.args, **kwargs: P.kwargs) -> R: + parallel = not _is_in_unsafe_thread_pool() + if not parallel: + msg = ( + "Detected unsupported threading environment. " + f"Trying to run {f.__name__} in serial mode. " + "In case of problems, install `tbb`." + ) + warnings.warn(msg, stacklevel=2) + return fns[parallel](*args, **kwargs) + + return wrapper + + return decorator if fn is None else decorator(fn) + + +LayerType = Literal["default", "safe", "threadsafe", "forksafe"] +Layer = Literal["tbb", "omp", "workqueue"] + + +LAYERS: dict[LayerType, set[Layer]] = { + "default": {"tbb", "omp", "workqueue"}, + "safe": {"tbb"}, + "threadsafe": {"tbb", "omp"}, + "forksafe": {"tbb", "workqueue", *(() if sys.platform == "linux" else {"omp"})}, +} + + +def _is_in_unsafe_thread_pool() -> bool: + import threading + + current_thread = threading.current_thread() + # ThreadPoolExecutor threads typically have names like 'ThreadPoolExecutor-0_1' + return ( + current_thread.name.startswith("ThreadPoolExecutor") + and _numba_threading_layer() not in LAYERS["threadsafe"] + ) + + +@cache +def _numba_threading_layer() -> Layer: + """\ + Get numba’s threading layer. + + This function implements the algorithm as described in + + """ + import importlib + + import numba + + if (available := LAYERS.get(numba.config.THREADING_LAYER)) is None: + # given by direct name + return numba.config.THREADING_LAYER + + # given by layer type (safe, …) + for layer in cast(list[Layer], numba.config.THREADING_LAYER_PRIORITY): + if layer not in available: + continue + if layer != "workqueue": + try: # `importlib.util.find_spec` doesn’t work here + importlib.import_module(f"numba.np.ufunc.{layer}pool") + except ImportError: + continue + # the layer has been found + return layer + msg = ( + f"No loadable threading layer: {numba.config.THREADING_LAYER=} " + f" ({available=}, {numba.config.THREADING_LAYER_PRIORITY=})" + ) + raise ValueError(msg) diff --git a/src/scanpy/_utils/compute/is_constant.py b/src/scanpy/_utils/compute/is_constant.py index 80f6581980..1bc147d68e 100644 --- a/src/scanpy/_utils/compute/is_constant.py +++ b/src/scanpy/_utils/compute/is_constant.py @@ -5,11 +5,11 @@ from numbers import Integral from typing import TYPE_CHECKING, TypeVar, overload +import numba import numpy as np -from numba import njit from scipy import sparse -from ..._compat import DaskArray +from ..._compat import DaskArray, njit if TYPE_CHECKING: from typing import Literal @@ -103,22 +103,21 @@ def _( else: return (a.data == 0).all() if axis == 1: - return _is_constant_csr_rows(a.data, a.indices, a.indptr, a.shape) + return _is_constant_csr_rows(a.data, a.indptr, a.shape) elif axis == 0: a = a.T.tocsr() - return _is_constant_csr_rows(a.data, a.indices, a.indptr, a.shape) + return _is_constant_csr_rows(a.data, a.indptr, a.shape) @njit def _is_constant_csr_rows( data: NDArray[np.number], - indices: NDArray[np.integer], indptr: NDArray[np.integer], shape: tuple[int, int], -): +) -> NDArray[np.bool_]: n = len(indptr) - 1 result = np.ones(n, dtype=np.bool_) - for i in range(n): + for i in numba.prange(n): start = indptr[i] stop = indptr[i + 1] val = data[start] if stop - start == shape[1] else 0 @@ -139,10 +138,10 @@ def _( else: return (a.data == 0).all() if axis == 0: - return _is_constant_csr_rows(a.data, a.indices, a.indptr, a.shape[::-1]) + return _is_constant_csr_rows(a.data, a.indptr, a.shape[::-1]) elif axis == 1: a = a.T.tocsc() - return _is_constant_csr_rows(a.data, a.indices, a.indptr, a.shape[::-1]) + return _is_constant_csr_rows(a.data, a.indptr, a.shape[::-1]) @is_constant.register(DaskArray) @@ -151,4 +150,8 @@ def _(a: DaskArray, axis: Literal[0, 1] | None = None) -> bool | NDArray[np.bool v = a[tuple(0 for _ in range(a.ndim))].compute() return (a == v).all() # TODO: use overlapping blocks and reduction instead of `drop_axis` - return a.map_blocks(partial(is_constant, axis=axis), drop_axis=axis) + return a.map_blocks( + partial(is_constant, axis=axis), + drop_axis=axis, + meta=np.array([], dtype=a.dtype), + ) diff --git a/src/scanpy/experimental/pp/_highly_variable_genes.py b/src/scanpy/experimental/pp/_highly_variable_genes.py index a8f8929e93..ab78f0a74a 100644 --- a/src/scanpy/experimental/pp/_highly_variable_genes.py +++ b/src/scanpy/experimental/pp/_highly_variable_genes.py @@ -12,6 +12,7 @@ from anndata import AnnData from scanpy import logging as logg +from scanpy._compat import njit from scanpy._settings import Verbosity, settings from scanpy._utils import _doc_params, check_nonnegative_integers, view_to_actual from scanpy.experimental._docs import ( @@ -32,7 +33,7 @@ from numpy.typing import NDArray -@nb.njit(parallel=True) +@njit def _calculate_res_sparse( indptr: NDArray[np.integer], index: NDArray[np.integer], @@ -92,7 +93,7 @@ def clac_clipped_res_sparse(gene: int, cell: int, value: np.float64) -> np.float return residuals -@nb.njit(parallel=True) +@njit def _calculate_res_dense( matrix, *, diff --git a/src/scanpy/metrics/_gearys_c.py b/src/scanpy/metrics/_gearys_c.py index a0ca9a0b61..358a201eed 100644 --- a/src/scanpy/metrics/_gearys_c.py +++ b/src/scanpy/metrics/_gearys_c.py @@ -9,7 +9,7 @@ import numpy as np from scipy import sparse -from .._compat import fullname +from .._compat import fullname, njit from ..get import _get_obs_rep from ._common import _check_vals, _resolve_vals @@ -136,7 +136,6 @@ def gearys_c( # tests to fail. -@numba.njit(cache=True, parallel=True) def _gearys_c_vec( data: np.ndarray, indices: np.ndarray, @@ -147,7 +146,7 @@ def _gearys_c_vec( return _gearys_c_vec_W(data, indices, indptr, x, W) -@numba.njit(cache=True, parallel=True) +@njit def _gearys_c_vec_W( data: np.ndarray, indices: np.ndarray, @@ -182,7 +181,7 @@ def _gearys_c_vec_W( # https://github.com/numba/numba/issues/6774#issuecomment-788789663 -@numba.njit(cache=True) +@numba.njit(cache=True, parallel=False) # noqa: TID251 def _gearys_c_inner_sparse_x_densevec( g_data: np.ndarray, g_indices: np.ndarray, @@ -203,7 +202,7 @@ def _gearys_c_inner_sparse_x_densevec( return numer / denom -@numba.njit(cache=True) +@numba.njit(cache=True, parallel=False) # noqa: TID251 def _gearys_c_inner_sparse_x_sparsevec( # noqa: PLR0917 g_data: np.ndarray, g_indices: np.ndarray, @@ -239,7 +238,7 @@ def _gearys_c_inner_sparse_x_sparsevec( # noqa: PLR0917 return numer / denom -@numba.njit(cache=True, parallel=True) +@njit def _gearys_c_mtx( g_data: np.ndarray, g_indices: np.ndarray, @@ -256,7 +255,7 @@ def _gearys_c_mtx( return out -@numba.njit(cache=True, parallel=True) +@njit def _gearys_c_mtx_csr( # noqa: PLR0917 g_data: np.ndarray, g_indices: np.ndarray, diff --git a/src/scanpy/metrics/_morans_i.py b/src/scanpy/metrics/_morans_i.py index 7c7609323e..5e4ab50788 100644 --- a/src/scanpy/metrics/_morans_i.py +++ b/src/scanpy/metrics/_morans_i.py @@ -9,7 +9,7 @@ import numpy as np from scipy import sparse -from .._compat import fullname +from .._compat import fullname, njit from ..get import _get_obs_rep from ._common import _check_vals, _resolve_vals @@ -126,7 +126,7 @@ def morans_i( # This is done in a very similar way to gearys_c. See notes there for details. -@numba.njit(cache=True, parallel=True) +@njit def _morans_i_vec( g_data: np.ndarray, g_indices: np.ndarray, @@ -137,7 +137,7 @@ def _morans_i_vec( return _morans_i_vec_W(g_data, g_indices, g_indptr, x, W) -@numba.njit(cache=True) +@numba.njit(cache=True, parallel=False) # noqa: TID251 def _morans_i_vec_W( g_data: np.ndarray, g_indices: np.ndarray, @@ -159,7 +159,7 @@ def _morans_i_vec_W( return len(x) / W * inum / z2ss -@numba.njit(cache=True) +@numba.njit(cache=True, parallel=False) # noqa: TID251 def _morans_i_vec_W_sparse( # noqa: PLR0917 g_data: np.ndarray, g_indices: np.ndarray, @@ -174,7 +174,7 @@ def _morans_i_vec_W_sparse( # noqa: PLR0917 return _morans_i_vec_W(g_data, g_indices, g_indptr, x, W) -@numba.njit(cache=True, parallel=True) +@njit def _morans_i_mtx( g_data: np.ndarray, g_indices: np.ndarray, @@ -191,7 +191,7 @@ def _morans_i_mtx( return out -@numba.njit(cache=True, parallel=True) +@njit def _morans_i_mtx_csr( # noqa: PLR0917 g_data: np.ndarray, g_indices: np.ndarray, diff --git a/src/scanpy/preprocessing/_highly_variable_genes.py b/src/scanpy/preprocessing/_highly_variable_genes.py index fa7971d21e..e34340b256 100644 --- a/src/scanpy/preprocessing/_highly_variable_genes.py +++ b/src/scanpy/preprocessing/_highly_variable_genes.py @@ -200,7 +200,8 @@ def _highly_variable_genes_seurat_v3( return df -@numba.njit(cache=True) +# parallel=False needed for accuracy +@numba.njit(cache=True, parallel=False) # noqa: TID251 def _sum_and_sum_squares_clipped( indices: NDArray[np.integer], data: NDArray[np.floating], @@ -211,7 +212,7 @@ def _sum_and_sum_squares_clipped( ) -> tuple[NDArray[np.float64], NDArray[np.float64]]: squared_batch_counts_sum = np.zeros(n_cols, dtype=np.float64) batch_counts_sum = np.zeros(n_cols, dtype=np.float64) - for i in range(nnz): + for i in numba.prange(nnz): idx = indices[i] element = min(np.float64(data[i]), clip_val[idx]) squared_batch_counts_sum[idx] += element**2 diff --git a/src/scanpy/preprocessing/_qc.py b/src/scanpy/preprocessing/_qc.py index 72b0e9cd50..27836e1717 100644 --- a/src/scanpy/preprocessing/_qc.py +++ b/src/scanpy/preprocessing/_qc.py @@ -12,7 +12,7 @@ from scanpy.preprocessing._distributed import materialize_as_ndarray from scanpy.preprocessing._utils import _get_mean_var -from .._compat import DaskArray +from .._compat import DaskArray, njit from .._utils import _doc_params, axis_nnz, axis_sum from ._docs import ( doc_adata_basic, @@ -445,7 +445,7 @@ def _(mtx: spmatrix, ns: Collection[int]) -> DaskArray: return top_segment_proportions_sparse_csr(mtx.data, mtx.indptr, np.array(ns)) -@numba.njit(cache=True, parallel=True) +@njit def top_segment_proportions_sparse_csr(data, indptr, ns): # work around https://github.com/numba/numba/issues/5056 indptr = indptr.astype(np.int64) diff --git a/src/scanpy/preprocessing/_scale.py b/src/scanpy/preprocessing/_scale.py index a7a16bbcc4..760c66cc5a 100644 --- a/src/scanpy/preprocessing/_scale.py +++ b/src/scanpy/preprocessing/_scale.py @@ -11,7 +11,7 @@ from scipy.sparse import issparse, isspmatrix_csc, spmatrix from .. import logging as logg -from .._compat import DaskArray, old_positionals +from .._compat import DaskArray, njit, old_positionals from .._utils import ( _check_array_function_arguments, axis_mul_or_truediv, @@ -32,7 +32,7 @@ from numpy.typing import NDArray -@numba.njit(cache=True, parallel=True) +@njit def _scale_sparse_numba(indptr, indices, data, *, std, mask_obs, clip): for i in numba.prange(len(indptr) - 1): if mask_obs[i]: @@ -43,7 +43,7 @@ def _scale_sparse_numba(indptr, indices, data, *, std, mask_obs, clip): data[j] /= std[indices[j]] -@numba.njit(parallel=True, cache=True) +@njit def clip_array(X: np.ndarray, *, max_value: float = 10, zero_center: bool = True): a_min, a_max = -max_value, max_value if X.ndim > 1: diff --git a/src/scanpy/preprocessing/_simple.py b/src/scanpy/preprocessing/_simple.py index 2b44797069..02ad758eae 100644 --- a/src/scanpy/preprocessing/_simple.py +++ b/src/scanpy/preprocessing/_simple.py @@ -1053,7 +1053,8 @@ def _downsample_total_counts(X, total_counts, random_state, replace): return X -@numba.njit(cache=True) +# TODO: can/should this be parallelized? +@numba.njit(cache=True) # noqa: TID251 def _downsample_array( col: np.ndarray, target: int, diff --git a/src/scanpy/preprocessing/_utils.py b/src/scanpy/preprocessing/_utils.py index f5ba280cfd..300d6450e8 100644 --- a/src/scanpy/preprocessing/_utils.py +++ b/src/scanpy/preprocessing/_utils.py @@ -8,6 +8,7 @@ from scipy import sparse from sklearn.random_projection import sample_without_replacement +from .._compat import njit from .._utils import axis_sum, elem_mul if TYPE_CHECKING: @@ -83,7 +84,7 @@ def sparse_mean_variance_axis(mtx: sparse.spmatrix, axis: int): ) -@numba.njit(cache=True, parallel=True) +@njit def sparse_mean_var_minor_axis( data, indices, indptr, *, major_len, minor_len, n_threads ): @@ -116,7 +117,7 @@ def sparse_mean_var_minor_axis( return means, variances -@numba.njit(cache=True, parallel=True) +@njit def sparse_mean_var_major_axis(data, indptr, *, major_len, minor_len, n_threads): """ Computes mean and variance for a sparse array for the major axis. From fb68987d6ffa24227f4cecc72eb97616b1431cd0 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Mon, 11 Nov 2024 13:43:38 +0100 Subject: [PATCH 082/118] Update notebooks (#3349) --- notebooks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notebooks b/notebooks index 3385df77ce..9f6926f87f 160000 --- a/notebooks +++ b/notebooks @@ -1 +1 @@ -Subproject commit 3385df77ce0f63987104bc644562a811c5d1b441 +Subproject commit 9f6926f87f052603916ee8f222965f654896e0c7 From dea952e299b6026b2b1c5b97797647953cc03c73 Mon Sep 17 00:00:00 2001 From: kaushal Date: Mon, 11 Nov 2024 18:22:09 +0530 Subject: [PATCH 083/118] Speedup (~20x) of scanpy.pp.regress_out function using Linear Least Square method. (#3284) Co-authored-by: Intron7 Co-authored-by: Philipp A. Co-authored-by: Severin Dicks <37635888+Intron7@users.noreply.github.com> --- docs/release-notes/3284.performance.md | 1 + src/scanpy/preprocessing/_simple.py | 90 ++++++++++++++++++------- src/scanpy/preprocessing/_utils.py | 43 ++++++++++++ tests/_data/regress_test_small.npy | Bin 0 -> 320128 bytes tests/test_preprocessing.py | 27 +++++++- 5 files changed, 136 insertions(+), 25 deletions(-) create mode 100644 docs/release-notes/3284.performance.md create mode 100644 tests/_data/regress_test_small.npy diff --git a/docs/release-notes/3284.performance.md b/docs/release-notes/3284.performance.md new file mode 100644 index 0000000000..31c95245ff --- /dev/null +++ b/docs/release-notes/3284.performance.md @@ -0,0 +1 @@ +* Speed up {func}`~scanpy.pp.regress_out` {smaller}`P Ashish, P Angerer & S Dicks` diff --git a/src/scanpy/preprocessing/_simple.py b/src/scanpy/preprocessing/_simple.py index 02ad758eae..22f907f308 100644 --- a/src/scanpy/preprocessing/_simple.py +++ b/src/scanpy/preprocessing/_simple.py @@ -8,7 +8,7 @@ import warnings from functools import singledispatch from itertools import repeat -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, TypeVar import numba import numpy as np @@ -19,7 +19,7 @@ from sklearn.utils import check_array, sparsefuncs from .. import logging as logg -from .._compat import old_positionals +from .._compat import njit, old_positionals from .._settings import settings as sett from .._utils import ( _check_array_function_arguments, @@ -32,6 +32,7 @@ ) from ..get import _get_obs_rep, _set_obs_rep from ._distributed import materialize_as_ndarray +from ._utils import _to_dense # install dask if available try: @@ -695,6 +696,34 @@ def normalize_per_cell( return X if copy else None +DT = TypeVar("DT") + + +@njit +def get_resid( + data: np.ndarray, + regressor: np.ndarray, + coeff: np.ndarray, +) -> np.ndarray: + for i in numba.prange(data.shape[0]): + data[i] -= regressor[i] @ coeff + return data + + +def numpy_regress_out( + data: np.ndarray, + regressor: np.ndarray, +) -> np.ndarray: + """\ + Numba kernel for regress out unwanted sorces of variantion. + Finding coefficient using Linear regression (Linear Least Squares). + """ + inv_gram_matrix = np.linalg.inv(regressor.T @ regressor) + coeff = inv_gram_matrix @ (regressor.T @ data) + data = get_resid(data, regressor, coeff) + return data + + @old_positionals("layer", "n_jobs", "copy") def regress_out( adata: AnnData, @@ -749,7 +778,6 @@ def regress_out( if issparse(X): logg.info(" sparse input is densified and may lead to high memory use") - X = X.toarray() n_jobs = sett.n_jobs if n_jobs is None else n_jobs @@ -766,6 +794,8 @@ def regress_out( ) logg.debug("... regressing on per-gene means within categories") regressors = np.zeros(X.shape, dtype="float32") + X = _to_dense(X, order="F") if issparse(X) else X + # TODO figure out if we should use a numba kernel for this for category in adata.obs[keys[0]].cat.categories: mask = (category == adata.obs[keys[0]]).values for ix, x in enumerate(X.T): @@ -778,32 +808,44 @@ def regress_out( # add column of ones at index 0 (first column) regressors.insert(0, "ones", 1.0) + regressors = regressors.to_numpy() - len_chunk = int(np.ceil(min(1000, X.shape[1]) / n_jobs)) - n_chunks = int(np.ceil(X.shape[1] / len_chunk)) + # if the regressors are not categorical and the matrix is not singular + # use the shortcut numpy_regress_out + if not variable_is_categorical and np.linalg.det(regressors.T @ regressors) != 0: + X = _to_dense(X, order="C") if issparse(X) else X + res = numpy_regress_out(X, regressors) - # split the adata.X matrix by columns in chunks of size n_chunk - # (the last chunk could be of smaller size than the others) - chunk_list = np.array_split(X, n_chunks, axis=1) - regressors_chunk = ( - np.array_split(regressors, n_chunks, axis=1) - if variable_is_categorical - else repeat(regressors) - ) + # for a categorical variable or if the above checks failed, + # we fall back to the GLM implemetation of regression. + else: + # split the adata.X matrix by columns in chunks of size n_chunk + # (the last chunk could be of smaller size than the others) + len_chunk = int(np.ceil(min(1000, X.shape[1]) / n_jobs)) + n_chunks = int(np.ceil(X.shape[1] / len_chunk)) + X = _to_dense(X, order="F") if issparse(X) else X + chunk_list = np.array_split(X, n_chunks, axis=1) + regressors_chunk = ( + np.array_split(regressors, n_chunks, axis=1) + if variable_is_categorical + else repeat(regressors) + ) - # each task is passed a data chunk (e.g. `adata.X[:, 0:100]``) and the regressors. - # This data will be passed to each of the jobs. - # TODO: figure out how to test that this doesn't oversubscribe resources - res = Parallel(n_jobs=n_jobs)( - delayed(_regress_out_chunk)( - data_chunk, regres, variable_is_categorical=variable_is_categorical + # each task is passed a data chunk (e.g. `adata.X[:, 0:100]``) and the regressors. + # This data will be passed to each of the jobs. + # TODO: figure out how to test that this doesn't oversubscribe resources + res = Parallel(n_jobs=n_jobs)( + delayed(_regress_out_chunk)( + data_chunk, regres, variable_is_categorical=variable_is_categorical + ) + for data_chunk, regres in zip(chunk_list, regressors_chunk, strict=False) ) - for data_chunk, regres in zip(chunk_list, regressors_chunk, strict=False) - ) - # res is a list of vectors (each corresponding to a regressed gene column). - # The transpose is needed to get the matrix in the shape needed - _set_obs_rep(adata, np.vstack(res).T, layer=layer) + # res is a list of vectors (each corresponding to a regressed gene column). + # The transpose is needed to get the matrix in the shape needed + res = np.vstack(res).T + + _set_obs_rep(adata, res, layer=layer) logg.info(" finished", time=start) return adata if copy else None diff --git a/src/scanpy/preprocessing/_utils.py b/src/scanpy/preprocessing/_utils.py index 300d6450e8..9c02f7e636 100644 --- a/src/scanpy/preprocessing/_utils.py +++ b/src/scanpy/preprocessing/_utils.py @@ -160,3 +160,46 @@ def sample_comb( np.prod(dims), nsamp, random_state=random_state, method=method ) return np.vstack(np.unravel_index(idx, dims)).T + + +def _to_dense( + X: sparse.spmatrix, + order: Literal["C", "F"] = "C", +) -> NDArray: + """\ + Numba kernel for np.toarray() function + """ + out = np.zeros(X.shape, dtype=X.dtype, order=order) + if X.format == "csr": + _to_dense_csr_numba(X.indptr, X.indices, X.data, out, X.shape) + elif X.format == "csc": + _to_dense_csc_numba(X.indptr, X.indices, X.data, out, X.shape) + else: + out = X.toarray(order=order) + return out + + +@njit +def _to_dense_csc_numba( + indptr: NDArray, + indices: NDArray, + data: NDArray, + X: NDArray, + shape: tuple[int, int], +) -> None: + for c in numba.prange(X.shape[1]): + for i in range(indptr[c], indptr[c + 1]): + X[indices[i], c] = data[i] + + +@njit +def _to_dense_csr_numba( + indptr: NDArray, + indices: NDArray, + data: NDArray, + X: NDArray, + shape: tuple[int, int], +) -> None: + for r in numba.prange(shape[0]): + for i in range(indptr[r], indptr[r + 1]): + X[r, indices[i]] = data[i] diff --git a/tests/_data/regress_test_small.npy b/tests/_data/regress_test_small.npy new file mode 100644 index 0000000000000000000000000000000000000000..5a590fb35f33916c28e2122cfd1a6f11a4854e28 GIT binary patch literal 320128 zcmbSS`9IX(_eT;X36-)-vQHc_kBxokbPgq*qO2K z#=i4?eg1{-{NVAJ8S{GG*E#2&`+Pp{^9DYA{6JNkoa{Z>r;7%LHm|HN-r&4=^R?tf zAsh{hV{Ksgzt1(S-x*>b+ZgLv8DekwM1_TgII%zcLYxkq|G(GKSqw*Zcr?Pk>dN;p3{;mcjs4drA; z-D-Dg;HYYJfg|5PI88`oR(jb7GTFC=H1^xUCeKshi$OE=ozY6P=Iex(u_T(s;Xar> zP3DqTx`M>kdJ}7$+QIHn@5flK9!PLY@Z<@s1wF4wPkUAzaAu30m;H+aIl_~Nk^S39 zIX5r6-emzgNGGPQ}y*mQK(KLfM|&Yb1WsDsVFzN`F#XTTqn@)l=Ab#Ru1%mLyhaR zvP+#vaFi={#Jm-fow@xt4tIjgrQ<5)TJ1pX^62B$2iwS2ie-EAaT|<=&vsulssi8B z-B)Q_I>72eY3MDHZB%z{)p0kl1JZwdDCx=U2N}74>3e!Ouu@)Y@!oF(YegHy(99Na ze&T)c(XVdU!AR6f#^t^BN|mp z$R#&O_4Dl(=-^^adrDsk8_&k;V}o~53pa1c+ulK#Kdnag{8AlEXl|ZW)ZIdKS6=t_ zGj_sr=RZFDf>^$dN2CNSyWz2Xa;LPwGAh@Ry)jr>3q8U!%Xy;R@ba8O(TRUGK++1L zdQAq1aJ6)$>RJbA;yE}?(TU3m)roxuOPebMtlIe1oD_?z&y!##f;eOAFGR6YNsUGPyK5JDpU<({K>A-p!}%bO2GprzBGG`Zdm=QIuXoiFr)#`^}- zFpXtYAx%qo6htO#s8-Zfmf8WVdgU>+i#td>vO+)${|73cuID$q)`QjPvA)Z9nnCu3 z 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

tcs+@6O6m8MUF7`h}@D{x&5E=%3 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

k;rNY`bO`*})`1GmXr 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

Q2Jv(E#>e&ta^=7rX-o`kl|ac<$%#xVz=tVt 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 Date: Mon, 11 Nov 2024 14:33:50 +0100 Subject: [PATCH 084/118] Fix zappy compatibility for clip_array (#3317) --- src/scanpy/_utils/__init__.py | 4 +-- src/scanpy/preprocessing/_scale.py | 42 ++++++++++++++++-------------- tests/test_preprocessing.py | 4 ++- 3 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/scanpy/_utils/__init__.py b/src/scanpy/_utils/__init__.py index d97b23f7ae..150afe8311 100644 --- a/src/scanpy/_utils/__init__.py +++ b/src/scanpy/_utils/__init__.py @@ -607,13 +607,13 @@ def check_op(op): @singledispatch def axis_mul_or_truediv( - X: np.ndarray, + X: ArrayLike, scaling_array: np.ndarray, axis: Literal[0, 1], op: Callable[[Any, Any], Any], *, allow_divide_by_zero: bool = True, - out: np.ndarray | None = None, + out: ArrayLike | None = None, ) -> np.ndarray: check_op(op) scaling_array = broadcast_axis(scaling_array, axis) diff --git a/src/scanpy/preprocessing/_scale.py b/src/scanpy/preprocessing/_scale.py index 760c66cc5a..d7123d5f65 100644 --- a/src/scanpy/preprocessing/_scale.py +++ b/src/scanpy/preprocessing/_scale.py @@ -30,6 +30,9 @@ if TYPE_CHECKING: from numpy.typing import NDArray + from scipy import sparse as sp + + CSMatrix = sp.csr_matrix | sp.csc_matrix @njit @@ -44,7 +47,9 @@ def _scale_sparse_numba(indptr, indices, data, *, std, mask_obs, clip): @njit -def clip_array(X: np.ndarray, *, max_value: float = 10, zero_center: bool = True): +def clip_array( + X: NDArray[np.floating], *, max_value: float, zero_center: bool +) -> NDArray[np.floating]: a_min, a_max = -max_value, max_value if X.ndim > 1: for r, c in numba.pndindex(X.shape): @@ -61,6 +66,14 @@ def clip_array(X: np.ndarray, *, max_value: float = 10, zero_center: bool = True return X +def clip_set(x: CSMatrix, *, max_value: float, zero_center: bool = True) -> CSMatrix: + x = x.copy() + x[x > max_value] = max_value + if zero_center: + x[x < -max_value] = -max_value + return x + + @renamed_arg("X", "data", pos_0=True) @old_positionals("zero_center", "max_value", "copy", "layer", "obsm") @singledispatch @@ -187,7 +200,8 @@ def scale_array( if zero_center: if isinstance(X, DaskArray) and issparse(X._meta): warnings.warn( - "zero-center being used with `DaskArray` sparse chunks. This can be bad if you have large chunks or intend to eventually read the whole data into memory.", + "zero-center being used with `DaskArray` sparse chunks. " + "This can be bad if you have large chunks or intend to eventually read the whole data into memory.", UserWarning, ) X -= mean @@ -203,25 +217,13 @@ def scale_array( # do the clipping if max_value is not None: logg.debug(f"... clipping at max_value {max_value}") - if isinstance(X, DaskArray) and issparse(X._meta): - - def clip_set(x): - x = x.copy() - x[x > max_value] = max_value - if zero_center: - x[x < -max_value] = -max_value - return x - - X = da.map_blocks(clip_set, X) + if isinstance(X, DaskArray): + clip = clip_set if issparse(X._meta) else clip_array + X = X.map_blocks(clip, max_value=max_value, zero_center=zero_center) + elif issparse(X): + X.data = clip_array(X.data, max_value=max_value, zero_center=False) else: - if isinstance(X, DaskArray): - X = X.map_blocks( - clip_array, max_value=max_value, zero_center=zero_center - ) - elif issparse(X): - X.data = clip_array(X.data, max_value=max_value, zero_center=False) - else: - X = clip_array(X, max_value=max_value, zero_center=zero_center) + X = clip_array(X, max_value=max_value, zero_center=zero_center) if return_mean_std: return X, mean, std else: diff --git a/tests/test_preprocessing.py b/tests/test_preprocessing.py index ce8313145e..b8f5115b01 100644 --- a/tests/test_preprocessing.py +++ b/tests/test_preprocessing.py @@ -17,6 +17,7 @@ anndata_v0_8_constructor_compat, check_rep_mutation, check_rep_results, + maybe_dask_process_context, ) from testing.scanpy._helpers.data import pbmc3k, pbmc68k_reduced from testing.scanpy._pytest.params import ARRAY_TYPES @@ -172,7 +173,8 @@ def test_scale_matrix_types(array_type, zero_center, max_value): adata_casted = adata.copy() adata_casted.X = array_type(adata_casted.raw.X) sc.pp.scale(adata, zero_center=zero_center, max_value=max_value) - sc.pp.scale(adata_casted, zero_center=zero_center, max_value=max_value) + with maybe_dask_process_context(): + sc.pp.scale(adata_casted, zero_center=zero_center, max_value=max_value) X = adata_casted.X if "dask" in array_type.__name__: X = X.compute() From 1b7d8f830aee7c22ace08b347295e784df074787 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 10:38:03 +0100 Subject: [PATCH 085/118] [pre-commit.ci] pre-commit autoupdate (#3354) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.7.2 → v0.7.3](https://github.com/astral-sh/ruff-pre-commit/compare/v0.7.2...v0.7.3) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 25b824a582..22194ec871 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.7.2 + rev: v0.7.3 hooks: - id: ruff types_or: [python, pyi, jupyter] From c6a5e588297fbcca8a3438260ef269b9a2aa4b43 Mon Sep 17 00:00:00 2001 From: "Lumberbot (aka Jack)" <39504233+meeseeksmachine@users.noreply.github.com> Date: Tue, 12 Nov 2024 02:06:36 -0800 Subject: [PATCH 086/118] Backport PR #3357 on branch main ((chore): generate 1.10.4 release notes) (#3359) Co-authored-by: Philipp A --- ci/scripts/min-deps.py | 16 +++++++++++++--- docs/release-notes/1.10.4.md | 17 +++++++++++++++++ docs/release-notes/3206.bugfix.md | 1 - docs/release-notes/3243.bugfix.md | 1 - docs/release-notes/3244.bugfix.md | 1 - docs/release-notes/3264.bugfix.md | 1 - docs/release-notes/3275.bugfix.md | 1 - docs/release-notes/3283.breaking.md | 1 - docs/release-notes/3286.bugfix.md | 1 - docs/release-notes/3299.bugfix.md | 1 - docs/release-notes/3302.bugfix.md | 1 - pyproject.toml | 5 ++--- 12 files changed, 32 insertions(+), 15 deletions(-) create mode 100644 docs/release-notes/1.10.4.md delete mode 100644 docs/release-notes/3206.bugfix.md delete mode 100644 docs/release-notes/3243.bugfix.md delete mode 100644 docs/release-notes/3244.bugfix.md delete mode 100644 docs/release-notes/3264.bugfix.md delete mode 100644 docs/release-notes/3275.bugfix.md delete mode 100644 docs/release-notes/3283.breaking.md delete mode 100644 docs/release-notes/3286.bugfix.md delete mode 100644 docs/release-notes/3299.bugfix.md delete mode 100644 docs/release-notes/3302.bugfix.md diff --git a/ci/scripts/min-deps.py b/ci/scripts/min-deps.py index f1381580b4..4dad297e03 100755 --- a/ci/scripts/min-deps.py +++ b/ci/scripts/min-deps.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# /// script +# dependencies = [ +# "tomli; python_version < '3.11'", +# "packaging", +# ] +# /// + from __future__ import annotations import argparse @@ -33,12 +40,15 @@ def min_dep(req: Requirement) -> Requirement: if req.extras: req_name = f"{req_name}[{','.join(req.extras)}]" - if not req.specifier: + filter_specs = [ + spec for spec in req.specifier if spec.operator in {"==", "~=", ">=", ">"} + ] + if not filter_specs: return Requirement(req_name) min_version = Version("0.0.0.a1") - for spec in req.specifier: - if spec.operator in [">", ">=", "~="]: + for spec in filter_specs: + if spec.operator in {">", ">=", "~="}: min_version = max(min_version, Version(spec.version)) elif spec.operator == "==": min_version = Version(spec.version) diff --git a/docs/release-notes/1.10.4.md b/docs/release-notes/1.10.4.md new file mode 100644 index 0000000000..d4ba850a46 --- /dev/null +++ b/docs/release-notes/1.10.4.md @@ -0,0 +1,17 @@ +(v1.10.4)= +### 1.10.4 {small}`2024-11-12` + +### Breaking changes + +- Remove Python 3.9 support {smaller}`P Angerer` ({pr}`3283`) + +### Bug fixes + +- Fix {meth}`scanpy.pl.DotPlot.style`, {meth}`scanpy.pl.MatrixPlot.style`, and {meth}`scanpy.pl.StackedViolin.style` resetting all non-specified parameters {smaller}`P Angerer` ({pr}`3206`) +- Accept `'group'` instead of `'obs'` for `standard_scale` parameter in {func}`~scanpy.pl.stacked_violin` {smaller}`P Angerer` ({pr}`3243`) +- Use `density_norm` instead of of `scale` (cont. from {pr}`2844`) in {func}`~scanpy.pl.violin` and {func}`~scanpy.pl.stacked_violin` {smaller}`P Angerer` ({pr}`3244`) +- Switched all compatibility adapters for positional parameters to {exc}`FutureWarning` {smaller}`P Angerer` ({pr}`3264`) +- Catch `PerfectSeparationWarning` during {func}`~scanpy.pp.regress_out` {smaller}`J Wagner` ({pr}`3275`) +- Fix {func}`scanpy.pp.highly_variable_genes` for batches of size 1 {smaller}`P Angerer` ({pr}`3286`) +- Fix {func}`scanpy.pl.scatter`’s `color` parameter to take collections as advertised {smaller}`P Angerer` ({pr}`3299`) +- Fix {func}`scanpy.pl.highest_expr_genes` when used with a categorical gene symbol column {smaller}`P Angerer` ({pr}`3302`) diff --git a/docs/release-notes/3206.bugfix.md b/docs/release-notes/3206.bugfix.md deleted file mode 100644 index 9e47d00b09..0000000000 --- a/docs/release-notes/3206.bugfix.md +++ /dev/null @@ -1 +0,0 @@ -Fix {meth}`scanpy.pl.DotPlot.style`, {meth}`scanpy.pl.MatrixPlot.style`, and {meth}`scanpy.pl.StackedViolin.style` resetting all non-specified parameters {smaller}`P Angerer` diff --git a/docs/release-notes/3243.bugfix.md b/docs/release-notes/3243.bugfix.md deleted file mode 100644 index 5aa6063b1e..0000000000 --- a/docs/release-notes/3243.bugfix.md +++ /dev/null @@ -1 +0,0 @@ -Accept `'group'` instead of `'obs'` for `standard_scale` parameter in {func}`~scanpy.pl.stacked_violin` {smaller}`P Angerer` diff --git a/docs/release-notes/3244.bugfix.md b/docs/release-notes/3244.bugfix.md deleted file mode 100644 index e918765588..0000000000 --- a/docs/release-notes/3244.bugfix.md +++ /dev/null @@ -1 +0,0 @@ -Use `density_norm` instead of of `scale` (cont. from {pr}`2844`) in {func}`~scanpy.pl.violin` and {func}`~scanpy.pl.stacked_violin` {smaller}`P Angerer` diff --git a/docs/release-notes/3264.bugfix.md b/docs/release-notes/3264.bugfix.md deleted file mode 100644 index 0886ee6aa3..0000000000 --- a/docs/release-notes/3264.bugfix.md +++ /dev/null @@ -1 +0,0 @@ -Switched all compatibility adapters for positional parameters to {exc}`FutureWarning` {smaller}`P Angerer` diff --git a/docs/release-notes/3275.bugfix.md b/docs/release-notes/3275.bugfix.md deleted file mode 100644 index 4465c7651d..0000000000 --- a/docs/release-notes/3275.bugfix.md +++ /dev/null @@ -1 +0,0 @@ -Catch `PerfectSeparationWarning` during {func}`~scanpy.pp.regress_out` {smaller}`J Wagner` diff --git a/docs/release-notes/3283.breaking.md b/docs/release-notes/3283.breaking.md deleted file mode 100644 index 6f391f325d..0000000000 --- a/docs/release-notes/3283.breaking.md +++ /dev/null @@ -1 +0,0 @@ -Remove Python 3.9 support {smaller}`P Angerer` diff --git a/docs/release-notes/3286.bugfix.md b/docs/release-notes/3286.bugfix.md deleted file mode 100644 index 164758a2fa..0000000000 --- a/docs/release-notes/3286.bugfix.md +++ /dev/null @@ -1 +0,0 @@ -Fix {func}`scanpy.pp.highly_variable_genes` for batches of size 1 {smaller}`P Angerer` diff --git a/docs/release-notes/3299.bugfix.md b/docs/release-notes/3299.bugfix.md deleted file mode 100644 index 1b0b512ad2..0000000000 --- a/docs/release-notes/3299.bugfix.md +++ /dev/null @@ -1 +0,0 @@ -Fix {func}`scanpy.pl.scatter`’s `color` parameter to take collections as advertised {smaller}`P Angerer` diff --git a/docs/release-notes/3302.bugfix.md b/docs/release-notes/3302.bugfix.md deleted file mode 100644 index 00d2468dad..0000000000 --- a/docs/release-notes/3302.bugfix.md +++ /dev/null @@ -1 +0,0 @@ -Fix {func}`scanpy.pl.highest_expr_genes` when used with a categorical gene symbol column {smaller}`P Angerer` diff --git a/pyproject.toml b/pyproject.toml index 526eca781d..8d221396bf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,7 +56,7 @@ dependencies = [ "tqdm", "scikit-learn>=1.1", "statsmodels>=0.13", - "patsy", + "patsy!=1.0.0", # https://github.com/pydata/patsy/issues/215 "networkx>=2.7", "natsort", "joblib", @@ -66,7 +66,6 @@ dependencies = [ "packaging>=21.3", "session-info", "legacy-api-wrap>=1.4", # for positional API deprecations - "get-annotations; python_version < '3.10'", ] dynamic = ["version"] @@ -124,7 +123,7 @@ doc = [ "ipython>=7.20", # for nbsphinx code highlighting "matplotlib!=3.6.1", "sphinxcontrib-bibtex", - "setuptools", + "setuptools", # undeclared dependency of sphinxcontrib-bibtex→pybtex # TODO: remove necessity for being able to import doc-linked classes "scanpy[paga,dask-ml]", "sam-algorithm", From 67059288fdd558664f4cb935e9fcfbdcd530a8cc Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 14 Nov 2024 10:41:54 +0100 Subject: [PATCH 087/118] Actually working min-deps job (#3337) --- .gitignore | 1 + ci/scripts/min-deps.py | 35 ++++++++++++++++++++++++------ ci/scripts/towncrier_automation.py | 4 ++++ hatch.toml | 9 +++++--- pyproject.toml | 2 +- 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index beafaf6171..d21120ee95 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ # Python build files __pycache__/ /src/scanpy/_version.py +/ci/scanpy-min-deps.txt /dist/ /*-env/ /env-*/ diff --git a/ci/scripts/min-deps.py b/ci/scripts/min-deps.py index 4dad297e03..b996302c01 100755 --- a/ci/scripts/min-deps.py +++ b/ci/scripts/min-deps.py @@ -11,6 +11,7 @@ import argparse import sys from collections import deque +from contextlib import ExitStack from pathlib import Path from typing import TYPE_CHECKING @@ -23,7 +24,7 @@ from packaging.version import Version if TYPE_CHECKING: - from collections.abc import Generator, Iterable + from collections.abc import Generator, Iterable, Sequence def min_dep(req: Requirement) -> Requirement: @@ -75,12 +76,19 @@ def extract_min_deps( yield min_dep(req) -def main(): +class Args(argparse.Namespace): + path: Path + output: Path | None + extras: list[str] + + +def main(argv: Sequence[str] | None = None) -> None: parser = argparse.ArgumentParser( prog="min-deps", - description="""Parse a pyproject.toml file and output a list of minimum dependencies. - - Output is directly passable to `pip install`.""", + description=( + "Parse a pyproject.toml file and output a list of minimum dependencies. " + "Output is optimized for `[uv] pip install` (see `-o`/`--output` for details)." + ), usage="pip install `python min-deps.py pyproject.toml`", ) parser.add_argument( @@ -89,8 +97,18 @@ def main(): parser.add_argument( "--extras", type=str, nargs="*", default=(), help="extras to install" ) + parser.add_argument( + *("--output", "-o"), + type=Path, + default=None, + help=( + "output file (default: stdout). " + "Without this option, output is space-separated for direct passing to `pip install`. " + "With this option, output written to a file newline-separated file usable as `requirements.txt` or `constraints.txt`." + ), + ) - args = parser.parse_args() + args = parser.parse_args(argv, Args()) pyproject = tomllib.loads(args.path.read_text()) @@ -102,7 +120,10 @@ def main(): min_deps = extract_min_deps(deps, pyproject=pyproject) - print(" ".join(map(str, min_deps))) + sep = "\n" if args.output else " " + with ExitStack() as stack: + f = stack.enter_context(args.output.open("w")) if args.output else sys.stdout + print(sep.join(map(str, min_deps)), file=f) if __name__ == "__main__": diff --git a/ci/scripts/towncrier_automation.py b/ci/scripts/towncrier_automation.py index 57a093a305..fd492f494a 100755 --- a/ci/scripts/towncrier_automation.py +++ b/ci/scripts/towncrier_automation.py @@ -1,4 +1,8 @@ #!/usr/bin/env python3 +# /// script +# dependencies = [ "towncrier", "packaging" ] +# /// + from __future__ import annotations import argparse diff --git a/hatch.toml b/hatch.toml index ab2bb7550e..ad5db60976 100644 --- a/hatch.toml +++ b/hatch.toml @@ -19,14 +19,17 @@ features = ["test", "dask-ml"] extra-dependencies = ["ipykernel"] overrides.matrix.deps.env-vars = [ { if = ["pre"], key = "UV_PRERELEASE", value = "allow" }, - { if = ["min"], key = "UV_RESOLUTION", value = "lowest-direct" }, + { if = ["min"], key = "UV_CONSTRAINT", value = "ci/scanpy-min-deps.txt" }, +] +overrides.matrix.deps.pre-install-commands = [ + { if = ["min"], value = "uv run ci/scripts/min-deps.py pyproject.toml -o ci/scanpy-min-deps.txt" }, ] overrides.matrix.deps.python = [ - { if = ["min"] , value = "3.10" }, + { if = ["min"], value = "3.10" }, { if = ["stable", "full", "pre"], value = "3.12" }, ] overrides.matrix.deps.features = [ - { if = ["full"] , value = "test-full" }, + { if = ["full"], value = "test-full" }, ] [[envs.hatch-test.matrix]] diff --git a/pyproject.toml b/pyproject.toml index 8d221396bf..d7e790f097 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,7 +52,7 @@ dependencies = [ "pandas >=1.5", "scipy>=1.8", "seaborn>=0.13", - "h5py>=3.6", + "h5py>=3.7", "tqdm", "scikit-learn>=1.1", "statsmodels>=0.13", From 88d0564f46dbafa7e7dd52595d6f21d9a5ac7753 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 14 Nov 2024 14:18:12 +0100 Subject: [PATCH 088/118] Fix CI (#3364) --- ci/scripts/min-deps.py | 2 +- ci/scripts/towncrier_automation.py | 4 +--- pyproject.toml | 4 ++-- tests/test_utils.py | 13 +++++++++---- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/ci/scripts/min-deps.py b/ci/scripts/min-deps.py index b996302c01..18af6ce151 100755 --- a/ci/scripts/min-deps.py +++ b/ci/scripts/min-deps.py @@ -35,7 +35,7 @@ def min_dep(req: Requirement) -> Requirement: ------- >>> min_dep(Requirement("numpy>=1.0")) - "numpy==1.0" + """ req_name = req.name if req.extras: diff --git a/ci/scripts/towncrier_automation.py b/ci/scripts/towncrier_automation.py index fd492f494a..c532883036 100755 --- a/ci/scripts/towncrier_automation.py +++ b/ci/scripts/towncrier_automation.py @@ -66,9 +66,7 @@ def main(argv: Sequence[str] | None = None) -> None: text=True, check=True, ).stdout.strip() - pr_description = ( - "" if base_branch == "main" else "@meeseeksmachine backport to main" - ) + pr_description = "" if base_branch == "main" else "@meeseeksdev backport to main" branch_name = f"release_notes_{args.version}" # Create a new branch + commit diff --git a/pyproject.toml b/pyproject.toml index d7e790f097..cfb7ffd28a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -166,7 +166,7 @@ addopts = [ "-ptesting.scanpy._pytest", "--pyargs", ] -testpaths = ["./tests", "scanpy"] +testpaths = ["./tests", "./ci", "scanpy"] norecursedirs = ["tests/_images"] xfail_strict = true nunit_attach_on = "fail" @@ -211,7 +211,7 @@ exclude_also = [ "if __name__ == .__main__.:", "if TYPE_CHECKING:", # https://github.com/numba/numba/issues/4268 - "@numba.njit.*", + '@(numba\.|nb\.)njit.*', ] [tool.ruff] diff --git a/tests/test_utils.py b/tests/test_utils.py index 3bec055995..f8a38a5f9d 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -6,9 +6,10 @@ import numpy as np import pytest from anndata.tests.helpers import asarray +from packaging.version import Version from scipy.sparse import csr_matrix, issparse -from scanpy._compat import DaskArray +from scanpy._compat import DaskArray, pkg_version from scanpy._utils import ( axis_mul_or_truediv, axis_sum, @@ -225,11 +226,15 @@ def test_is_constant(array_type): ], ) @pytest.mark.parametrize("block_type", [np.array, csr_matrix]) -def test_is_constant_dask(axis, expected, block_type): +def test_is_constant_dask(request: pytest.FixtureRequest, axis, expected, block_type): import dask.array as da - if (axis is None) and block_type is csr_matrix: - pytest.skip("Dask has weak support for scipy sparse matrices") + if block_type is csr_matrix and ( + axis is None or pkg_version("dask") < Version("2023.2.0") + ): + reason = "Dask has weak support for scipy sparse matrices" + # This test is flaky for old dask versions, but when `axis=None` it reliably fails + request.applymarker(pytest.mark.xfail(reason=reason, strict=axis is None)) x_data = [ [0, 0, 1, 1], From 5d7efdbcd9f910eabf81f4313081294c7a6f4d92 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 08:57:59 +0100 Subject: [PATCH 089/118] [pre-commit.ci] pre-commit autoupdate (#3373) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 22194ec871..c8088c28f3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.7.3 + rev: v0.7.4 hooks: - id: ruff types_or: [python, pyi, jupyter] From ba7dea87591e4f0eaeddd43eaa47cc44549aa07f Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Tue, 19 Nov 2024 09:30:06 +0100 Subject: [PATCH 090/118] Deprecate RandomState (using names only) (#3372) --- src/scanpy/_compat.py | 4 ++++ src/scanpy/_utils/__init__.py | 10 ++++++---- src/scanpy/datasets/_datasets.py | 4 ++-- src/scanpy/external/pp/_dca.py | 4 ++-- src/scanpy/external/pp/_magic.py | 4 ++-- src/scanpy/external/tl/_phate.py | 4 ++-- src/scanpy/neighbors/__init__.py | 12 ++++++------ src/scanpy/plotting/_tools/paga.py | 3 ++- src/scanpy/preprocessing/_pca/__init__.py | 5 +++-- src/scanpy/preprocessing/_pca/_compat.py | 4 ++-- src/scanpy/preprocessing/_recipes.py | 4 ++-- src/scanpy/preprocessing/_scrublet/__init__.py | 8 ++++---- src/scanpy/preprocessing/_scrublet/core.py | 10 +++++----- src/scanpy/preprocessing/_scrublet/pipeline.py | 6 +++--- src/scanpy/preprocessing/_scrublet/sparse_utils.py | 8 ++++---- src/scanpy/preprocessing/_simple.py | 9 ++++----- src/scanpy/preprocessing/_utils.py | 6 +++--- src/scanpy/tools/_diffmap.py | 4 ++-- src/scanpy/tools/_draw_graph.py | 4 ++-- src/scanpy/tools/_leiden.py | 4 +++- src/scanpy/tools/_louvain.py | 4 +++- src/scanpy/tools/_score_genes.py | 4 ++-- src/scanpy/tools/_tsne.py | 4 ++-- src/scanpy/tools/_umap.py | 4 ++-- 24 files changed, 72 insertions(+), 61 deletions(-) diff --git a/src/scanpy/_compat.py b/src/scanpy/_compat.py index c5fa4dbe84..dca6c84c4e 100644 --- a/src/scanpy/_compat.py +++ b/src/scanpy/_compat.py @@ -9,15 +9,19 @@ from pathlib import Path from typing import TYPE_CHECKING, Literal, ParamSpec, TypeVar, cast, overload +import numpy as np from packaging.version import Version if TYPE_CHECKING: from collections.abc import Callable from importlib.metadata import PackageMetadata + P = ParamSpec("P") R = TypeVar("R") +_LegacyRandom = int | np.random.RandomState | None + if TYPE_CHECKING: # type checkers are confused and can only see …core.Array diff --git a/src/scanpy/_utils/__init__.py b/src/scanpy/_utils/__init__.py index 150afe8311..67e2ae03c8 100644 --- a/src/scanpy/_utils/__init__.py +++ b/src/scanpy/_utils/__init__.py @@ -12,6 +12,7 @@ import re import sys import warnings +from collections.abc import Sequence from contextlib import contextmanager, suppress from enum import Enum from functools import partial, reduce, singledispatch, wraps @@ -56,12 +57,13 @@ from anndata import AnnData from numpy.typing import ArrayLike, DTypeLike, NDArray + from .._compat import _LegacyRandom from ..neighbors import NeighborsParams, RPForestDict -# e.g. https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html -# maybe in the future random.Generator -AnyRandom = int | np.random.RandomState | None +SeedLike = int | np.integer | Sequence[int] | np.random.SeedSequence +RNGLike = np.random.Generator | np.random.BitGenerator + LegacyUnionType = type(Union[int, str]) # noqa: UP007 @@ -493,7 +495,7 @@ def moving_average(a: np.ndarray, n: int): return ret[n - 1 :] / n -def get_random_state(seed: AnyRandom) -> np.random.RandomState: +def _get_legacy_random(seed: _LegacyRandom) -> np.random.RandomState: if isinstance(seed, np.random.RandomState): return seed return np.random.RandomState(seed) diff --git a/src/scanpy/datasets/_datasets.py b/src/scanpy/datasets/_datasets.py index 41b23160d6..df510b3209 100644 --- a/src/scanpy/datasets/_datasets.py +++ b/src/scanpy/datasets/_datasets.py @@ -18,7 +18,7 @@ if TYPE_CHECKING: from typing import Literal - from .._utils import AnyRandom + from .._compat import _LegacyRandom VisiumSampleID = Literal[ "V1_Breast_Cancer_Block_A_Section_1", @@ -63,7 +63,7 @@ def blobs( n_centers: int = 5, cluster_std: float = 1.0, n_observations: int = 640, - random_state: AnyRandom = 0, + random_state: _LegacyRandom = 0, ) -> AnnData: """\ Gaussian Blobs. diff --git a/src/scanpy/external/pp/_dca.py b/src/scanpy/external/pp/_dca.py index 14842c8071..c47fff90f2 100644 --- a/src/scanpy/external/pp/_dca.py +++ b/src/scanpy/external/pp/_dca.py @@ -11,7 +11,7 @@ from anndata import AnnData - from ..._utils import AnyRandom + from ..._compat import _LegacyRandom _AEType = Literal["zinb-conddisp", "zinb", "nb-conddisp", "nb"] @@ -62,7 +62,7 @@ def dca( early_stop: int = 15, batch_size: int = 32, optimizer: str = "RMSprop", - random_state: AnyRandom = 0, + random_state: _LegacyRandom = 0, threads: int | None = None, learning_rate: float | None = None, verbose: bool = False, diff --git a/src/scanpy/external/pp/_magic.py b/src/scanpy/external/pp/_magic.py index fd4b19667d..132d2a6448 100644 --- a/src/scanpy/external/pp/_magic.py +++ b/src/scanpy/external/pp/_magic.py @@ -19,7 +19,7 @@ from anndata import AnnData - from ..._utils import AnyRandom + from ..._compat import _LegacyRandom MIN_VERSION = "2.0" @@ -36,7 +36,7 @@ def magic( n_pca: int | None = 100, solver: Literal["exact", "approximate"] = "exact", knn_dist: str = "euclidean", - random_state: AnyRandom = None, + random_state: _LegacyRandom = None, n_jobs: int | None = None, verbose: bool = False, copy: bool | None = None, diff --git a/src/scanpy/external/tl/_phate.py b/src/scanpy/external/tl/_phate.py index 78b50327a9..ff50a1e6f7 100644 --- a/src/scanpy/external/tl/_phate.py +++ b/src/scanpy/external/tl/_phate.py @@ -16,7 +16,7 @@ from anndata import AnnData - from ..._utils import AnyRandom + from ..._compat import _LegacyRandom @old_positionals( @@ -49,7 +49,7 @@ def phate( mds_dist: str = "euclidean", mds: Literal["classic", "metric", "nonmetric"] = "metric", n_jobs: int | None = None, - random_state: AnyRandom = None, + random_state: _LegacyRandom = None, verbose: bool | int | None = None, copy: bool = False, **kwargs, diff --git a/src/scanpy/neighbors/__init__.py b/src/scanpy/neighbors/__init__.py index 379f34227b..ec5957b325 100644 --- a/src/scanpy/neighbors/__init__.py +++ b/src/scanpy/neighbors/__init__.py @@ -33,7 +33,7 @@ from igraph import Graph from scipy.sparse import csr_matrix - from .._utils import AnyRandom + from .._compat import _LegacyRandom from ._types import KnnTransformerLike, _Metric, _MetricFn @@ -54,13 +54,13 @@ class KwdsForTransformer(TypedDict): n_neighbors: int metric: _Metric | _MetricFn metric_params: Mapping[str, Any] - random_state: AnyRandom + random_state: _LegacyRandom class NeighborsParams(TypedDict): n_neighbors: int method: _Method - random_state: AnyRandom + random_state: _LegacyRandom metric: _Metric | _MetricFn metric_kwds: NotRequired[Mapping[str, Any]] use_rep: NotRequired[str] @@ -79,7 +79,7 @@ def neighbors( transformer: KnnTransformerLike | _KnownTransformer | None = None, metric: _Metric | _MetricFn = "euclidean", metric_kwds: Mapping[str, Any] = MappingProxyType({}), - random_state: AnyRandom = 0, + random_state: _LegacyRandom = 0, key_added: str | None = None, copy: bool = False, ) -> AnnData | None: @@ -521,7 +521,7 @@ def compute_neighbors( transformer: KnnTransformerLike | _KnownTransformer | None = None, metric: _Metric | _MetricFn = "euclidean", metric_kwds: Mapping[str, Any] = MappingProxyType({}), - random_state: AnyRandom = 0, + random_state: _LegacyRandom = 0, ) -> None: """\ Compute distances and connectivities of neighbors. @@ -757,7 +757,7 @@ def compute_eigen( n_comps: int = 15, sym: bool | None = None, sort: Literal["decrease", "increase"] = "decrease", - random_state: AnyRandom = 0, + random_state: _LegacyRandom = 0, ): """\ Compute eigen decomposition of transition matrix. diff --git a/src/scanpy/plotting/_tools/paga.py b/src/scanpy/plotting/_tools/paga.py index 7e62d46eac..ff14a19989 100644 --- a/src/scanpy/plotting/_tools/paga.py +++ b/src/scanpy/plotting/_tools/paga.py @@ -33,6 +33,7 @@ from matplotlib.colors import Colormap from scipy.sparse import spmatrix + from ..._compat import _LegacyRandom from ...tools._draw_graph import _Layout as _LayoutWithoutEqTree from .._utils import _FontSize, _FontWeight, _LegendLoc @@ -210,7 +211,7 @@ def _compute_pos( adjacency_solid: spmatrix | np.ndarray, *, layout: _Layout | None = None, - random_state: _sc_utils.AnyRandom = 0, + random_state: _LegacyRandom = 0, init_pos: np.ndarray | None = None, adj_tree=None, root: int = 0, diff --git a/src/scanpy/preprocessing/_pca/__init__.py b/src/scanpy/preprocessing/_pca/__init__.py index dba47d821c..3fd288ad93 100644 --- a/src/scanpy/preprocessing/_pca/__init__.py +++ b/src/scanpy/preprocessing/_pca/__init__.py @@ -30,7 +30,8 @@ from scipy import sparse from scipy.sparse import spmatrix - from ..._utils import AnyRandom, Empty + from ..._compat import _LegacyRandom + from ..._utils import Empty CSMatrix = sparse.csr_matrix | sparse.csc_matrix @@ -70,7 +71,7 @@ def pca( layer: str | None = None, zero_center: bool | None = True, svd_solver: SvdSolver | None = None, - random_state: AnyRandom = 0, + random_state: _LegacyRandom = 0, return_info: bool = False, mask_var: NDArray[np.bool_] | str | None | Empty = _empty, use_highly_variable: bool | None = None, diff --git a/src/scanpy/preprocessing/_pca/_compat.py b/src/scanpy/preprocessing/_pca/_compat.py index 23cb60a2e9..28eef2ba1a 100644 --- a/src/scanpy/preprocessing/_pca/_compat.py +++ b/src/scanpy/preprocessing/_pca/_compat.py @@ -18,7 +18,7 @@ from scipy import sparse from sklearn.decomposition import PCA - from .._utils import AnyRandom + from ..._compat import _LegacyRandom CSMatrix = sparse.csr_matrix | sparse.csc_matrix @@ -29,7 +29,7 @@ def _pca_compat_sparse( *, solver: Literal["arpack", "lobpcg"], mu: NDArray[np.floating] | None = None, - random_state: AnyRandom = None, + random_state: _LegacyRandom = None, ) -> tuple[NDArray[np.floating], PCA]: """Sparse PCA for scikit-learn <1.4""" random_state = check_random_state(random_state) diff --git a/src/scanpy/preprocessing/_recipes.py b/src/scanpy/preprocessing/_recipes.py index 4579739939..4b97405df9 100644 --- a/src/scanpy/preprocessing/_recipes.py +++ b/src/scanpy/preprocessing/_recipes.py @@ -16,7 +16,7 @@ if TYPE_CHECKING: from anndata import AnnData - from .._utils import AnyRandom + from .._compat import _LegacyRandom @old_positionals( @@ -36,7 +36,7 @@ def recipe_weinreb17( cv_threshold: int = 2, n_pcs: int = 50, svd_solver="randomized", - random_state: AnyRandom = 0, + random_state: _LegacyRandom = 0, copy: bool = False, ) -> AnnData | None: """\ diff --git a/src/scanpy/preprocessing/_scrublet/__init__.py b/src/scanpy/preprocessing/_scrublet/__init__.py index d57eb81750..68b7f59526 100644 --- a/src/scanpy/preprocessing/_scrublet/__init__.py +++ b/src/scanpy/preprocessing/_scrublet/__init__.py @@ -15,7 +15,7 @@ from .core import Scrublet if TYPE_CHECKING: - from ..._utils import AnyRandom + from ..._compat import _LegacyRandom from ...neighbors import _Metric, _MetricFn @@ -58,7 +58,7 @@ def scrublet( threshold: float | None = None, verbose: bool = True, copy: bool = False, - random_state: AnyRandom = 0, + random_state: _LegacyRandom = 0, ) -> AnnData | None: """\ Predict doublets using Scrublet :cite:p:`Wolock2019`. @@ -309,7 +309,7 @@ def _scrublet_call_doublets( knn_dist_metric: _Metric | _MetricFn = "euclidean", get_doublet_neighbor_parents: bool = False, threshold: float | None = None, - random_state: AnyRandom = 0, + random_state: _LegacyRandom = 0, verbose: bool = True, ) -> AnnData: """\ @@ -503,7 +503,7 @@ def scrublet_simulate_doublets( layer: str | None = None, sim_doublet_ratio: float = 2.0, synthetic_doublet_umi_subsampling: float = 1.0, - random_seed: AnyRandom = 0, + random_seed: _LegacyRandom = 0, ) -> AnnData: """\ Simulate doublets by adding the counts of random observed transcriptome pairs. diff --git a/src/scanpy/preprocessing/_scrublet/core.py b/src/scanpy/preprocessing/_scrublet/core.py index 4c992b2b64..1236f42a7a 100644 --- a/src/scanpy/preprocessing/_scrublet/core.py +++ b/src/scanpy/preprocessing/_scrublet/core.py @@ -9,7 +9,7 @@ from scipy import sparse from ... import logging as logg -from ..._utils import get_random_state +from ..._utils import _get_legacy_random from ...neighbors import ( Neighbors, _get_indices_distances_from_sparse_matrix, @@ -21,7 +21,7 @@ from numpy.random import RandomState from numpy.typing import NDArray - from ..._utils import AnyRandom + from ..._compat import _LegacyRandom from ...neighbors import _Metric, _MetricFn __all__ = ["Scrublet"] @@ -73,7 +73,7 @@ class Scrublet: n_neighbors: InitVar[int | None] = None expected_doublet_rate: float = 0.1 stdev_doublet_rate: float = 0.02 - random_state: InitVar[AnyRandom] = 0 + random_state: InitVar[_LegacyRandom] = 0 # private fields @@ -174,7 +174,7 @@ def __post_init__( counts_obs: sparse.csr_matrix | sparse.csc_matrix | NDArray[np.integer], total_counts_obs: NDArray[np.integer] | None, n_neighbors: int | None, - random_state: AnyRandom, + random_state: _LegacyRandom, ) -> None: self._counts_obs = sparse.csc_matrix(counts_obs) self._total_counts_obs = ( @@ -187,7 +187,7 @@ def __post_init__( if n_neighbors is None else n_neighbors ) - self._random_state = get_random_state(random_state) + self._random_state = _get_legacy_random(random_state) def simulate_doublets( self, diff --git a/src/scanpy/preprocessing/_scrublet/pipeline.py b/src/scanpy/preprocessing/_scrublet/pipeline.py index 5f6c62838c..586587e2cf 100644 --- a/src/scanpy/preprocessing/_scrublet/pipeline.py +++ b/src/scanpy/preprocessing/_scrublet/pipeline.py @@ -12,7 +12,7 @@ if TYPE_CHECKING: from typing import Literal - from ..._utils import AnyRandom + from ..._compat import _LegacyRandom from .core import Scrublet @@ -49,7 +49,7 @@ def truncated_svd( self: Scrublet, n_prin_comps: int = 30, *, - random_state: AnyRandom = 0, + random_state: _LegacyRandom = 0, algorithm: Literal["arpack", "randomized"] = "arpack", ) -> None: if self._counts_sim_norm is None: @@ -68,7 +68,7 @@ def pca( self: Scrublet, n_prin_comps: int = 50, *, - random_state: AnyRandom = 0, + random_state: _LegacyRandom = 0, svd_solver: Literal["auto", "full", "arpack", "randomized"] = "arpack", ) -> None: if self._counts_sim_norm is None: diff --git a/src/scanpy/preprocessing/_scrublet/sparse_utils.py b/src/scanpy/preprocessing/_scrublet/sparse_utils.py index cc0b1bc815..795559583c 100644 --- a/src/scanpy/preprocessing/_scrublet/sparse_utils.py +++ b/src/scanpy/preprocessing/_scrublet/sparse_utils.py @@ -7,12 +7,12 @@ from scanpy.preprocessing._utils import _get_mean_var -from ..._utils import get_random_state +from ..._utils import _get_legacy_random if TYPE_CHECKING: from numpy.typing import NDArray - from ..._utils import AnyRandom + from .._compat import _LegacyRandom def sparse_multiply( @@ -47,10 +47,10 @@ def subsample_counts( *, rate: float, original_totals, - random_seed: AnyRandom = 0, + random_seed: _LegacyRandom = 0, ) -> tuple[sparse.csr_matrix | sparse.csc_matrix, NDArray[np.int64]]: if rate < 1: - random_seed = get_random_state(random_seed) + random_seed = _get_legacy_random(random_seed) E.data = random_seed.binomial(np.round(E.data).astype(int), rate) current_totals = np.asarray(E.sum(1)).squeeze() unsampled_orig_totals = original_totals - current_totals diff --git a/src/scanpy/preprocessing/_simple.py b/src/scanpy/preprocessing/_simple.py index 22f907f308..7a95cf9fe6 100644 --- a/src/scanpy/preprocessing/_simple.py +++ b/src/scanpy/preprocessing/_simple.py @@ -51,8 +51,7 @@ import pandas as pd from numpy.typing import NDArray - from .._compat import DaskArray - from .._utils import AnyRandom + from .._compat import DaskArray, _LegacyRandom def get_rows_to_keep_1(indptr, data): lens = np.zeros(len(indptr) - 1, dtype=type(data[0])) @@ -902,7 +901,7 @@ def subsample( fraction: float | None = None, *, n_obs: int | None = None, - random_state: AnyRandom = 0, + random_state: _LegacyRandom = 0, copy: bool = False, ) -> AnnData | tuple[np.ndarray | spmatrix, NDArray[np.int64]] | None: """\ @@ -965,7 +964,7 @@ def downsample_counts( counts_per_cell: int | Collection[int] | None = None, total_counts: int | None = None, *, - random_state: AnyRandom = 0, + random_state: _LegacyRandom = 0, replace: bool = False, copy: bool = False, ) -> AnnData | None: @@ -1101,7 +1100,7 @@ def _downsample_array( col: np.ndarray, target: int, *, - random_state: AnyRandom = 0, + random_state: _LegacyRandom = 0, replace: bool = True, inplace: bool = False, ): diff --git a/src/scanpy/preprocessing/_utils.py b/src/scanpy/preprocessing/_utils.py index 9c02f7e636..b200e89ce8 100644 --- a/src/scanpy/preprocessing/_utils.py +++ b/src/scanpy/preprocessing/_utils.py @@ -16,8 +16,8 @@ from numpy.typing import DTypeLike, NDArray - from .._compat import DaskArray - from .._utils import AnyRandom, _SupportedArray + from .._compat import DaskArray, _LegacyRandom + from .._utils import _SupportedArray @singledispatch @@ -150,7 +150,7 @@ def sample_comb( dims: tuple[int, ...], nsamp: int, *, - random_state: AnyRandom = None, + random_state: _LegacyRandom = None, method: Literal[ "auto", "tracking_selection", "reservoir_sampling", "pool" ] = "auto", diff --git a/src/scanpy/tools/_diffmap.py b/src/scanpy/tools/_diffmap.py index dee643c39b..d2bdcc647b 100644 --- a/src/scanpy/tools/_diffmap.py +++ b/src/scanpy/tools/_diffmap.py @@ -8,7 +8,7 @@ if TYPE_CHECKING: from anndata import AnnData - from .._utils import AnyRandom + from .._compat import _LegacyRandom @old_positionals("neighbors_key", "random_state", "copy") @@ -17,7 +17,7 @@ def diffmap( n_comps: int = 15, *, neighbors_key: str | None = None, - random_state: AnyRandom = 0, + random_state: _LegacyRandom = 0, copy: bool = False, ) -> AnnData | None: """\ diff --git a/src/scanpy/tools/_draw_graph.py b/src/scanpy/tools/_draw_graph.py index 3f0e65c061..aedd41f3d3 100644 --- a/src/scanpy/tools/_draw_graph.py +++ b/src/scanpy/tools/_draw_graph.py @@ -18,7 +18,7 @@ from anndata import AnnData from scipy.sparse import spmatrix - from .._utils import AnyRandom + from .._compat import _LegacyRandom S = TypeVar("S", bound=LiteralString) @@ -43,7 +43,7 @@ def draw_graph( *, init_pos: str | bool | None = None, root: int | None = None, - random_state: AnyRandom = 0, + random_state: _LegacyRandom = 0, n_jobs: int | None = None, adjacency: spmatrix | None = None, key_added_ext: str | None = None, diff --git a/src/scanpy/tools/_leiden.py b/src/scanpy/tools/_leiden.py index 5a8ba00484..f73ec1fd7d 100644 --- a/src/scanpy/tools/_leiden.py +++ b/src/scanpy/tools/_leiden.py @@ -17,6 +17,8 @@ from anndata import AnnData from scipy import sparse + from .._compat import _LegacyRandom + try: from leidenalg.VertexPartition import MutableVertexPartition except ImportError: @@ -32,7 +34,7 @@ def leiden( resolution: float = 1, *, restrict_to: tuple[str, Sequence[str]] | None = None, - random_state: _utils.AnyRandom = 0, + random_state: _LegacyRandom = 0, key_added: str = "leiden", adjacency: sparse.spmatrix | None = None, directed: bool | None = None, diff --git a/src/scanpy/tools/_louvain.py b/src/scanpy/tools/_louvain.py index d3e616a850..470858ff38 100644 --- a/src/scanpy/tools/_louvain.py +++ b/src/scanpy/tools/_louvain.py @@ -22,6 +22,8 @@ from anndata import AnnData from scipy.sparse import spmatrix + from .._compat import _LegacyRandom + try: from louvain.VertexPartition import MutableVertexPartition except ImportError: @@ -50,7 +52,7 @@ def louvain( adata: AnnData, resolution: float | None = None, *, - random_state: _utils.AnyRandom = 0, + random_state: _LegacyRandom = 0, restrict_to: tuple[str, Sequence[str]] | None = None, key_added: str = "louvain", adjacency: spmatrix | None = None, diff --git a/src/scanpy/tools/_score_genes.py b/src/scanpy/tools/_score_genes.py index a3909b7a28..a40d9f3288 100644 --- a/src/scanpy/tools/_score_genes.py +++ b/src/scanpy/tools/_score_genes.py @@ -22,7 +22,7 @@ from numpy.typing import DTypeLike, NDArray from scipy.sparse import csc_matrix, csr_matrix - from .._utils import AnyRandom + from .._compat import _LegacyRandom try: _StrIdx = pd.Index[str] @@ -70,7 +70,7 @@ def score_genes( gene_pool: Sequence[str] | pd.Index[str] | None = None, n_bins: int = 25, score_name: str = "score", - random_state: AnyRandom = 0, + random_state: _LegacyRandom = 0, copy: bool = False, use_raw: bool | None = None, layer: str | None = None, diff --git a/src/scanpy/tools/_tsne.py b/src/scanpy/tools/_tsne.py index ac0e6a6317..18e4a47f8e 100644 --- a/src/scanpy/tools/_tsne.py +++ b/src/scanpy/tools/_tsne.py @@ -15,7 +15,7 @@ if TYPE_CHECKING: from anndata import AnnData - from .._utils import AnyRandom + from .._compat import _LegacyRandom @old_positionals( @@ -38,7 +38,7 @@ def tsne( metric: str = "euclidean", early_exaggeration: float = 12, learning_rate: float = 1000, - random_state: AnyRandom = 0, + random_state: _LegacyRandom = 0, use_fast_tsne: bool = False, n_jobs: int | None = None, key_added: str | None = None, diff --git a/src/scanpy/tools/_umap.py b/src/scanpy/tools/_umap.py index 4f225da2a1..902171d58c 100644 --- a/src/scanpy/tools/_umap.py +++ b/src/scanpy/tools/_umap.py @@ -17,7 +17,7 @@ from anndata import AnnData - from .._utils import AnyRandom + from .._compat import _LegacyRandom _InitPos = Literal["paga", "spectral", "random"] @@ -49,7 +49,7 @@ def umap( gamma: float = 1.0, negative_sample_rate: int = 5, init_pos: _InitPos | np.ndarray | None = "spectral", - random_state: AnyRandom = 0, + random_state: _LegacyRandom = 0, a: float | None = None, b: float | None = None, method: Literal["umap", "rapids"] = "umap", From 28e2b016a7fbd238692dc7fd7c70385e5def38cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damin=20K=C3=BChn?= Date: Tue, 19 Nov 2024 10:09:04 +0100 Subject: [PATCH 091/118] Updated Harmony Integrate Docs to better match interface to Harmonypy package (#3362) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Phil Schaf --- docs/release-notes/3362.doc.md | 1 + src/scanpy/external/pp/_harmony_integrate.py | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 docs/release-notes/3362.doc.md diff --git a/docs/release-notes/3362.doc.md b/docs/release-notes/3362.doc.md new file mode 100644 index 0000000000..1dae77b3e2 --- /dev/null +++ b/docs/release-notes/3362.doc.md @@ -0,0 +1 @@ +Improve {func}`~scanpy.external.pp.harmony_integrate` docs {smaller}`D Kühl` diff --git a/src/scanpy/external/pp/_harmony_integrate.py b/src/scanpy/external/pp/_harmony_integrate.py index 27c4d2ac8f..1104690d53 100644 --- a/src/scanpy/external/pp/_harmony_integrate.py +++ b/src/scanpy/external/pp/_harmony_integrate.py @@ -4,6 +4,7 @@ from __future__ import annotations +from collections.abc import Sequence # noqa: TCH003 from typing import TYPE_CHECKING import numpy as np @@ -19,7 +20,7 @@ @doctest_needs("harmonypy") def harmony_integrate( adata: AnnData, - key: str, + key: str | Sequence[str], *, basis: str = "X_pca", adjusted_basis: str = "X_pca_harmony", @@ -42,7 +43,9 @@ def harmony_integrate( The annotated data matrix. key The name of the column in ``adata.obs`` that differentiates - among experiments/batches. + among experiments/batches. To integrate over two or more covariates, + you can pass multiple column names as a list. See ``vars_use`` + parameter of the ``harmonypy`` package for more details. basis The name of the field in ``adata.obsm`` where the PCA table is stored. Defaults to ``'X_pca'``, which is the default for From 1d71eb14120adb7f4a739406da106162232e4a41 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 22 Nov 2024 15:11:40 +0100 Subject: [PATCH 092/118] Use deprecation decorator (#3380) --- docs/release-notes/3380.bugfix.md | 1 + pyproject.toml | 1 + src/scanpy/_compat.py | 13 ++++++++++ src/scanpy/plotting/_preprocessing.py | 3 ++- .../_deprecated/highly_variable_genes.py | 24 +++++++++---------- src/scanpy/preprocessing/_simple.py | 21 ++++++++-------- 6 files changed, 40 insertions(+), 23 deletions(-) create mode 100644 docs/release-notes/3380.bugfix.md diff --git a/docs/release-notes/3380.bugfix.md b/docs/release-notes/3380.bugfix.md new file mode 100644 index 0000000000..633ce346af --- /dev/null +++ b/docs/release-notes/3380.bugfix.md @@ -0,0 +1 @@ +Raise {exc}`FutureWarning` when calling deprecated {mod}`scanpy.pp` functions {smaller}`P Angerer` diff --git a/pyproject.toml b/pyproject.toml index cfb7ffd28a..324c4c4262 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,6 +66,7 @@ dependencies = [ "packaging>=21.3", "session-info", "legacy-api-wrap>=1.4", # for positional API deprecations + "typing-extensions; python_version < '3.13'", ] dynamic = ["version"] diff --git a/src/scanpy/_compat.py b/src/scanpy/_compat.py index dca6c84c4e..b97b1a8603 100644 --- a/src/scanpy/_compat.py +++ b/src/scanpy/_compat.py @@ -48,6 +48,10 @@ class ZappyArray: "fullname", "pkg_metadata", "pkg_version", + "old_positionals", + "deprecated", + "njit", + "_numba_threading_layer", ] @@ -102,6 +106,15 @@ def old_positionals(*old_positionals: str): return lambda func: func +if sys.version_info >= (3, 13): + from warnings import deprecated as _deprecated +else: + from typing_extensions import deprecated as _deprecated + + +deprecated = partial(_deprecated, category=FutureWarning) + + @overload def njit(fn: Callable[P, R], /) -> Callable[P, R]: ... @overload diff --git a/src/scanpy/plotting/_preprocessing.py b/src/scanpy/plotting/_preprocessing.py index e6c7808be1..b51688082e 100644 --- a/src/scanpy/plotting/_preprocessing.py +++ b/src/scanpy/plotting/_preprocessing.py @@ -6,7 +6,7 @@ from matplotlib import pyplot as plt from matplotlib import rcParams -from .._compat import old_positionals +from .._compat import deprecated, old_positionals from .._settings import settings from . import _utils @@ -103,6 +103,7 @@ def highly_variable_genes( # backwards compat +@deprecated("Use sc.pl.highly_variable_genes instead") @old_positionals("log", "show", "save") def filter_genes_dispersion( result: np.recarray, diff --git a/src/scanpy/preprocessing/_deprecated/highly_variable_genes.py b/src/scanpy/preprocessing/_deprecated/highly_variable_genes.py index f2c3ce971b..27e8f1f846 100644 --- a/src/scanpy/preprocessing/_deprecated/highly_variable_genes.py +++ b/src/scanpy/preprocessing/_deprecated/highly_variable_genes.py @@ -9,7 +9,7 @@ from scipy.sparse import issparse from ... import logging as logg -from ..._compat import old_positionals +from ..._compat import deprecated, old_positionals from .._distributed import materialize_as_ndarray from .._utils import _get_mean_var @@ -19,6 +19,7 @@ from scipy.sparse import spmatrix +@deprecated("Use sc.pp.highly_variable_genes instead") @old_positionals( "flavor", "min_disp", @@ -48,18 +49,17 @@ def filter_genes_dispersion( """\ Extract highly variable genes :cite:p:`Satija2015,Zheng2017`. - .. warning:: - .. deprecated:: 1.3.6 - Use :func:`~scanpy.pp.highly_variable_genes` - instead. The new function is equivalent to the present - function, except that + .. deprecated:: 1.3.6 - * the new function always expects logarithmized data - * `subset=False` in the new function, it suffices to - merely annotate the genes, tools like `pp.pca` will - detect the annotation - * you can now call: `sc.pl.highly_variable_genes(adata)` - * `copy` is replaced by `inplace` + Use :func:`~scanpy.pp.highly_variable_genes` instead. + The new function is equivalent to the present function, except that + + * the new function always expects logarithmized data + * `subset=False` in the new function, it suffices to + merely annotate the genes, tools like `pp.pca` will + detect the annotation + * you can now call: `sc.pl.highly_variable_genes(adata)` + * `copy` is replaced by `inplace` If trying out parameters, pass the data matrix instead of AnnData. diff --git a/src/scanpy/preprocessing/_simple.py b/src/scanpy/preprocessing/_simple.py index 7a95cf9fe6..54c052f0b9 100644 --- a/src/scanpy/preprocessing/_simple.py +++ b/src/scanpy/preprocessing/_simple.py @@ -19,7 +19,7 @@ from sklearn.utils import check_array, sparsefuncs from .. import logging as logg -from .._compat import njit, old_positionals +from .._compat import deprecated, njit, old_positionals from .._settings import settings as sett from .._utils import ( _check_array_function_arguments, @@ -545,6 +545,7 @@ def sqrt( return X.sqrt() +@deprecated("Use sc.pp.normalize_total instead") @old_positionals( "counts_per_cell_after", "counts_per_cell", @@ -568,16 +569,16 @@ def normalize_per_cell( """\ Normalize total counts per cell. - .. warning:: - .. deprecated:: 1.3.7 - Use :func:`~scanpy.pp.normalize_total` instead. - The new function is equivalent to the present - function, except that + .. deprecated:: 1.3.7 - * the new function doesn't filter cells based on `min_counts`, - use :func:`~scanpy.pp.filter_cells` if filtering is needed. - * some arguments were renamed - * `copy` is replaced by `inplace` + Use :func:`~scanpy.pp.normalize_total` instead. + The new function is equivalent to the present + function, except that + + * the new function doesn't filter cells based on `min_counts`, + use :func:`~scanpy.pp.filter_cells` if filtering is needed. + * some arguments were renamed + * `copy` is replaced by `inplace` Normalize each cell by total counts over all genes, so that every cell has the same total count after normalization. From f74263cfcf336c2a2ce447e81eeb841c7533ec66 Mon Sep 17 00:00:00 2001 From: Ilan Gold Date: Fri, 6 Dec 2024 15:37:16 +0100 Subject: [PATCH 093/118] (fix): bound sklearn because of dask-ml on the release candidate (#3393) * (fix): bound sklearn because of dask-ml on the release candidate * (chore): release note * (fix): `mod` in note * (fix): release notes number --- docs/release-notes/3393.bugfix.md | 1 + pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 docs/release-notes/3393.bugfix.md diff --git a/docs/release-notes/3393.bugfix.md b/docs/release-notes/3393.bugfix.md new file mode 100644 index 0000000000..22af00f124 --- /dev/null +++ b/docs/release-notes/3393.bugfix.md @@ -0,0 +1 @@ +Upper-bound {mod}`sklearn` `<1.6.0` due to {issue}`dask/dask-ml#1002` {smaller}`Ilan Gold` diff --git a/pyproject.toml b/pyproject.toml index 324c4c4262..f1495442fe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,7 +54,7 @@ dependencies = [ "seaborn>=0.13", "h5py>=3.7", "tqdm", - "scikit-learn>=1.1", + "scikit-learn>=1.1,<1.6.0", "statsmodels>=0.13", "patsy!=1.0.0", # https://github.com/pydata/patsy/issues/215 "networkx>=2.7", From 52e4ee52398ff06312bbf309f161bf5e64fb6462 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 10 Dec 2024 09:11:15 +0100 Subject: [PATCH 094/118] [pre-commit.ci] pre-commit autoupdate (#3388) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c8088c28f3..6c91285096 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.7.4 + rev: v0.8.2 hooks: - id: ruff types_or: [python, pyi, jupyter] From ad093296ed5db49480aea8837c6aef6d101b30b4 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Tue, 10 Dec 2024 16:37:09 +0100 Subject: [PATCH 095/118] Remove calls to `.format` (#3325) --- src/scanpy/_settings.py | 4 +--- src/scanpy/external/exporting.py | 4 ++-- src/scanpy/external/tl/_phenograph.py | 4 ++-- src/scanpy/plotting/_tools/paga.py | 8 +++---- src/scanpy/preprocessing/_qc.py | 21 +++++++------------ src/scanpy/tools/_rank_genes_groups.py | 7 ++++--- .../notebooks/test_paga_paul15_subsampled.py | 2 +- 7 files changed, 22 insertions(+), 28 deletions(-) diff --git a/src/scanpy/_settings.py b/src/scanpy/_settings.py index 54b51b6420..5543689ef7 100644 --- a/src/scanpy/_settings.py +++ b/src/scanpy/_settings.py @@ -82,9 +82,7 @@ def _type_check(var: Any, varname: str, types: type | tuple[type, ...]): possible_types_str = types.__name__ else: type_names = [t.__name__ for t in types] - possible_types_str = "{} or {}".format( - ", ".join(type_names[:-1]), type_names[-1] - ) + possible_types_str = f"{', '.join(type_names[:-1])} or {type_names[-1]}" raise TypeError(f"{varname} must be of type {possible_types_str}") diff --git a/src/scanpy/external/exporting.py b/src/scanpy/external/exporting.py index c1d7fa93b4..9364b7d368 100644 --- a/src/scanpy/external/exporting.py +++ b/src/scanpy/external/exporting.py @@ -345,8 +345,8 @@ def _write_color_tracks(ctracks, fname): def _frac_to_hex(frac): - rgb = tuple(np.array(np.array(plt.cm.jet(frac)[:3]) * 255, dtype=int)) - return "#{:02x}{:02x}{:02x}".format(*rgb) + r, g, b = tuple(np.array(np.array(plt.cm.jet(frac)[:3]) * 255, dtype=int)) + return f"#{r:02x}{g:02x}{b:02x}" def _get_color_stats_genes(color_stats, E, gene_list): diff --git a/src/scanpy/external/tl/_phenograph.py b/src/scanpy/external/tl/_phenograph.py index 8cecfa7276..24e10bcb85 100644 --- a/src/scanpy/external/tl/_phenograph.py +++ b/src/scanpy/external/tl/_phenograph.py @@ -244,8 +244,8 @@ def phenograph( comm_key = ( f"pheno_{clustering_algo}" if clustering_algo in ["louvain", "leiden"] else "" ) - ig_key = "pheno_{}_ig".format("jaccard" if jaccard else "gaussian") - q_key = "pheno_{}_q".format("jaccard" if jaccard else "gaussian") + ig_key = f"pheno_{'jaccard' if jaccard else 'gaussian'}_ig" + q_key = f"pheno_{'jaccard' if jaccard else 'gaussian'}_q" communities, graph, Q = phenograph.cluster( data=data, diff --git a/src/scanpy/plotting/_tools/paga.py b/src/scanpy/plotting/_tools/paga.py index ff14a19989..e67e6e2ece 100644 --- a/src/scanpy/plotting/_tools/paga.py +++ b/src/scanpy/plotting/_tools/paga.py @@ -702,11 +702,11 @@ def _paga_graph( and isinstance(node_labels, str) and node_labels != adata.uns["paga"]["groups"] ): - raise ValueError( - "Provide a list of group labels for the PAGA groups {}, not {}.".format( - adata.uns["paga"]["groups"], node_labels - ) + msg = ( + "Provide a list of group labels for the PAGA groups " + f"{adata.uns['paga']['groups']}, not {node_labels}." ) + raise ValueError(msg) groups_key = adata.uns["paga"]["groups"] if node_labels is None: node_labels = adata.obs[groups_key].cat.categories diff --git a/src/scanpy/preprocessing/_qc.py b/src/scanpy/preprocessing/_qc.py index 27836e1717..87ad51d420 100644 --- a/src/scanpy/preprocessing/_qc.py +++ b/src/scanpy/preprocessing/_qc.py @@ -194,26 +194,21 @@ def describe_var( if issparse(X): X.eliminate_zeros() var_metrics = pd.DataFrame(index=adata.var_names) - var_metrics["n_cells_by_{expr_type}"], var_metrics["mean_{expr_type}"] = ( + var_metrics[f"n_cells_by_{expr_type}"], var_metrics[f"mean_{expr_type}"] = ( materialize_as_ndarray((axis_nnz(X, axis=0), _get_mean_var(X, axis=0)[0])) ) if log1p: - var_metrics["log1p_mean_{expr_type}"] = np.log1p( - var_metrics["mean_{expr_type}"] + var_metrics[f"log1p_mean_{expr_type}"] = np.log1p( + var_metrics[f"mean_{expr_type}"] ) - var_metrics["pct_dropout_by_{expr_type}"] = ( - 1 - var_metrics["n_cells_by_{expr_type}"] / X.shape[0] + var_metrics[f"pct_dropout_by_{expr_type}"] = ( + 1 - var_metrics[f"n_cells_by_{expr_type}"] / X.shape[0] ) * 100 - var_metrics["total_{expr_type}"] = np.ravel(axis_sum(X, axis=0)) + var_metrics[f"total_{expr_type}"] = np.ravel(axis_sum(X, axis=0)) if log1p: - var_metrics["log1p_total_{expr_type}"] = np.log1p( - var_metrics["total_{expr_type}"] + var_metrics[f"log1p_total_{expr_type}"] = np.log1p( + var_metrics[f"total_{expr_type}"] ) - # Relabel - new_colnames = [] - for col in var_metrics.columns: - new_colnames.append(col.format(**locals())) - var_metrics.columns = new_colnames if inplace: adata.var[var_metrics.columns] = var_metrics return None diff --git a/src/scanpy/tools/_rank_genes_groups.py b/src/scanpy/tools/_rank_genes_groups.py index 9a2896196a..59526ee516 100644 --- a/src/scanpy/tools/_rank_genes_groups.py +++ b/src/scanpy/tools/_rank_genes_groups.py @@ -124,10 +124,11 @@ def __init__( ) if len(invalid_groups_selected) > 0: - raise ValueError( - "Could not calculate statistics for groups {} since they only " - "contain one sample.".format(", ".join(invalid_groups_selected)) + msg = ( + f"Could not calculate statistics for groups {', '.join(invalid_groups_selected)} " + "since they only contain one sample." ) + raise ValueError(msg) adata_comp = adata if layer is not None: diff --git a/tests/notebooks/test_paga_paul15_subsampled.py b/tests/notebooks/test_paga_paul15_subsampled.py index 9ce6ea8319..5d8c17d336 100644 --- a/tests/notebooks/test_paga_paul15_subsampled.py +++ b/tests/notebooks/test_paga_paul15_subsampled.py @@ -138,6 +138,6 @@ def test_paga_paul15_subsampled(image_comparer, plt): show=False, ) # add a test for this at some point - # data.to_csv('./write/paga_path_{}.csv'.format(descr)) + # data.to_csv(f"./write/paga_path_{descr}.csv") save_and_compare_images("paga_path") From 817d972d09068242e83afdfea44cacfbbf3af555 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 12 Dec 2024 15:23:36 +0100 Subject: [PATCH 096/118] Constrain all extras for min-deps job (#3367) --- ci/scripts/min-deps.py | 107 ++++++++++++++++++++++++++++------------- hatch.toml | 2 +- 2 files changed, 75 insertions(+), 34 deletions(-) diff --git a/ci/scripts/min-deps.py b/ci/scripts/min-deps.py index 18af6ce151..0d49d151ef 100755 --- a/ci/scripts/min-deps.py +++ b/ci/scripts/min-deps.py @@ -12,6 +12,7 @@ import sys from collections import deque from contextlib import ExitStack +from functools import cached_property from pathlib import Path from typing import TYPE_CHECKING @@ -25,6 +26,8 @@ if TYPE_CHECKING: from collections.abc import Generator, Iterable, Sequence + from collections.abc import Set as AbstractSet + from typing import Any, Self def min_dep(req: Requirement) -> Requirement: @@ -77,48 +80,86 @@ def extract_min_deps( class Args(argparse.Namespace): - path: Path + """\ + Parse a pyproject.toml file and output a list of minimum dependencies. + Output is optimized for `[uv] pip install` (see `-o`/`--output` for details). + """ + + _path: Path output: Path | None - extras: list[str] + _extras: list[str] + _all_extras: bool + + @classmethod + def parse(cls, argv: Sequence[str] | None = None) -> Self: + return cls.parser().parse_args(argv, cls()) + + @classmethod + def parser(cls) -> argparse.ArgumentParser: + parser = argparse.ArgumentParser( + prog="min-deps", + description=cls.__doc__, + usage="pip install `python min-deps.py pyproject.toml`", + ) + parser.add_argument( + "_path", + metavar="pyproject.toml", + type=Path, + help="Path to pyproject.toml to parse minimum dependencies from", + ) + parser.add_argument( + "--extras", + dest="_extras", + metavar="EXTRA", + type=str, + nargs="*", + default=(), + help="extras to install", + ) + parser.add_argument( + "--all-extras", + dest="_all_extras", + action="store_true", + help="get all extras", + ) + parser.add_argument( + *("--output", "-o"), + metavar="FILE", + type=Path, + default=None, + help=( + "output file (default: stdout). " + "Without this option, output is space-separated for direct passing to `pip install`. " + "With this option, output written to a file newline-separated file usable as `requirements.txt` or `constraints.txt`." + ), + ) + return parser + + @cached_property + def pyproject(self) -> dict[str, Any]: + return tomllib.loads(self._path.read_text()) + + @cached_property + def extras(self) -> AbstractSet[str]: + if self._extras: + if self._all_extras: + sys.exit("Cannot specify both --extras and --all-extras") + return dict.fromkeys(self._extras).keys() + if not self._all_extras: + return set() + return self.pyproject["project"]["optional-dependencies"].keys() def main(argv: Sequence[str] | None = None) -> None: - parser = argparse.ArgumentParser( - prog="min-deps", - description=( - "Parse a pyproject.toml file and output a list of minimum dependencies. " - "Output is optimized for `[uv] pip install` (see `-o`/`--output` for details)." - ), - usage="pip install `python min-deps.py pyproject.toml`", - ) - parser.add_argument( - "path", type=Path, help="pyproject.toml to parse minimum dependencies from" - ) - parser.add_argument( - "--extras", type=str, nargs="*", default=(), help="extras to install" - ) - parser.add_argument( - *("--output", "-o"), - type=Path, - default=None, - help=( - "output file (default: stdout). " - "Without this option, output is space-separated for direct passing to `pip install`. " - "With this option, output written to a file newline-separated file usable as `requirements.txt` or `constraints.txt`." - ), - ) - - args = parser.parse_args(argv, Args()) - - pyproject = tomllib.loads(args.path.read_text()) + args = Args.parse(argv) - project_name = pyproject["project"]["name"] + project_name = args.pyproject["project"]["name"] deps = [ - *map(Requirement, pyproject["project"]["dependencies"]), + *map(Requirement, args.pyproject["project"]["dependencies"]), *(Requirement(f"{project_name}[{extra}]") for extra in args.extras), ] - min_deps = extract_min_deps(deps, pyproject=pyproject) + min_deps = extract_min_deps(deps, pyproject=args.pyproject) sep = "\n" if args.output else " " with ExitStack() as stack: diff --git a/hatch.toml b/hatch.toml index ad5db60976..3163d5d82d 100644 --- a/hatch.toml +++ b/hatch.toml @@ -22,7 +22,7 @@ overrides.matrix.deps.env-vars = [ { if = ["min"], key = "UV_CONSTRAINT", value = "ci/scanpy-min-deps.txt" }, ] overrides.matrix.deps.pre-install-commands = [ - { if = ["min"], value = "uv run ci/scripts/min-deps.py pyproject.toml -o ci/scanpy-min-deps.txt" }, + { if = ["min"], value = "uv run ci/scripts/min-deps.py pyproject.toml --all-extras -o ci/scanpy-min-deps.txt" }, ] overrides.matrix.deps.python = [ { if = ["min"], value = "3.10" }, From 98e241c39478d6248620142b7e8e8b00dc2b7fe8 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Mon, 16 Dec 2024 12:39:52 +0100 Subject: [PATCH 097/118] =?UTF-8?q?Add=20a=20=E2=80=9Cimproved=20documenta?= =?UTF-8?q?tion=E2=80=9D=20category=20to=20enhancement=20template=20(#3403?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/ISSUE_TEMPLATE/bug-report.yml | 2 +- .github/ISSUE_TEMPLATE/config.yml | 2 +- .github/ISSUE_TEMPLATE/enhancement-request.yml | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 9b7cac7353..71637016a7 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -1,8 +1,8 @@ name: Bug report description: Scanpy doesn’t do what it should? Please help us fix it! #title: ... +type: Bug labels: -- Bug 🐛 - Triage 🩺 #assignees: [] body: diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 1505f196f5..a0c4b12e00 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,4 +1,4 @@ -blank_issues_enabled: true +blank_issues_enabled: false contact_links: - name: Scanpy Community Forum url: https://discourse.scverse.org/ diff --git a/.github/ISSUE_TEMPLATE/enhancement-request.yml b/.github/ISSUE_TEMPLATE/enhancement-request.yml index 209ee6805a..9e511c592c 100644 --- a/.github/ISSUE_TEMPLATE/enhancement-request.yml +++ b/.github/ISSUE_TEMPLATE/enhancement-request.yml @@ -1,8 +1,8 @@ name: Enhancement request description: Anything you’d like to see in scanpy? #title: ... +type: Enhancement labels: -- Enhancement ✨ - Triage 🩺 #assignees: [] body: @@ -14,6 +14,7 @@ body: - 'Additional function parameters / changed functionality / changed defaults?' - 'New analysis tool: A simple analysis tool you have been using and are missing in `sc.tools`?' - 'New plotting function: A kind of plot you would like to seein `sc.pl`?' + - 'Improved documentation or error message?' - 'Other?' validations: required: true From b02b1ceebccc298ed6e14add042ab2041fa53a49 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Tue, 17 Dec 2024 11:07:59 +0100 Subject: [PATCH 098/118] Modify error message if certifi is not installed (#3402) --- src/scanpy/_compat.py | 13 +++++++++++++ src/scanpy/readwrite.py | 23 +++++++++++------------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/scanpy/_compat.py b/src/scanpy/_compat.py index b97b1a8603..d2c69a9e37 100644 --- a/src/scanpy/_compat.py +++ b/src/scanpy/_compat.py @@ -106,6 +106,19 @@ def old_positionals(*old_positionals: str): return lambda func: func +if sys.version_info >= (3, 11): + + @wraps(BaseException.add_note) + def add_note(exc: BaseException, note: str) -> None: + exc.add_note(note) +else: + + def add_note(exc: BaseException, note: str) -> None: + if not hasattr(exc, "__notes__"): + exc.__notes__ = [] + exc.__notes__.append(note) + + if sys.version_info >= (3, 13): from warnings import deprecated as _deprecated else: diff --git a/src/scanpy/readwrite.py b/src/scanpy/readwrite.py index 3c958a1e50..07bd817ca5 100644 --- a/src/scanpy/readwrite.py +++ b/src/scanpy/readwrite.py @@ -36,7 +36,7 @@ from matplotlib.image import imread from . import logging as logg -from ._compat import old_positionals +from ._compat import add_note, old_positionals from ._settings import settings from ._utils import _empty @@ -993,15 +993,11 @@ def _get_filename_from_key(key, ext=None) -> Path: def _download(url: str, path: Path): - try: - import ipywidgets # noqa: F401 - from tqdm.auto import tqdm - except ImportError: - from tqdm import tqdm - from urllib.error import URLError from urllib.request import Request, urlopen + from tqdm.auto import tqdm + blocksize = 1024 * 8 blocknum = 0 @@ -1011,14 +1007,17 @@ def _download(url: str, path: Path): try: open_url = urlopen(req) except URLError: - logg.warning( - "Failed to open the url with default certificates, trying with certifi." - ) + msg = "Failed to open the url with default certificates." + try: + from certifi import where + except ImportError as e: + add_note(e, f"{msg} Please install `certifi` and try again.") + raise + else: + logg.warning(f"{msg} Trying to use certifi.") from ssl import create_default_context - from certifi import where - open_url = urlopen(req, context=create_default_context(cafile=where())) with open_url as resp: From 120db93061103789c545512107d47495da24cebf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6k=C3=A7en=20Eraslan?= Date: Thu, 19 Dec 2024 08:48:10 -0800 Subject: [PATCH 099/118] Add replace option to subsample and rename function to sample (#943) --- docs/api/deprecated.md | 1 + docs/api/preprocessing.md | 2 +- docs/release-notes/943.feature.md | 1 + pyproject.toml | 4 +- src/scanpy/_compat.py | 41 ++++- src/scanpy/preprocessing/__init__.py | 4 +- .../preprocessing/_deprecated/sampling.py | 60 +++++++ src/scanpy/preprocessing/_simple.py | 165 +++++++++++++----- tests/test_package_structure.py | 1 + tests/test_preprocessing.py | 144 ++++++++++++--- tests/test_utils.py | 42 ++++- 11 files changed, 391 insertions(+), 74 deletions(-) create mode 100644 docs/release-notes/943.feature.md create mode 100644 src/scanpy/preprocessing/_deprecated/sampling.py diff --git a/docs/api/deprecated.md b/docs/api/deprecated.md index 4511f4b3a7..d09c1af405 100644 --- a/docs/api/deprecated.md +++ b/docs/api/deprecated.md @@ -11,4 +11,5 @@ pp.filter_genes_dispersion pp.normalize_per_cell + pp.subsample ``` diff --git a/docs/api/preprocessing.md b/docs/api/preprocessing.md index 4b17567a6b..36e732a6dc 100644 --- a/docs/api/preprocessing.md +++ b/docs/api/preprocessing.md @@ -31,7 +31,7 @@ For visual quality control, see {func}`~scanpy.pl.highest_expr_genes` and pp.normalize_total pp.regress_out pp.scale - pp.subsample + pp.sample pp.downsample_counts ``` diff --git a/docs/release-notes/943.feature.md b/docs/release-notes/943.feature.md new file mode 100644 index 0000000000..4f5474d762 --- /dev/null +++ b/docs/release-notes/943.feature.md @@ -0,0 +1 @@ +{func}`~scanpy.pp.sample` supports both upsampling and downsampling of observations and variables. {func}`~scanpy.pp.subsample` is now deprecated. {smaller}`G Eraslan` & {smaller}`P Angerer` diff --git a/pyproject.toml b/pyproject.toml index f1495442fe..b4b8abd1b1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,7 @@ classifiers = [ ] dependencies = [ "anndata>=0.8", - "numpy>=1.23", + "numpy>=1.24", "matplotlib>=3.6", "pandas >=1.5", "scipy>=1.8", @@ -60,7 +60,7 @@ dependencies = [ "networkx>=2.7", "natsort", "joblib", - "numba>=0.56", + "numba>=0.57", "umap-learn>=0.5,!=0.5.0", "pynndescent>=0.5", "packaging>=21.3", diff --git a/src/scanpy/_compat.py b/src/scanpy/_compat.py index d2c69a9e37..9ea7780b0d 100644 --- a/src/scanpy/_compat.py +++ b/src/scanpy/_compat.py @@ -4,7 +4,7 @@ import sys import warnings from dataclasses import dataclass, field -from functools import cache, partial, wraps +from functools import WRAPPER_ASSIGNMENTS, cache, partial, wraps from importlib.util import find_spec from pathlib import Path from typing import TYPE_CHECKING, Literal, ParamSpec, TypeVar, cast, overload @@ -224,3 +224,42 @@ def _numba_threading_layer() -> Layer: f" ({available=}, {numba.config.THREADING_LAYER_PRIORITY=})" ) raise ValueError(msg) + + +def _legacy_numpy_gen( + random_state: _LegacyRandom | None = None, +) -> np.random.Generator: + """Return a random generator that behaves like the legacy one.""" + + if random_state is not None: + if isinstance(random_state, np.random.RandomState): + np.random.set_state(random_state.get_state(legacy=False)) + return _FakeRandomGen(random_state) + np.random.seed(random_state) + return _FakeRandomGen(np.random.RandomState(np.random.get_bit_generator())) + + +class _FakeRandomGen(np.random.Generator): + _state: np.random.RandomState + + def __init__(self, random_state: np.random.RandomState) -> None: + self._state = random_state + + @classmethod + def _delegate(cls) -> None: + for name, meth in np.random.Generator.__dict__.items(): + if name.startswith("_") or not callable(meth): + continue + + def mk_wrapper(name: str): + # Old pytest versions try to run the doctests + @wraps(meth, assigned=set(WRAPPER_ASSIGNMENTS) - {"__doc__"}) + def wrapper(self: _FakeRandomGen, *args, **kwargs): + return getattr(self._state, name)(*args, **kwargs) + + return wrapper + + setattr(cls, name, mk_wrapper(name)) + + +_FakeRandomGen._delegate() diff --git a/src/scanpy/preprocessing/__init__.py b/src/scanpy/preprocessing/__init__.py index 8c396d8640..4307cbb6c9 100644 --- a/src/scanpy/preprocessing/__init__.py +++ b/src/scanpy/preprocessing/__init__.py @@ -3,6 +3,7 @@ from ..neighbors import neighbors from ._combat import combat from ._deprecated.highly_variable_genes import filter_genes_dispersion +from ._deprecated.sampling import subsample from ._highly_variable_genes import highly_variable_genes from ._normalization import normalize_total from ._pca import pca @@ -17,8 +18,8 @@ log1p, normalize_per_cell, regress_out, + sample, sqrt, - subsample, ) __all__ = [ @@ -40,6 +41,7 @@ "log1p", "normalize_per_cell", "regress_out", + "sample", "scale", "sqrt", "subsample", diff --git a/src/scanpy/preprocessing/_deprecated/sampling.py b/src/scanpy/preprocessing/_deprecated/sampling.py new file mode 100644 index 0000000000..02619a2364 --- /dev/null +++ b/src/scanpy/preprocessing/_deprecated/sampling.py @@ -0,0 +1,60 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +from ..._compat import _legacy_numpy_gen, old_positionals +from .._simple import sample + +if TYPE_CHECKING: + import numpy as np + from anndata import AnnData + from numpy.typing import NDArray + from scipy.sparse import csc_matrix, csr_matrix + + from ..._compat import _LegacyRandom + + CSMatrix = csr_matrix | csc_matrix + + +@old_positionals("n_obs", "random_state", "copy") +def subsample( + data: AnnData | np.ndarray | CSMatrix, + fraction: float | None = None, + *, + n_obs: int | None = None, + random_state: _LegacyRandom = 0, + copy: bool = False, +) -> AnnData | tuple[np.ndarray | CSMatrix, NDArray[np.int64]] | None: + """\ + Subsample to a fraction of the number of observations. + + .. deprecated:: 1.11.0 + + Use :func:`~scanpy.pp.sample` instead. + + Parameters + ---------- + data + The (annotated) data matrix of shape `n_obs` × `n_vars`. + Rows correspond to cells and columns to genes. + fraction + Subsample to this `fraction` of the number of observations. + n_obs + Subsample to this number of observations. + random_state + Random seed to change subsampling. + copy + If an :class:`~anndata.AnnData` is passed, + determines whether a copy is returned. + + Returns + ------- + Returns `X[obs_indices], obs_indices` if data is array-like, otherwise + subsamples the passed :class:`~anndata.AnnData` (`copy == False`) or + returns a subsampled copy of it (`copy == True`). + """ + + rng = _legacy_numpy_gen(random_state) + return sample( + data=data, fraction=fraction, n=n_obs, rng=rng, copy=copy, replace=False, axis=0 + ) diff --git a/src/scanpy/preprocessing/_simple.py b/src/scanpy/preprocessing/_simple.py index 54c052f0b9..14f2b9d382 100644 --- a/src/scanpy/preprocessing/_simple.py +++ b/src/scanpy/preprocessing/_simple.py @@ -8,21 +8,22 @@ import warnings from functools import singledispatch from itertools import repeat -from typing import TYPE_CHECKING, TypeVar +from typing import TYPE_CHECKING, TypeVar, overload import numba import numpy as np import scipy as sp from anndata import AnnData from pandas.api.types import CategoricalDtype -from scipy.sparse import csr_matrix, issparse, isspmatrix_csr, spmatrix +from scipy.sparse import csc_matrix, csr_matrix, issparse, isspmatrix_csr, spmatrix from sklearn.utils import check_array, sparsefuncs from .. import logging as logg -from .._compat import deprecated, njit, old_positionals +from .._compat import DaskArray, deprecated, njit, old_positionals from .._settings import settings as sett from .._utils import ( _check_array_function_arguments, + _resolve_axis, axis_sum, is_backed_type, raise_not_implemented_error_if_backed_type, @@ -34,15 +35,11 @@ from ._distributed import materialize_as_ndarray from ._utils import _to_dense -# install dask if available try: import dask.array as da except ImportError: da = None -# backwards compat -from ._deprecated.highly_variable_genes import filter_genes_dispersion # noqa: F401 - if TYPE_CHECKING: from collections.abc import Collection, Iterable, Sequence from numbers import Number @@ -51,7 +48,13 @@ import pandas as pd from numpy.typing import NDArray - from .._compat import DaskArray, _LegacyRandom + from .._compat import _LegacyRandom + from .._utils import RNGLike, SeedLike + + +CSMatrix = csr_matrix | csc_matrix + +A = TypeVar("A", bound=np.ndarray | CSMatrix | DaskArray) def get_rows_to_keep_1(indptr, data): lens = np.zeros(len(indptr) - 1, dtype=type(data[0])) @@ -896,17 +899,51 @@ def _regress_out_chunk( return np.vstack(responses_chunk_list) -@old_positionals("n_obs", "random_state", "copy") -def subsample( - data: AnnData | np.ndarray | spmatrix, +@overload +def sample( + data: AnnData, fraction: float | None = None, *, - n_obs: int | None = None, - random_state: _LegacyRandom = 0, + n: int | None = None, + rng: RNGLike | SeedLike | None = 0, + copy: Literal[False] = False, + replace: bool = False, + axis: Literal["obs", 0, "var", 1] = "obs", +) -> None: ... +@overload +def sample( + data: AnnData, + fraction: float | None = None, + *, + n: int | None = None, + rng: RNGLike | SeedLike | None = None, + copy: Literal[True], + replace: bool = False, + axis: Literal["obs", 0, "var", 1] = "obs", +) -> AnnData: ... +@overload +def sample( + data: A, + fraction: float | None = None, + *, + n: int | None = None, + rng: RNGLike | SeedLike | None = None, copy: bool = False, -) -> AnnData | tuple[np.ndarray | spmatrix, NDArray[np.int64]] | None: + replace: bool = False, + axis: Literal["obs", 0, "var", 1] = "obs", +) -> tuple[A, NDArray[np.int64]]: ... +def sample( + data: AnnData | np.ndarray | CSMatrix | DaskArray, + fraction: float | None = None, + *, + n: int | None = None, + rng: RNGLike | SeedLike | None = None, + copy: bool = False, + replace: bool = False, + axis: Literal["obs", 0, "var", 1] = "obs", +) -> AnnData | None | tuple[np.ndarray | CSMatrix | DaskArray, NDArray[np.int64]]: """\ - Subsample to a fraction of the number of observations. + Sample observations or variables with or without replacement. Parameters ---------- @@ -914,49 +951,81 @@ def subsample( The (annotated) data matrix of shape `n_obs` × `n_vars`. Rows correspond to cells and columns to genes. fraction - Subsample to this `fraction` of the number of observations. - n_obs - Subsample to this number of observations. + Sample to this `fraction` of the number of observations or variables. + This can be larger than 1.0, if `replace=True`. + See `axis` and `replace`. + n + Sample to this number of observations or variables. See `axis`. random_state Random seed to change subsampling. copy If an :class:`~anndata.AnnData` is passed, determines whether a copy is returned. + replace + If True, samples are drawn with replacement. + axis + Sample `obs`\\ ervations (axis 0) or `var`\\ iables (axis 1). Returns ------- - Returns `X[obs_indices], obs_indices` if data is array-like, otherwise - subsamples the passed :class:`~anndata.AnnData` (`copy == False`) or - returns a subsampled copy of it (`copy == True`). + If `isinstance(data, AnnData)` and `copy=False`, + this function returns `None`. Otherwise: + + `data[indices, :]` | `data[:, indices]` (depending on `axis`) + If `data` is array-like or `copy=True`, returns the subset. + `indices` : numpy.ndarray + If `data` is array-like, also returns the indices into the original. """ - np.random.seed(random_state) - old_n_obs = data.n_obs if isinstance(data, AnnData) else data.shape[0] - if n_obs is not None: - new_n_obs = n_obs - elif fraction is not None: - if fraction > 1 or fraction < 0: - raise ValueError(f"`fraction` needs to be within [0, 1], not {fraction}") - new_n_obs = int(fraction * old_n_obs) - logg.debug(f"... subsampled to {new_n_obs} data points") - else: - raise ValueError("Either pass `n_obs` or `fraction`.") - obs_indices = np.random.choice(old_n_obs, size=new_n_obs, replace=False) - if isinstance(data, AnnData): - if data.isbacked: - if copy: - return data[obs_indices].to_memory() - else: - raise NotImplementedError( - "Inplace subsampling is not implemented for backed objects." - ) + # parameter validation + if not copy and isinstance(data, AnnData) and data.isbacked: + msg = "Inplace sampling (`copy=False`) is not implemented for backed objects." + raise NotImplementedError(msg) + axis, axis_name = _resolve_axis(axis) + old_n = data.shape[axis] + match (fraction, n): + case (None, None): + msg = "Either `fraction` or `n` must be set." + raise TypeError(msg) + case (None, _): + pass + case (_, None): + if fraction < 0: + msg = f"`{fraction=}` needs to be nonnegative." + raise ValueError(msg) + if not replace and fraction > 1: + msg = f"If `replace=False`, `{fraction=}` needs to be within [0, 1]." + raise ValueError(msg) + n = int(fraction * old_n) + logg.debug(f"... sampled to {n} {axis_name}") + case _: + msg = "Providing both `fraction` and `n` is not allowed." + raise TypeError(msg) + del fraction + + # actually do subsampling + rng = np.random.default_rng(rng) + indices = rng.choice(old_n, size=n, replace=replace) + + # overload 1: inplace AnnData subset + if not copy and isinstance(data, AnnData): + if axis_name == "obs": + data._inplace_subset_obs(indices) else: - if copy: - return data[obs_indices].copy() - else: - data._inplace_subset_obs(obs_indices) - else: - X = data - return X[obs_indices], obs_indices + data._inplace_subset_var(indices) + return None + + subset = data[indices] if axis_name == "obs" else data[:, indices] + + # overload 2: copy AnnData subset + if copy and isinstance(data, AnnData): + assert isinstance(subset, AnnData) + return subset.to_memory() if data.isbacked else subset.copy() + + # overload 3: return array and indices + assert isinstance(subset, np.ndarray | CSMatrix | DaskArray), type(subset) + if copy: + subset = subset.copy() + return subset, indices @renamed_arg("target_counts", "counts_per_cell") diff --git a/tests/test_package_structure.py b/tests/test_package_structure.py index 834c06d8b4..3541c561a5 100644 --- a/tests/test_package_structure.py +++ b/tests/test_package_structure.py @@ -138,6 +138,7 @@ class ExpectedSig(TypedDict): copy_sigs["sc.pp.filter_cells"] = None # unclear `inplace` situation copy_sigs["sc.pp.filter_genes"] = None # unclear `inplace` situation copy_sigs["sc.pp.subsample"] = None # returns indices along matrix +copy_sigs["sc.pp.sample"] = None # returns indices along matrix # partial exceptions: “data” instead of “adata” copy_sigs["sc.pp.log1p"]["first_name"] = "data" copy_sigs["sc.pp.normalize_per_cell"]["first_name"] = "data" diff --git a/tests/test_preprocessing.py b/tests/test_preprocessing.py index b8f5115b01..36283e7ed0 100644 --- a/tests/test_preprocessing.py +++ b/tests/test_preprocessing.py @@ -1,7 +1,10 @@ from __future__ import annotations +import warnings +from importlib.util import find_spec from itertools import product from pathlib import Path +from typing import TYPE_CHECKING import numpy as np import pandas as pd @@ -22,6 +25,13 @@ from testing.scanpy._helpers.data import pbmc3k, pbmc68k_reduced from testing.scanpy._pytest.params import ARRAY_TYPES +if TYPE_CHECKING: + from collections.abc import Callable + from typing import Any, Literal + + CSMatrix = sp.csc_matrix | sp.csr_matrix + + HERE = Path(__file__).parent DATA_PATH = HERE / "_data" @@ -134,34 +144,128 @@ def test_normalize_per_cell(): assert adata.X.sum(axis=1).tolist() == adata_sparse.X.sum(axis=1).A1.tolist() -def test_subsample(): - adata = AnnData(np.ones((200, 10))) - sc.pp.subsample(adata, n_obs=40) - assert adata.n_obs == 40 - sc.pp.subsample(adata, fraction=0.1) - assert adata.n_obs == 4 +@pytest.mark.parametrize("array_type", ARRAY_TYPES) +@pytest.mark.parametrize("which", ["copy", "inplace", "array"]) +@pytest.mark.parametrize( + ("axis", "fraction", "n", "replace", "expected"), + [ + pytest.param(0, None, 40, False, 40, id="obs-40-no_replace"), + pytest.param(0, 0.1, None, False, 20, id="obs-0.1-no_replace"), + pytest.param(0, None, 201, True, 201, id="obs-201-replace"), + pytest.param(0, None, 1, True, 1, id="obs-1-replace"), + pytest.param(1, None, 10, False, 10, id="var-10-no_replace"), + pytest.param(1, None, 11, True, 11, id="var-11-replace"), + pytest.param(1, 2.0, None, True, 20, id="var-2.0-replace"), + ], +) +def test_sample( + *, + array_type: Callable[[np.ndarray], np.ndarray | CSMatrix], + which: Literal["copy", "inplace", "array"], + axis: Literal[0, 1], + fraction: float | None, + n: int | None, + replace: bool, + expected: int, +): + adata = AnnData(array_type(np.ones((200, 10)))) + + # ignoring this warning declaratively is a pain so do it here + if find_spec("dask"): + import dask.array as da + + warnings.filterwarnings("ignore", category=da.PerformanceWarning) + # can’t guarantee that duplicates are drawn when `replace=True`, + # so we just ignore the warning instead using `with pytest.warns(...)` + warnings.filterwarnings( + "ignore" if replace else "error", r".*names are not unique", UserWarning + ) + rv = sc.pp.sample( + adata.X if which == "array" else adata, + fraction, + n=n, + replace=replace, + axis=axis, + # `copy` only effects AnnData inputs + copy=dict(copy=True, inplace=False, array=False)[which], + ) + match which: + case "copy": + subset = rv + assert rv is not adata + assert adata.shape == (200, 10) + case "inplace": + subset = adata + assert rv is None + case "array": + subset, indices = rv + assert len(indices) == expected + assert adata.shape == (200, 10) + case _: + pytest.fail(f"Unknown `{which=}`") -def test_subsample_copy(): + assert subset.shape == ((expected, 10) if axis == 0 else (200, expected)) + + +@pytest.mark.parametrize( + ("args", "exc", "pattern"), + [ + pytest.param( + dict(), TypeError, r"Either `fraction` or `n` must be set", id="empty" + ), + pytest.param( + dict(n=10, fraction=0.2), + TypeError, + r"Providing both `fraction` and `n` is not allowed", + id="both", + ), + pytest.param( + dict(fraction=2), + ValueError, + r"If `replace=False`, `fraction=2` needs to be", + id="frac>1", + ), + pytest.param( + dict(fraction=-0.3), + ValueError, + r"`fraction=-0\.3` needs to be nonnegative", + id="frac<0", + ), + ], +) +def test_sample_error(args: dict[str, Any], exc: type[Exception], pattern: str): adata = AnnData(np.ones((200, 10))) - assert sc.pp.subsample(adata, n_obs=40, copy=True).shape == (40, 10) - assert sc.pp.subsample(adata, fraction=0.1, copy=True).shape == (20, 10) + with pytest.raises(exc, match=pattern): + sc.pp.sample(adata, **args) -def test_subsample_copy_backed(tmp_path): - A = np.random.rand(200, 10).astype(np.float32) - adata_m = AnnData(A.copy()) - adata_d = AnnData(A.copy()) - filename = tmp_path / "test.h5ad" - adata_d.filename = filename - # This should not throw an error - assert sc.pp.subsample(adata_d, n_obs=40, copy=True).shape == (40, 10) +def test_sample_backwards_compat(): + expected = np.array( + [26, 86, 2, 55, 75, 93, 16, 73, 54, 95, 53, 92, 78, 13, 7, 30, 22, 24, 33, 8] + ) + legacy_result, indices = sc.pp.subsample(np.arange(100), n_obs=20) + assert np.array_equal(indices, legacy_result), "arange choices should match indices" + assert np.array_equal(legacy_result, expected) + + +def test_sample_copy_backed(tmp_path): + adata_m = AnnData(np.random.rand(200, 10).astype(np.float32)) + adata_d = adata_m.copy() + adata_d.filename = tmp_path / "test.h5ad" + + assert sc.pp.sample(adata_d, n=40, copy=True).shape == (40, 10) np.testing.assert_array_equal( - sc.pp.subsample(adata_m, n_obs=40, copy=True).X, - sc.pp.subsample(adata_d, n_obs=40, copy=True).X, + sc.pp.sample(adata_m, n=40, copy=True, rng=0).X, + sc.pp.sample(adata_d, n=40, copy=True, rng=0).X, ) + + +def test_sample_copy_backed_error(tmp_path): + adata_d = AnnData(np.random.rand(200, 10).astype(np.float32)) + adata_d.filename = tmp_path / "test.h5ad" with pytest.raises(NotImplementedError): - sc.pp.subsample(adata_d, n_obs=40, copy=False) + sc.pp.sample(adata_d, n=40, copy=False) @pytest.mark.parametrize("array_type", ARRAY_TYPES) diff --git a/tests/test_utils.py b/tests/test_utils.py index f8a38a5f9d..81369a6938 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -2,6 +2,7 @@ from operator import mul, truediv from types import ModuleType +from typing import TYPE_CHECKING import numpy as np import pytest @@ -9,7 +10,7 @@ from packaging.version import Version from scipy.sparse import csr_matrix, issparse -from scanpy._compat import DaskArray, pkg_version +from scanpy._compat import DaskArray, _legacy_numpy_gen, pkg_version from scanpy._utils import ( axis_mul_or_truediv, axis_sum, @@ -26,6 +27,9 @@ ARRAY_TYPES_SPARSE_DASK_UNSUPPORTED, ) +if TYPE_CHECKING: + from typing import Any + def test_descend_classes_and_funcs(): # create module hierarchy @@ -247,3 +251,39 @@ def test_is_constant_dask(request: pytest.FixtureRequest, axis, expected, block_ x = da.from_array(np.array(x_data), chunks=2).map_blocks(block_type) result = is_constant(x, axis=axis).compute() np.testing.assert_array_equal(expected, result) + + +@pytest.mark.parametrize("seed", [0, 1, 1256712675]) +@pytest.mark.parametrize("pass_seed", [True, False], ids=["pass_seed", "set_seed"]) +@pytest.mark.parametrize("func", ["choice"]) +def test_legacy_numpy_gen(*, seed: int, pass_seed: bool, func: str): + np.random.seed(seed) + state_before = np.random.get_state(legacy=False) + + arrs: dict[bool, np.ndarray] = {} + states_after: dict[bool, dict[str, Any]] = {} + for direct in [True, False]: + if not pass_seed: + np.random.seed(seed) + arrs[direct] = _mk_random(func, direct=direct, seed=seed if pass_seed else None) + states_after[direct] = np.random.get_state(legacy=False) + + np.testing.assert_array_equal(arrs[True], arrs[False]) + np.testing.assert_equal( + *states_after.values(), err_msg="both should affect global state the same" + ) + # they should affect the global state + with pytest.raises(AssertionError): + np.testing.assert_equal(states_after[True], state_before) + + +def _mk_random(func: str, *, direct: bool, seed: int | None) -> np.ndarray: + if direct and seed is not None: + np.random.seed(seed) + gen = np.random if direct else _legacy_numpy_gen(seed) + match func: + case "choice": + arr = np.arange(1000) + return gen.choice(arr, size=(100, 100)) + case _: + pytest.fail(f"Unknown {func=}") From a99d365bdc5a73075932fd2e45ac8f89b06d5cb9 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 19 Dec 2024 17:49:55 +0100 Subject: [PATCH 100/118] Switch to session-info2 (#3384) --- docs/conf.py | 1 + docs/release-notes/3384.feature.md | 1 + pyproject.toml | 2 +- src/scanpy/logging.py | 92 ++++++++---------------------- tests/test_logging.py | 4 +- 5 files changed, 31 insertions(+), 69 deletions(-) create mode 100644 docs/release-notes/3384.feature.md diff --git a/docs/conf.py b/docs/conf.py index 2c79aa8d82..155869b360 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -142,6 +142,7 @@ rapids_singlecell=("https://rapids-singlecell.readthedocs.io/en/latest/", None), scipy=("https://docs.scipy.org/doc/scipy/", None), seaborn=("https://seaborn.pydata.org/", None), + session_info2=("https://session-info2.readthedocs.io/en/stable/", None), sklearn=("https://scikit-learn.org/stable/", None), ) diff --git a/docs/release-notes/3384.feature.md b/docs/release-notes/3384.feature.md new file mode 100644 index 0000000000..755af9a8a3 --- /dev/null +++ b/docs/release-notes/3384.feature.md @@ -0,0 +1 @@ +Switch {func}`~scanpy.logging.print_header` and {func}`~scanpy.logging.print_versions` to {mod}`session_info2` {smaller}`P Angerer` diff --git a/pyproject.toml b/pyproject.toml index b4b8abd1b1..8e23afb14b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,7 +64,7 @@ dependencies = [ "umap-learn>=0.5,!=0.5.0", "pynndescent>=0.5", "packaging>=21.3", - "session-info", + "session-info2", "legacy-api-wrap>=1.4", # for positional API deprecations "typing-extensions; python_version < '3.13'", ] diff --git a/src/scanpy/logging.py b/src/scanpy/logging.py index 168c3b5405..3aa0ca494c 100644 --- a/src/scanpy/logging.py +++ b/src/scanpy/logging.py @@ -4,17 +4,20 @@ import logging import sys -import warnings from datetime import datetime, timedelta, timezone from functools import partial, update_wrapper from logging import CRITICAL, DEBUG, ERROR, INFO, WARNING -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, overload import anndata.logging +from ._compat import deprecated + if TYPE_CHECKING: from typing import IO + from session_info2 import SessionInfo + from ._settings import ScanpyConfig @@ -127,33 +130,11 @@ def format(self, record: logging.LogRecord): get_memory_usage = anndata.logging.get_memory_usage -_DEPENDENCIES_NUMERICS = [ - "anndata", # anndata actually shouldn't, but as long as it's in development - "umap", - "numpy", - "scipy", - "pandas", - ("sklearn", "scikit-learn"), - "statsmodels", - "igraph", - "louvain", - "leidenalg", - "pynndescent", -] - - -def _versions_dependencies(dependencies): - # this is not the same as the requirements! - for mod in dependencies: - mod_name, dist_name = mod if isinstance(mod, tuple) else (mod, mod) - try: - imp = __import__(mod_name) - yield dist_name, imp.__version__ - except (ImportError, AttributeError): - pass - - -def print_header(*, file=None): +@overload +def print_header(*, file: None = None) -> SessionInfo: ... +@overload +def print_header(*, file: IO[str]) -> None: ... +def print_header(*, file: IO[str] | None = None): """\ Versions that might influence the numerical results. Matplotlib and Seaborn are excluded from this. @@ -163,50 +144,27 @@ def print_header(*, file=None): file Optional path for dependency output. """ + from session_info2 import session_info - modules = ["scanpy"] + _DEPENDENCIES_NUMERICS - print( - " ".join(f"{mod}=={ver}" for mod, ver in _versions_dependencies(modules)), - file=file or sys.stdout, - ) + sinfo = session_info(os=True, cpu=True, gpu=True, dependencies=True) + + if file is not None: + print(sinfo, file=file) + return + + return sinfo -def print_versions(*, file: IO[str] | None = None): +@deprecated("Use `print_header` instead") +def print_versions() -> SessionInfo: """\ - Print versions of imported packages, OS, and jupyter environment. + Alias for `print_header`. - For more options (including rich output) use `session_info.show` directly. + .. deprecated:: 1.11.0 - Parameters - ---------- - file - Optional path for output. + Use :func:`print_header` instead. """ - import session_info - - if file is not None: - from contextlib import redirect_stdout - - warnings.warn( - "Passing argument 'file' to print_versions is deprecated, and will be " - "removed in a future version.", - FutureWarning, - ) - with redirect_stdout(file): - print_versions() - else: - session_info.show( - dependencies=True, - html=False, - excludes=[ - "builtins", - "stdlib_list", - "importlib_metadata", - # Special module present if test coverage being calculated - # https://gitlab.com/joelostblom/session_info/-/issues/10 - "$coverage", - ], - ) + return print_header() def print_version_and_date(*, file=None): @@ -235,7 +193,7 @@ def _copy_docs_and_signature(fn): def error( msg: str, *, - time: datetime = None, + time: datetime | None = None, deep: str | None = None, extra: dict | None = None, ) -> datetime: diff --git a/tests/test_logging.py b/tests/test_logging.py index 3f8a3ee97d..81b4acbf38 100644 --- a/tests/test_logging.py +++ b/tests/test_logging.py @@ -142,6 +142,8 @@ def test_call_outputs(func): """ output_io = StringIO() with redirect_stdout(output_io): - func() + out = func() + if out is not None: + print(out) output = output_io.getvalue() assert output != "" From 6e70c3df39b65f7a1b9c39eb41b32a7cc1163921 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 19 Dec 2024 19:30:49 +0100 Subject: [PATCH 101/118] Scipy 1.15 compat, some test refactors (#3409) --- src/scanpy/tools/_rank_genes_groups.py | 2 +- tests/test_backed.py | 4 +- tests/test_filter_rank_genes_groups.py | 211 +++++++++--------------- tests/test_preprocessing_distributed.py | 3 +- 4 files changed, 79 insertions(+), 141 deletions(-) diff --git a/src/scanpy/tools/_rank_genes_groups.py b/src/scanpy/tools/_rank_genes_groups.py index 59526ee516..aa4428dad1 100644 --- a/src/scanpy/tools/_rank_genes_groups.py +++ b/src/scanpy/tools/_rank_genes_groups.py @@ -854,7 +854,7 @@ def filter_rank_genes_groups( if not use_logfolds or not use_fraction: sub_X = adata.raw[:, var_names].X if use_raw else adata[:, var_names].X - in_group = adata.obs[groupby] == cluster + in_group = (adata.obs[groupby] == cluster).to_numpy() X_in = sub_X[in_group] X_out = sub_X[~in_group] diff --git a/tests/test_backed.py b/tests/test_backed.py index 787edf9c21..bfa1d79592 100644 --- a/tests/test_backed.py +++ b/tests/test_backed.py @@ -91,8 +91,8 @@ def test_log1p_backed_errors(backed_adata): def test_scatter_backed(backed_adata): sc.pp.pca(backed_adata, chunked=True) - sc.pl.scatter(backed_adata, color="0", basis="pca") + sc.pl.scatter(backed_adata, color="0", basis="pca", show=False) def test_dotplot_backed(backed_adata): - sc.pl.dotplot(backed_adata, ["0", "1", "2", "3"], groupby="cat") + sc.pl.dotplot(backed_adata, ["0", "1", "2", "3"], groupby="cat", show=False) diff --git a/tests/test_filter_rank_genes_groups.py b/tests/test_filter_rank_genes_groups.py index 26851bb102..a64ac983f3 100644 --- a/tests/test_filter_rank_genes_groups.py +++ b/tests/test_filter_rank_genes_groups.py @@ -1,159 +1,96 @@ from __future__ import annotations import numpy as np +import pytest from scanpy.tools import filter_rank_genes_groups, rank_genes_groups from testing.scanpy._helpers.data import pbmc68k_reduced -names_no_reference = np.array( +NAMES_NO_REF = [ + ["CD3D", "ITM2A", "CD3D", "CCL5", "CD7", "nan", "CD79A", "nan", "NKG7", "LYZ"], + ["CD3E", "CD3D", "nan", "NKG7", "CD3D", "AIF1", "CD79B", "nan", "GNLY", "CST3"], + ["IL32", "RPL39", "nan", "CST7", "nan", "nan", "nan", "SNHG7", "CD7", "nan"], + ["nan", "SRSF7", "IL32", "GZMA", "nan", "LST1", "IGJ", "nan", "CTSW", "nan"], + ["nan", "nan", "CD2", "CTSW", "CD8B", "TYROBP", "ISG20", "SNHG8", "GZMB", "nan"], +] + +NAMES_REF = [ + ["CD3D", "ITM2A", "CD3D", "nan", "CD3D", "nan", "CD79A", "nan", "CD7"], + ["nan", "nan", "nan", "CD3D", "nan", "AIF1", "nan", "nan", "NKG7"], + ["nan", "nan", "nan", "NKG7", "nan", "FCGR3A", "ISG20", "SNHG7", "CTSW"], + ["nan", "CD3D", "nan", "CCL5", "CD7", "nan", "CD79B", "nan", "GNLY"], + ["CD3E", "IL32", "nan", "IL32", "CD27", "FCER1G", "nan", "nan", "nan"], +] + +NAMES_NO_REF_COMPARE_ABS = [ [ - ["CD3D", "ITM2A", "CD3D", "CCL5", "CD7", "nan", "CD79A", "nan", "NKG7", "LYZ"], - ["CD3E", "CD3D", "nan", "NKG7", "CD3D", "AIF1", "CD79B", "nan", "GNLY", "CST3"], - ["IL32", "RPL39", "nan", "CST7", "nan", "nan", "nan", "SNHG7", "CD7", "nan"], - ["nan", "SRSF7", "IL32", "GZMA", "nan", "LST1", "IGJ", "nan", "CTSW", "nan"], - [ - "nan", - "nan", - "CD2", - "CTSW", - "CD8B", - "TYROBP", - "ISG20", - "SNHG8", - "GZMB", - "nan", - ], - ] -) - -names_reference = np.array( + *("CD3D", "ITM2A", "HLA-DRB1", "CCL5", "HLA-DPA1"), + *("nan", "CD79A", "nan", "NKG7", "LYZ"), + ], [ - ["CD3D", "ITM2A", "CD3D", "nan", "CD3D", "nan", "CD79A", "nan", "CD7"], - ["nan", "nan", "nan", "CD3D", "nan", "AIF1", "nan", "nan", "NKG7"], - ["nan", "nan", "nan", "NKG7", "nan", "FCGR3A", "ISG20", "SNHG7", "CTSW"], - ["nan", "CD3D", "nan", "CCL5", "CD7", "nan", "CD79B", "nan", "GNLY"], - ["CD3E", "IL32", "nan", "IL32", "CD27", "FCER1G", "nan", "nan", "nan"], - ] -) - -names_compare_abs = np.array( + *("HLA-DPA1", "nan", "CD3D", "NKG7", "HLA-DRB1"), + *("AIF1", "CD79B", "nan", "GNLY", "CST3"), + ], [ - [ - "CD3D", - "ITM2A", - "HLA-DRB1", - "CCL5", - "HLA-DPA1", - "nan", - "CD79A", - "nan", - "NKG7", - "LYZ", - ], - [ - "HLA-DPA1", - "nan", - "CD3D", - "NKG7", - "HLA-DRB1", - "AIF1", - "CD79B", - "nan", - "GNLY", - "CST3", - ], - [ - "nan", - "PSAP", - "CD74", - "CST7", - "CD74", - "PSAP", - "FCER1G", - "SNHG7", - "CD7", - "HLA-DRA", - ], - [ - "IL32", - "nan", - "HLA-DRB5", - "GZMA", - "HLA-DRB5", - "LST1", - "nan", - "nan", - "CTSW", - "HLA-DRB1", - ], - [ - "nan", - "FCER1G", - "HLA-DPB1", - "CTSW", - "HLA-DPB1", - "TYROBP", - "TYROBP", - "S100A10", - "GZMB", - "HLA-DPA1", - ], - ] -) - - -def test_filter_rank_genes_groups(): - adata = pbmc68k_reduced() - - # fix filter defaults - args = { - "adata": adata, - "key_added": "rank_genes_groups_filtered", - "min_in_group_fraction": 0.25, - "min_fold_change": 1, - "max_out_group_fraction": 0.5, - } - - rank_genes_groups( - adata, "bulk_labels", reference="Dendritic", method="wilcoxon", n_genes=5 - ) - filter_rank_genes_groups(**args) - - assert np.array_equal( - names_reference, - np.array(adata.uns["rank_genes_groups_filtered"]["names"].tolist()), - ) + *("nan", "PSAP", "CD74", "CST7", "CD74"), + *("PSAP", "FCER1G", "SNHG7", "CD7", "HLA-DRA"), + ], + [ + *("IL32", "nan", "HLA-DRB5", "GZMA", "HLA-DRB5"), + *("LST1", "nan", "nan", "CTSW", "HLA-DRB1"), + ], + [ + *("nan", "FCER1G", "HLA-DPB1", "CTSW", "HLA-DPB1"), + *("TYROBP", "TYROBP", "S100A10", "GZMB", "HLA-DPA1"), + ], +] - rank_genes_groups(adata, "bulk_labels", method="wilcoxon", n_genes=5) - filter_rank_genes_groups(**args) - assert np.array_equal( - names_no_reference, - np.array(adata.uns["rank_genes_groups_filtered"]["names"].tolist()), - ) +EXPECTED = { + ("Dendritic", False): np.array(NAMES_REF), + ("rest", False): np.array(NAMES_NO_REF), + ("rest", True): np.array(NAMES_NO_REF_COMPARE_ABS), +} - rank_genes_groups(adata, "bulk_labels", method="wilcoxon", pts=True, n_genes=5) - filter_rank_genes_groups(**args) - assert np.array_equal( - names_no_reference, - np.array(adata.uns["rank_genes_groups_filtered"]["names"].tolist()), - ) +@pytest.mark.parametrize( + ("reference", "pts", "abs"), + [ + pytest.param("Dendritic", False, False, id="ref-no_pts-no_abs"), + pytest.param("rest", False, False, id="rest-no_pts-no_abs"), + pytest.param("rest", True, False, id="rest-pts-no_abs"), + pytest.param("rest", True, True, id="rest-pts-abs"), + ], +) +def test_filter_rank_genes_groups(reference, pts, abs): + adata = pbmc68k_reduced() - # test compare_abs rank_genes_groups( - adata, "bulk_labels", method="wilcoxon", pts=True, rankby_abs=True, n_genes=5 - ) - - filter_rank_genes_groups( adata, - compare_abs=True, - min_in_group_fraction=-1, - max_out_group_fraction=1, - min_fold_change=3.1, + "bulk_labels", + reference=reference, + pts=pts, + method="wilcoxon", + rankby_abs=abs, + n_genes=5, ) + if abs: + filter_rank_genes_groups( + adata, + compare_abs=True, + min_in_group_fraction=-1, + max_out_group_fraction=1, + min_fold_change=3.1, + ) + else: + filter_rank_genes_groups( + adata, + min_in_group_fraction=0.25, + min_fold_change=1, + max_out_group_fraction=0.5, + ) assert np.array_equal( - names_compare_abs, + EXPECTED[reference, abs], np.array(adata.uns["rank_genes_groups_filtered"]["names"].tolist()), ) diff --git a/tests/test_preprocessing_distributed.py b/tests/test_preprocessing_distributed.py index a1b99121ef..afb120b982 100644 --- a/tests/test_preprocessing_distributed.py +++ b/tests/test_preprocessing_distributed.py @@ -40,13 +40,13 @@ def adata() -> AnnData: return a -@filter_oldformatwarning @pytest.fixture( params=[ pytest.param("direct", marks=[needs.zappy]), pytest.param("dask", marks=[needs.dask, pytest.mark.anndata_dask_support]), ] ) +@filter_oldformatwarning def adata_dist(request: pytest.FixtureRequest) -> AnnData: # regular anndata except for X, which we replace on the next line a = read_zarr(input_file) @@ -75,6 +75,7 @@ def test_log1p(adata: AnnData, adata_dist: AnnData): npt.assert_allclose(result, adata.X) +@pytest.mark.filterwarnings("ignore:Use sc.pp.normalize_total instead:FutureWarning") def test_normalize_per_cell( request: pytest.FixtureRequest, adata: AnnData, adata_dist: AnnData ): From 99b9aa055fe47e8f68b193a58367ac42f3a902e7 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 19 Dec 2024 19:59:59 +0100 Subject: [PATCH 102/118] Deprecate visium (#3407) --- docs/conf.py | 1 + docs/release-notes/1.5.0.md | 2 +- docs/release-notes/3407.misc.md | 7 + docs/tutorials/index.md | 22 +- docs/tutorials/spatial/basic-analysis.ipynb | 1 - docs/tutorials/spatial/index.md | 8 - .../spatial/integration-scanorama.ipynb | 1 - src/scanpy/datasets/_datasets.py | 6 +- src/scanpy/plotting/_tools/scatterplots.py | 7 +- src/scanpy/readwrite.py | 6 +- tests/test_datasets.py | 3 + tests/test_embedding_plots.py | 566 ------------------ tests/test_plotting.py | 5 +- tests/test_plotting_embedded/conftest.py | 66 ++ .../test_plotting_embedded/test_embeddings.py | 253 ++++++++ tests/test_plotting_embedded/test_spatial.py | 267 +++++++++ tests/test_read_10x.py | 1 + 17 files changed, 625 insertions(+), 597 deletions(-) create mode 100644 docs/release-notes/3407.misc.md delete mode 120000 docs/tutorials/spatial/basic-analysis.ipynb delete mode 100644 docs/tutorials/spatial/index.md delete mode 120000 docs/tutorials/spatial/integration-scanorama.ipynb delete mode 100644 tests/test_embedding_plots.py create mode 100644 tests/test_plotting_embedded/conftest.py create mode 100644 tests/test_plotting_embedded/test_embeddings.py create mode 100644 tests/test_plotting_embedded/test_spatial.py diff --git a/docs/conf.py b/docs/conf.py index 155869b360..e17aa9df0f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -143,6 +143,7 @@ scipy=("https://docs.scipy.org/doc/scipy/", None), seaborn=("https://seaborn.pydata.org/", None), session_info2=("https://session-info2.readthedocs.io/en/stable/", None), + squidpy=("https://squidpy.readthedocs.io/en/stable/", None), sklearn=("https://scikit-learn.org/stable/", None), ) diff --git a/docs/release-notes/1.5.0.md b/docs/release-notes/1.5.0.md index 922e758723..956ceb9493 100644 --- a/docs/release-notes/1.5.0.md +++ b/docs/release-notes/1.5.0.md @@ -5,7 +5,7 @@ The `1.5.0` release adds a lot of new functionality, much of which takes advanta #### Spatial data support -- Basic analysis {doc}`/tutorials/spatial/basic-analysis` and integration with single cell data {doc}`/tutorials/spatial/integration-scanorama` {smaller}`G Palla` +- Tutorials for basic analysis and integration with single cell data {smaller}`G Palla` - {func}`~scanpy.read_visium` read 10x Visium data {pr}`1034` {smaller}`G Palla, P Angerer, I Virshup` - {func}`~scanpy.datasets.visium_sge` load Visium data directly from 10x Genomics {pr}`1013` {smaller}`M Mirkazemi, G Palla, P Angerer` - {func}`~scanpy.pl.spatial` plot spatial data {pr}`1012` {smaller}`G Palla, P Angerer` diff --git a/docs/release-notes/3407.misc.md b/docs/release-notes/3407.misc.md new file mode 100644 index 0000000000..4670de6fd4 --- /dev/null +++ b/docs/release-notes/3407.misc.md @@ -0,0 +1,7 @@ +| Deprecate … | in favor of … | +| --- | --- | +| {func}`scanpy.read_visium` | {func}`squidpy.read.visium` | +| {func}`scanpy.datasets.visium_sge` | {func}`squidpy.datasets.visium` | +| {func}`scanpy.pl.spatial` | {func}`squidpy.pl.spatial_scatter` | + +{smaller}`P Angerer` diff --git a/docs/tutorials/index.md b/docs/tutorials/index.md index ee57056a6d..b20ee2b762 100644 --- a/docs/tutorials/index.md +++ b/docs/tutorials/index.md @@ -37,19 +37,6 @@ trajectories/index ## Spatial data -```{seealso} -For more up-to-date tutorials on working with spatial data, see: - -* [SquidPy tutorials](https://squidpy.readthedocs.io/en/stable/notebooks/tutorials/index.html) -* [SpatialData tutorials](https://spatialdata.scverse.org/en/latest/tutorials/notebooks/notebooks.html) -* [Scverse ecosystem spatial tutorials](https://scverse.org/learn/) -``` - -```{toctree} -:maxdepth: 2 - -spatial/index -``` ## Experimental @@ -64,3 +51,12 @@ experimental/index A number of older tutorials can be found at: * The [`scanpy_usage`](https://github.com/scverse/scanpy_usage) repository + +```{seealso} +Scanpy used to have tutorials for its (now deprecated) spatial data functionality.x +For up-to-date tutorials on working with spatial data, see: + +* SquidPy {doc}`squidpy:notebooks/tutorials/index` +* [SpatialData tutorials](https://spatialdata.scverse.org/en/latest/tutorials/notebooks/notebooks.html) +* [Scverse ecosystem spatial tutorials](https://scverse.org/learn/) +``` diff --git a/docs/tutorials/spatial/basic-analysis.ipynb b/docs/tutorials/spatial/basic-analysis.ipynb deleted file mode 120000 index 66d9e48121..0000000000 --- a/docs/tutorials/spatial/basic-analysis.ipynb +++ /dev/null @@ -1 +0,0 @@ -../../../notebooks/spatial/basic-analysis.ipynb \ No newline at end of file diff --git a/docs/tutorials/spatial/index.md b/docs/tutorials/spatial/index.md deleted file mode 100644 index 801b901e53..0000000000 --- a/docs/tutorials/spatial/index.md +++ /dev/null @@ -1,8 +0,0 @@ -## Spatial - -```{toctree} -:maxdepth: 1 - -basic-analysis -integration-scanorama -``` diff --git a/docs/tutorials/spatial/integration-scanorama.ipynb b/docs/tutorials/spatial/integration-scanorama.ipynb deleted file mode 120000 index 5143681577..0000000000 --- a/docs/tutorials/spatial/integration-scanorama.ipynb +++ /dev/null @@ -1 +0,0 @@ -../../../notebooks/spatial/integration-scanorama.ipynb \ No newline at end of file diff --git a/src/scanpy/datasets/_datasets.py b/src/scanpy/datasets/_datasets.py index df510b3209..8859de4d74 100644 --- a/src/scanpy/datasets/_datasets.py +++ b/src/scanpy/datasets/_datasets.py @@ -9,7 +9,7 @@ from anndata import AnnData from .. import _utils -from .._compat import old_positionals +from .._compat import deprecated, old_positionals from .._settings import settings from .._utils._doctests import doctest_internet, doctest_needs from ..readwrite import read, read_visium @@ -509,6 +509,7 @@ def _download_visium_dataset( return sample_dir +@deprecated("Use `squidpy.datasets.visium` instead.") @doctest_internet @check_datasetdir_exists def visium_sge( @@ -519,6 +520,9 @@ def visium_sge( """\ Processed Visium Spatial Gene Expression data from 10x Genomics’ database. + .. deprecated:: 1.11.0 + Use :func:`squidpy.datasets.visium` instead. + The database_ can be browsed online to find the ``sample_id`` you want. .. _database: https://support.10xgenomics.com/spatial-gene-expression/datasets diff --git a/src/scanpy/plotting/_tools/scatterplots.py b/src/scanpy/plotting/_tools/scatterplots.py index 4ce39f7211..e2564eb17f 100644 --- a/src/scanpy/plotting/_tools/scatterplots.py +++ b/src/scanpy/plotting/_tools/scatterplots.py @@ -28,6 +28,7 @@ from packaging.version import Version from ... import logging as logg +from ..._compat import deprecated from ..._settings import settings from ..._utils import ( Empty, # noqa: TCH001 @@ -919,6 +920,7 @@ def pca( return axs +@deprecated("Use `squidpy.pl.spatial_scatter` instead.") @_wraps_plot_scatter @_doc_params( adata_color_etc=doc_adata_color_etc, @@ -948,6 +950,9 @@ def spatial( """\ Scatter plot in spatial coordinates. + .. deprecated:: 1.11.0 + Use :func:`squidpy.pl.spatial_scatter` instead. + This function allows overlaying data on top of images. Use the parameter `img_key` to see the image in the background And the parameter `library_id` to select the image. @@ -994,8 +999,6 @@ def spatial( -------- :func:`scanpy.datasets.visium_sge` Example visium data. - :doc:`/tutorials/spatial/basic-analysis` - Tutorial on spatial analysis. """ # get default image params if available library_id, spatial_data = _check_spatial_data(adata.uns, library_id) diff --git a/src/scanpy/readwrite.py b/src/scanpy/readwrite.py index 07bd817ca5..3333fbc0a1 100644 --- a/src/scanpy/readwrite.py +++ b/src/scanpy/readwrite.py @@ -36,7 +36,7 @@ from matplotlib.image import imread from . import logging as logg -from ._compat import add_note, old_positionals +from ._compat import add_note, deprecated, old_positionals from ._settings import settings from ._utils import _empty @@ -366,6 +366,7 @@ def _read_v3_10x_h5(filename, *, start=None): raise Exception("File is missing one or more required datasets.") +@deprecated("Use `squidpy.read.visium` instead.") def read_visium( path: Path | str, genome: str | None = None, @@ -378,6 +379,9 @@ def read_visium( """\ Read 10x-Genomics-formatted visum dataset. + .. deprecated:: 1.11.0 + Use :func:`squidpy.read.visium` instead. + In addition to reading regular 10x output, this looks for the `spatial` folder and loads images, coordinates and scale factors. diff --git a/tests/test_datasets.py b/tests/test_datasets.py index 4bad3800d7..5e0fc1e125 100644 --- a/tests/test_datasets.py +++ b/tests/test_datasets.py @@ -111,6 +111,7 @@ def test_pbmc68k_reduced(): sc.datasets.pbmc68k_reduced() +@pytest.mark.filterwarnings("ignore:Use `squidpy.*` instead:FutureWarning") @pytest.mark.internet def test_visium_datasets(): """Tests that reading/ downloading works and is does not have global effects.""" @@ -121,6 +122,7 @@ def test_visium_datasets(): assert_adata_equal(hheart, hheart_again) +@pytest.mark.filterwarnings("ignore:Use `squidpy.*` instead:FutureWarning") @pytest.mark.internet def test_visium_datasets_dir_change(tmp_path: Path): """Test that changing the dataset dir doesn't break reading.""" @@ -132,6 +134,7 @@ def test_visium_datasets_dir_change(tmp_path: Path): assert_adata_equal(mbrain, mbrain_again) +@pytest.mark.filterwarnings("ignore:Use `squidpy.*` instead:FutureWarning") @pytest.mark.internet def test_visium_datasets_images(): """Test that image download works and is does not have global effects.""" diff --git a/tests/test_embedding_plots.py b/tests/test_embedding_plots.py deleted file mode 100644 index d48f44b2b6..0000000000 --- a/tests/test_embedding_plots.py +++ /dev/null @@ -1,566 +0,0 @@ -from __future__ import annotations - -from functools import partial -from pathlib import Path -from typing import TYPE_CHECKING - -import matplotlib as mpl -import matplotlib.pyplot as plt -import numpy as np -import pandas as pd -import pytest -import seaborn as sns -from matplotlib.colors import Normalize -from matplotlib.testing.compare import compare_images - -import scanpy as sc -from testing.scanpy._helpers.data import pbmc3k_processed - -if TYPE_CHECKING: - from scanpy.plotting._utils import _LegendLoc - - -HERE: Path = Path(__file__).parent -ROOT = HERE / "_images" - -MISSING_VALUES_ROOT = ROOT / "embedding-missing-values" - - -def check_images(pth1, pth2, *, tol): - result = compare_images(pth1, pth2, tol=tol) - assert result is None, result - - -@pytest.fixture(scope="module") -def adata(): - """A bit cute.""" - from matplotlib.image import imread - from sklearn.cluster import DBSCAN - from sklearn.datasets import make_blobs - - empty_pixel = np.array([1.0, 1.0, 1.0, 0]).reshape(1, 1, -1) - image = imread(HERE.parent / "docs/_static/img/Scanpy_Logo_RGB.png") - x, y = np.where(np.logical_and.reduce(~np.equal(image, empty_pixel), axis=2)) - - # Just using to calculate the hex coords - hexes = plt.hexbin(x, y, gridsize=(44, 100)) - counts = hexes.get_array() - pixels = hexes.get_offsets()[counts != 0] - plt.close() - - labels = DBSCAN(eps=20, min_samples=2).fit(pixels).labels_ - order = np.argsort(labels) - adata = sc.AnnData( - make_blobs( - pd.Series(labels[order]).value_counts().values, - n_features=20, - shuffle=False, - random_state=42, - )[0], - obs={"label": pd.Categorical(labels[order].astype(str))}, - obsm={"spatial": pixels[order, ::-1]}, - uns={ - "spatial": { - "scanpy_img": { - "images": {"hires": image}, - "scalefactors": { - "tissue_hires_scalef": 1, - "spot_diameter_fullres": 10, - }, - } - } - }, - ) - sc.pp.pca(adata) - - # Adding some missing values - adata.obs["label_missing"] = adata.obs["label"].copy() - adata.obs["label_missing"][::2] = np.nan - - adata.obs["1_missing"] = adata.obs_vector("1") - adata.obs.loc[ - adata.obsm["spatial"][:, 0] < adata.obsm["spatial"][:, 0].mean(), "1_missing" - ] = np.nan - - return adata - - -@pytest.fixture -def fixture_request(request): - """Returns a Request object. - - Allows you to access names of parameterized tests from within a test. - """ - return request - - -@pytest.fixture( - params=[(0, 0, 0, 1), None], - ids=["na_color.black_tup", "na_color.default"], -) -def na_color(request): - return request.param - - -@pytest.fixture(params=[True, False], ids=["na_in_legend.True", "na_in_legend.False"]) -def na_in_legend(request): - return request.param - - -@pytest.fixture( - params=[partial(sc.pl.pca, show=False), partial(sc.pl.spatial, show=False)], - ids=["pca", "spatial"], -) -def plotfunc(request): - return request.param - - -@pytest.fixture( - params=["on data", "right margin", "lower center", None], - ids=["legend.on_data", "legend.on_right", "legend.on_bottom", "legend.off"], -) -def legend_loc(request) -> _LegendLoc | None: - return request.param - - -@pytest.fixture( - params=[lambda x: list(x.cat.categories[:3]), lambda x: []], - ids=["groups.3", "groups.all"], -) -def groupsfunc(request): - return request.param - - -@pytest.fixture( - params=[ - pytest.param( - {"vmin": None, "vmax": None, "vcenter": None, "norm": None}, - id="vbounds.default", - ), - pytest.param( - {"vmin": 0, "vmax": 5, "vcenter": None, "norm": None}, id="vbounds.numbers" - ), - pytest.param( - {"vmin": "p15", "vmax": "p90", "vcenter": None, "norm": None}, - id="vbounds.percentile", - ), - pytest.param( - {"vmin": 0, "vmax": "p99", "vcenter": 0.1, "norm": None}, - id="vbounds.vcenter", - ), - pytest.param( - {"vmin": None, "vmax": None, "vcenter": None, "norm": Normalize(0, 5)}, - id="vbounds.norm", - ), - ] -) -def vbounds(request): - return request.param - - -def test_missing_values_categorical( - *, - fixture_request: pytest.FixtureRequest, - image_comparer, - adata, - plotfunc, - na_color, - na_in_legend, - legend_loc, - groupsfunc, -): - save_and_compare_images = partial(image_comparer, MISSING_VALUES_ROOT, tol=15) - - base_name = fixture_request.node.name - - # Passing through a dict so it's easier to use default values - kwargs = {} - kwargs["legend_loc"] = legend_loc - kwargs["groups"] = groupsfunc(adata.obs["label"]) - if na_color is not None: - kwargs["na_color"] = na_color - kwargs["na_in_legend"] = na_in_legend - - plotfunc(adata, color=["label", "label_missing"], **kwargs) - - save_and_compare_images(base_name) - - -def test_missing_values_continuous( - *, - fixture_request: pytest.FixtureRequest, - image_comparer, - adata, - plotfunc, - na_color, - vbounds, -): - save_and_compare_images = partial(image_comparer, MISSING_VALUES_ROOT, tol=15) - - base_name = fixture_request.node.name - - # Passing through a dict so it's easier to use default values - kwargs = {} - kwargs.update(vbounds) - if na_color is not None: - kwargs["na_color"] = na_color - - plotfunc(adata, color=["1", "1_missing"], **kwargs) - - save_and_compare_images(base_name) - - -def test_enumerated_palettes(fixture_request, adata, tmpdir, plotfunc): - tmpdir = Path(tmpdir) - base_name = fixture_request.node.name - - categories = adata.obs["label"].cat.categories - colors_rgb = dict(zip(categories, sns.color_palette(n_colors=12))) - - dict_pth = tmpdir / f"rgbdict_{base_name}.png" - list_pth = tmpdir / f"rgblist_{base_name}.png" - - # making a copy so colors aren't saved - plotfunc(adata.copy(), color="label", palette=colors_rgb) - plt.savefig(dict_pth, dpi=40) - plt.close() - plotfunc(adata.copy(), color="label", palette=[colors_rgb[c] for c in categories]) - plt.savefig(list_pth, dpi=40) - plt.close() - - check_images(dict_pth, list_pth, tol=15) - - -def test_dimension_broadcasting(adata, tmpdir, check_same_image): - tmpdir = Path(tmpdir) - - with pytest.raises( - ValueError, - match=r"Could not broadcast together arguments with shapes: \[2, 3, 1\]", - ): - sc.pl.pca( - adata, color=["label", "1_missing"], dimensions=[(0, 1), (1, 2), (2, 3)] - ) - - dims_pth = tmpdir / "broadcast_dims.png" - color_pth = tmpdir / "broadcast_colors.png" - - sc.pl.pca(adata, color=["label", "label", "label"], dimensions=(2, 3), show=False) - plt.savefig(dims_pth, dpi=40) - plt.close() - sc.pl.pca(adata, color="label", dimensions=[(2, 3), (2, 3), (2, 3)], show=False) - plt.savefig(color_pth, dpi=40) - plt.close() - - check_same_image(dims_pth, color_pth, tol=5) - - -def test_marker_broadcasting(adata, tmpdir, check_same_image): - tmpdir = Path(tmpdir) - - with pytest.raises( - ValueError, - match=r"Could not broadcast together arguments with shapes: \[2, 1, 3\]", - ): - sc.pl.pca(adata, color=["label", "1_missing"], marker=[".", "^", "x"]) - - dims_pth = tmpdir / "broadcast_markers.png" - color_pth = tmpdir / "broadcast_colors_for_markers.png" - - sc.pl.pca(adata, color=["label", "label", "label"], marker="^", show=False) - plt.savefig(dims_pth, dpi=40) - plt.close() - sc.pl.pca(adata, color="label", marker=["^", "^", "^"], show=False) - plt.savefig(color_pth, dpi=40) - plt.close() - - check_same_image(dims_pth, color_pth, tol=5) - - -def test_dimensions_same_as_components(adata, tmpdir, check_same_image): - tmpdir = Path(tmpdir) - adata = adata.copy() - adata.obs["mean"] = np.ravel(adata.X.mean(axis=1)) - - comp_pth = tmpdir / "components_plot.png" - dims_pth = tmpdir / "dimension_plot.png" - - # TODO: Deprecate components kwarg - # with pytest.warns(FutureWarning, match=r"components .* deprecated"): - sc.pl.pca( - adata, - color=["mean", "label"], - components=["1,2", "2,3"], - show=False, - ) - plt.savefig(comp_pth, dpi=40) - plt.close() - - sc.pl.pca( - adata, - color=["mean", "mean", "label", "label"], - dimensions=[(0, 1), (1, 2), (0, 1), (1, 2)], - show=False, - ) - plt.savefig(dims_pth, dpi=40) - plt.close() - - check_same_image(dims_pth, comp_pth, tol=5) - - -def test_embedding_colorbar_location(image_comparer): - save_and_compare_images = partial(image_comparer, ROOT, tol=15) - - adata = pbmc3k_processed().raw.to_adata() - - sc.pl.pca(adata, color="LDHB", colorbar_loc=None) - - save_and_compare_images("no_colorbar") - - -# Spatial specific - - -def test_visium_circles(image_comparer): # standard visium data - save_and_compare_images = partial(image_comparer, ROOT, tol=15) - - adata = sc.read_visium(HERE / "_data" / "visium_data" / "1.0.0") - adata.obs = adata.obs.astype({"array_row": "str"}) - - sc.pl.spatial( - adata, - color="array_row", - groups=["24", "33"], - crop_coord=(100, 400, 400, 100), - alpha=0.5, - size=1.3, - show=False, - ) - - save_and_compare_images("spatial_visium") - - -def test_visium_default(image_comparer): # default values - from packaging.version import parse as parse_version - - if parse_version(mpl.__version__) < parse_version("3.7.0"): - pytest.xfail("Matplotlib 3.7.0+ required for this test") - - save_and_compare_images = partial(image_comparer, ROOT, tol=5) - - adata = sc.read_visium(HERE / "_data" / "visium_data" / "1.0.0") - adata.obs = adata.obs.astype({"array_row": "str"}) - - # Points default to transparent if an image is included - sc.pl.spatial(adata, show=False) - - save_and_compare_images("spatial_visium_default") - - -def test_visium_empty_img_key(image_comparer): # visium coordinates but image empty - save_and_compare_images = partial(image_comparer, ROOT, tol=15) - - adata = sc.read_visium(HERE / "_data" / "visium_data" / "1.0.0") - adata.obs = adata.obs.astype({"array_row": "str"}) - - sc.pl.spatial(adata, img_key=None, color="array_row", show=False) - - save_and_compare_images("spatial_visium_empty_image") - - sc.pl.embedding(adata, basis="spatial", color="array_row", show=False) - save_and_compare_images("spatial_visium_embedding") - - -def test_spatial_general(image_comparer): # general coordinates - save_and_compare_images = partial(image_comparer, ROOT, tol=15) - - adata = sc.read_visium(HERE / "_data" / "visium_data" / "1.0.0") - adata.obs = adata.obs.astype({"array_row": "str"}) - spatial_metadata = adata.uns.pop( - "spatial" - ) # spatial data don't have imgs, so remove entry from uns - # Required argument for now - spot_size = list(spatial_metadata.values())[0]["scalefactors"][ - "spot_diameter_fullres" - ] - - sc.pl.spatial(adata, show=False, spot_size=spot_size) - save_and_compare_images("spatial_general_nocol") - - # category - sc.pl.spatial(adata, show=False, spot_size=spot_size, color="array_row") - save_and_compare_images("spatial_general_cat") - - # continuous - sc.pl.spatial(adata, show=False, spot_size=spot_size, color="array_col") - save_and_compare_images("spatial_general_cont") - - -def test_spatial_external_img(image_comparer): # external image - save_and_compare_images = partial(image_comparer, ROOT, tol=15) - - adata = sc.read_visium(HERE / "_data" / "visium_data" / "1.0.0") - adata.obs = adata.obs.astype({"array_row": "str"}) - - img = adata.uns["spatial"]["custom"]["images"]["hires"] - scalef = adata.uns["spatial"]["custom"]["scalefactors"]["tissue_hires_scalef"] - sc.pl.spatial( - adata, - color="array_row", - scale_factor=scalef, - img=img, - basis="spatial", - show=False, - ) - save_and_compare_images("spatial_external_img") - - -@pytest.fixture(scope="module") -def equivalent_spatial_plotters(adata): - no_spatial = adata.copy() - del no_spatial.uns["spatial"] - - img_key = "hires" - library_id = list(adata.uns["spatial"])[0] - spatial_data = adata.uns["spatial"][library_id] - img = spatial_data["images"][img_key] - scale_factor = spatial_data["scalefactors"][f"tissue_{img_key}_scalef"] - spot_size = spatial_data["scalefactors"]["spot_diameter_fullres"] - - orig_plotter = partial(sc.pl.spatial, adata, color="1", show=False) - removed_plotter = partial( - sc.pl.spatial, - no_spatial, - color="1", - img=img, - scale_factor=scale_factor, - spot_size=spot_size, - show=False, - ) - - return (orig_plotter, removed_plotter) - - -@pytest.fixture(scope="module") -def equivalent_spatial_plotters_no_img(equivalent_spatial_plotters): - orig, removed = equivalent_spatial_plotters - return (partial(orig, img_key=None), partial(removed, img=None, scale_factor=None)) - - -@pytest.fixture( - params=[ - pytest.param({"crop_coord": (50, 200, 0, 500)}, id="crop"), - pytest.param({"size": 0.5}, id="size:.5"), - pytest.param({"size": 2}, id="size:2"), - pytest.param({"spot_size": 5}, id="spotsize"), - pytest.param({"bw": True}, id="bw"), - # Shape of the image for particular fixture, should not be hardcoded like this - pytest.param({"img": np.ones((774, 1755, 4)), "scale_factor": 1.0}, id="img"), - pytest.param( - {"na_color": (0, 0, 0, 0), "color": "1_missing"}, id="na_color.transparent" - ), - pytest.param( - {"na_color": "lightgray", "color": "1_missing"}, id="na_color.lightgray" - ), - ] -) -def spatial_kwargs(request): - return request.param - - -def test_manual_equivalency(equivalent_spatial_plotters, tmpdir, spatial_kwargs): - """ - Tests that manually passing values to sc.pl.spatial is similar to automatic extraction. - """ - orig, removed = equivalent_spatial_plotters - - TESTDIR = Path(tmpdir) - orig_pth = TESTDIR / "orig.png" - removed_pth = TESTDIR / "removed.png" - - orig(**spatial_kwargs) - plt.savefig(orig_pth, dpi=40) - plt.close() - removed(**spatial_kwargs) - plt.savefig(removed_pth, dpi=40) - plt.close() - - check_images(orig_pth, removed_pth, tol=1) - - -def test_manual_equivalency_no_img( - equivalent_spatial_plotters_no_img, tmpdir, spatial_kwargs -): - if "bw" in spatial_kwargs: - # Has no meaning when there is no image - pytest.skip() - orig, removed = equivalent_spatial_plotters_no_img - - TESTDIR = Path(tmpdir) - orig_pth = TESTDIR / "orig.png" - removed_pth = TESTDIR / "removed.png" - - orig(**spatial_kwargs) - plt.savefig(orig_pth, dpi=40) - plt.close() - removed(**spatial_kwargs) - plt.savefig(removed_pth, dpi=40) - plt.close() - - check_images(orig_pth, removed_pth, tol=1) - - -def test_white_background_vs_no_img(adata, tmpdir, spatial_kwargs): - if {"bw", "img", "img_key", "na_color"}.intersection(spatial_kwargs): - # These arguments don't make sense for this check - pytest.skip() - - white_background = np.ones_like( - adata.uns["spatial"]["scanpy_img"]["images"]["hires"] - ) - TESTDIR = Path(tmpdir) - white_pth = TESTDIR / "white_background.png" - noimg_pth = TESTDIR / "no_img.png" - - sc.pl.spatial( - adata, - color="2", - img=white_background, - scale_factor=1.0, - show=False, - **spatial_kwargs, - ) - plt.savefig(white_pth) - sc.pl.spatial(adata, color="2", img_key=None, show=False, **spatial_kwargs) - plt.savefig(noimg_pth) - - check_images(white_pth, noimg_pth, tol=1) - - -def test_spatial_na_color(adata, tmpdir): - """ - Check that na_color defaults to transparent when an image is present, light gray when not. - """ - white_background = np.ones_like( - adata.uns["spatial"]["scanpy_img"]["images"]["hires"] - ) - TESTDIR = Path(tmpdir) - lightgray_pth = TESTDIR / "lightgray.png" - transparent_pth = TESTDIR / "transparent.png" - noimg_pth = TESTDIR / "noimg.png" - whiteimg_pth = TESTDIR / "whiteimg.png" - - def plot(pth, **kwargs): - sc.pl.spatial(adata, color="1_missing", show=False, **kwargs) - plt.savefig(pth, dpi=40) - plt.close() - - plot(lightgray_pth, na_color="lightgray", img_key=None) - plot(transparent_pth, na_color=(0.0, 0.0, 0.0, 0.0), img_key=None) - plot(noimg_pth, img_key=None) - plot(whiteimg_pth, img=white_background, scale_factor=1.0) - - check_images(lightgray_pth, noimg_pth, tol=1) - check_images(transparent_pth, whiteimg_pth, tol=1) - with pytest.raises(AssertionError): - check_images(lightgray_pth, transparent_pth, tol=1) diff --git a/tests/test_plotting.py b/tests/test_plotting.py index 2f0f5f60cd..f135a68aa4 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -1456,11 +1456,10 @@ def test_rankings(image_comparer): # TODO: Make more generic -def test_scatter_rep(tmpdir): +def test_scatter_rep(tmp_path): """ Test to make sure I can predict when scatter reps should be the same """ - TESTDIR = Path(tmpdir) rep_args = { "raw": {"use_raw": True}, "layer": {"layer": "layer", "use_raw": False}, @@ -1475,7 +1474,7 @@ def test_scatter_rep(tmpdir): columns=["rep", "gene", "result"], ) states["outpth"] = [ - TESTDIR / f"{state.gene}_{state.rep}_{state.result}.png" + tmp_path / f"{state.gene}_{state.rep}_{state.result}.png" for state in states.itertuples() ] pattern = np.array(list(chain.from_iterable(repeat(i, 5) for i in range(3)))) diff --git a/tests/test_plotting_embedded/conftest.py b/tests/test_plotting_embedded/conftest.py new file mode 100644 index 0000000000..d9e8ff8581 --- /dev/null +++ b/tests/test_plotting_embedded/conftest.py @@ -0,0 +1,66 @@ +from __future__ import annotations + +from pathlib import Path + +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +import pytest + +import scanpy as sc + +HERE: Path = Path(__file__).parent + + +@pytest.fixture(scope="module") +def adata(): + """A bit cute.""" + from matplotlib.image import imread + from sklearn.cluster import DBSCAN + from sklearn.datasets import make_blobs + + empty_pixel = np.array([1.0, 1.0, 1.0, 0]).reshape(1, 1, -1) + image = imread(HERE.parent.parent / "docs/_static/img/Scanpy_Logo_RGB.png") + x, y = np.where(np.logical_and.reduce(~np.equal(image, empty_pixel), axis=2)) + + # Just using to calculate the hex coords + hexes = plt.hexbin(x, y, gridsize=(44, 100)) + counts = hexes.get_array() + pixels = hexes.get_offsets()[counts != 0] + plt.close() + + labels = DBSCAN(eps=20, min_samples=2).fit(pixels).labels_ + order = np.argsort(labels) + adata = sc.AnnData( + make_blobs( + pd.Series(labels[order]).value_counts().values, + n_features=20, + shuffle=False, + random_state=42, + )[0], + obs={"label": pd.Categorical(labels[order].astype(str))}, + obsm={"spatial": pixels[order, ::-1]}, + uns={ + "spatial": { + "scanpy_img": { + "images": {"hires": image}, + "scalefactors": { + "tissue_hires_scalef": 1, + "spot_diameter_fullres": 10, + }, + } + } + }, + ) + sc.pp.pca(adata) + + # Adding some missing values + adata.obs["label_missing"] = adata.obs["label"].copy() + adata.obs.loc[::2, "label_missing"] = np.nan + + adata.obs["1_missing"] = adata.obs_vector("1") + adata.obs.loc[ + adata.obsm["spatial"][:, 0] < adata.obsm["spatial"][:, 0].mean(), "1_missing" + ] = np.nan + + return adata diff --git a/tests/test_plotting_embedded/test_embeddings.py b/tests/test_plotting_embedded/test_embeddings.py new file mode 100644 index 0000000000..c5dc8d3e53 --- /dev/null +++ b/tests/test_plotting_embedded/test_embeddings.py @@ -0,0 +1,253 @@ +from __future__ import annotations + +from functools import partial, wraps +from pathlib import Path +from typing import TYPE_CHECKING + +import matplotlib.pyplot as plt +import numpy as np +import pytest +import seaborn as sns +from matplotlib.colors import Normalize +from matplotlib.testing.compare import compare_images + +import scanpy as sc +from testing.scanpy._helpers.data import pbmc3k_processed + +if TYPE_CHECKING: + from scanpy.plotting._utils import _LegendLoc + + +HERE: Path = Path(__file__).parent +ROOT = HERE.parent / "_images" + +MISSING_VALUES_ROOT = ROOT / "embedding-missing-values" + + +def check_images(pth1: Path, pth2: Path, *, tol: int) -> None: + result = compare_images(str(pth1), str(pth2), tol=tol) + assert result is None, result + + +@pytest.fixture( + params=[(0, 0, 0, 1), None], + ids=["na_color.black_tup", "na_color.default"], +) +def na_color(request): + return request.param + + +@pytest.fixture(params=[True, False], ids=["na_in_legend.True", "na_in_legend.False"]) +def na_in_legend(request): + return request.param + + +@pytest.fixture(params=[sc.pl.pca, sc.pl.spatial]) +def plotfunc(request): + if request.param is sc.pl.spatial: + + @wraps(request.param) + def f(adata, **kwargs): + with pytest.warns(FutureWarning, match=r"Use `squidpy.*` instead"): + return sc.pl.spatial(adata, **kwargs) + + else: + f = request.param + return partial(f, show=False) + + +@pytest.fixture( + params=["on data", "right margin", "lower center", None], + ids=["legend.on_data", "legend.on_right", "legend.on_bottom", "legend.off"], +) +def legend_loc(request) -> _LegendLoc | None: + return request.param + + +@pytest.fixture( + params=[lambda x: list(x.cat.categories[:3]), lambda x: []], + ids=["groups.3", "groups.all"], +) +def groupsfunc(request): + return request.param + + +@pytest.fixture( + params=[ + pytest.param( + {"vmin": None, "vmax": None, "vcenter": None, "norm": None}, + id="vbounds.default", + ), + pytest.param( + {"vmin": 0, "vmax": 5, "vcenter": None, "norm": None}, id="vbounds.numbers" + ), + pytest.param( + {"vmin": "p15", "vmax": "p90", "vcenter": None, "norm": None}, + id="vbounds.percentile", + ), + pytest.param( + {"vmin": 0, "vmax": "p99", "vcenter": 0.1, "norm": None}, + id="vbounds.vcenter", + ), + pytest.param( + {"vmin": None, "vmax": None, "vcenter": None, "norm": Normalize(0, 5)}, + id="vbounds.norm", + ), + ] +) +def vbounds(request): + return request.param + + +def test_missing_values_categorical( + *, + request: pytest.FixtureRequest, + image_comparer, + adata, + plotfunc, + na_color, + na_in_legend, + legend_loc, + groupsfunc, +): + save_and_compare_images = partial(image_comparer, MISSING_VALUES_ROOT, tol=15) + + base_name = request.node.name + + # Passing through a dict so it's easier to use default values + kwargs = {} + kwargs["legend_loc"] = legend_loc + kwargs["groups"] = groupsfunc(adata.obs["label"]) + if na_color is not None: + kwargs["na_color"] = na_color + kwargs["na_in_legend"] = na_in_legend + + plotfunc(adata, color=["label", "label_missing"], **kwargs) + + save_and_compare_images(base_name) + + +def test_missing_values_continuous( + *, + request: pytest.FixtureRequest, + image_comparer, + adata, + plotfunc, + na_color, + vbounds, +): + save_and_compare_images = partial(image_comparer, MISSING_VALUES_ROOT, tol=15) + + base_name = request.node.name + + # Passing through a dict so it's easier to use default values + kwargs = {} + kwargs.update(vbounds) + if na_color is not None: + kwargs["na_color"] = na_color + + plotfunc(adata, color=["1", "1_missing"], **kwargs) + + save_and_compare_images(base_name) + + +def test_enumerated_palettes(request, adata, tmp_path, plotfunc): + base_name = request.node.name + + categories = adata.obs["label"].cat.categories + colors_rgb = dict(zip(categories, sns.color_palette(n_colors=12))) + + dict_pth = tmp_path / f"rgbdict_{base_name}.png" + list_pth = tmp_path / f"rgblist_{base_name}.png" + + # making a copy so colors aren't saved + plotfunc(adata.copy(), color="label", palette=colors_rgb) + plt.savefig(dict_pth, dpi=40) + plt.close() + plotfunc(adata.copy(), color="label", palette=[colors_rgb[c] for c in categories]) + plt.savefig(list_pth, dpi=40) + plt.close() + + check_images(dict_pth, list_pth, tol=15) + + +def test_dimension_broadcasting(adata, tmp_path, check_same_image): + with pytest.raises( + ValueError, + match=r"Could not broadcast together arguments with shapes: \[2, 3, 1\]", + ): + sc.pl.pca( + adata, color=["label", "1_missing"], dimensions=[(0, 1), (1, 2), (2, 3)] + ) + + dims_pth = tmp_path / "broadcast_dims.png" + color_pth = tmp_path / "broadcast_colors.png" + + sc.pl.pca(adata, color=["label", "label", "label"], dimensions=(2, 3), show=False) + plt.savefig(dims_pth, dpi=40) + plt.close() + sc.pl.pca(adata, color="label", dimensions=[(2, 3), (2, 3), (2, 3)], show=False) + plt.savefig(color_pth, dpi=40) + plt.close() + + check_same_image(dims_pth, color_pth, tol=5) + + +def test_marker_broadcasting(adata, tmp_path, check_same_image): + with pytest.raises( + ValueError, + match=r"Could not broadcast together arguments with shapes: \[2, 1, 3\]", + ): + sc.pl.pca(adata, color=["label", "1_missing"], marker=[".", "^", "x"]) + + dims_pth = tmp_path / "broadcast_markers.png" + color_pth = tmp_path / "broadcast_colors_for_markers.png" + + sc.pl.pca(adata, color=["label", "label", "label"], marker="^", show=False) + plt.savefig(dims_pth, dpi=40) + plt.close() + sc.pl.pca(adata, color="label", marker=["^", "^", "^"], show=False) + plt.savefig(color_pth, dpi=40) + plt.close() + + check_same_image(dims_pth, color_pth, tol=5) + + +def test_dimensions_same_as_components(adata, tmp_path, check_same_image): + adata = adata.copy() + adata.obs["mean"] = np.ravel(adata.X.mean(axis=1)) + + comp_pth = tmp_path / "components_plot.png" + dims_pth = tmp_path / "dimension_plot.png" + + # TODO: Deprecate components kwarg + # with pytest.warns(FutureWarning, match=r"components .* deprecated"): + sc.pl.pca( + adata, + color=["mean", "label"], + components=["1,2", "2,3"], + show=False, + ) + plt.savefig(comp_pth, dpi=40) + plt.close() + + sc.pl.pca( + adata, + color=["mean", "mean", "label", "label"], + dimensions=[(0, 1), (1, 2), (0, 1), (1, 2)], + show=False, + ) + plt.savefig(dims_pth, dpi=40) + plt.close() + + check_same_image(dims_pth, comp_pth, tol=5) + + +def test_embedding_colorbar_location(image_comparer): + save_and_compare_images = partial(image_comparer, ROOT, tol=15) + + adata = pbmc3k_processed().raw.to_adata() + + sc.pl.pca(adata, color="LDHB", colorbar_loc=None) + + save_and_compare_images("no_colorbar") diff --git a/tests/test_plotting_embedded/test_spatial.py b/tests/test_plotting_embedded/test_spatial.py new file mode 100644 index 0000000000..873db68794 --- /dev/null +++ b/tests/test_plotting_embedded/test_spatial.py @@ -0,0 +1,267 @@ +from __future__ import annotations + +from functools import partial +from pathlib import Path + +import matplotlib as mpl +import matplotlib.pyplot as plt +import numpy as np +import pytest +from matplotlib.testing.compare import compare_images + +import scanpy as sc + +HERE: Path = Path(__file__).parent +ROOT = HERE.parent / "_images" +DATA_DIR = HERE.parent / "_data" + + +pytestmark = [ + pytest.mark.filterwarnings("ignore:Use `squidpy.*` instead:FutureWarning") +] + + +def check_images(pth1: Path, pth2: Path, *, tol: int) -> None: + result = compare_images(str(pth1), str(pth2), tol=tol) + assert result is None, result + + +def test_visium_circles(image_comparer): # standard visium data + save_and_compare_images = partial(image_comparer, ROOT, tol=15) + + adata = sc.read_visium(DATA_DIR / "visium_data" / "1.0.0") + adata.obs = adata.obs.astype({"array_row": "str"}) + + sc.pl.spatial( + adata, + color="array_row", + groups=["24", "33"], + crop_coord=(100, 400, 400, 100), + alpha=0.5, + size=1.3, + show=False, + ) + + save_and_compare_images("spatial_visium") + + +def test_visium_default(image_comparer): # default values + from packaging.version import parse as parse_version + + if parse_version(mpl.__version__) < parse_version("3.7.0"): + pytest.xfail("Matplotlib 3.7.0+ required for this test") + + save_and_compare_images = partial(image_comparer, ROOT, tol=5) + + adata = sc.read_visium(DATA_DIR / "visium_data" / "1.0.0") + adata.obs = adata.obs.astype({"array_row": "str"}) + + # Points default to transparent if an image is included + sc.pl.spatial(adata, show=False) + + save_and_compare_images("spatial_visium_default") + + +def test_visium_empty_img_key(image_comparer): # visium coordinates but image empty + save_and_compare_images = partial(image_comparer, ROOT, tol=15) + + adata = sc.read_visium(DATA_DIR / "visium_data" / "1.0.0") + adata.obs = adata.obs.astype({"array_row": "str"}) + + sc.pl.spatial(adata, img_key=None, color="array_row", show=False) + + save_and_compare_images("spatial_visium_empty_image") + + sc.pl.embedding(adata, basis="spatial", color="array_row", show=False) + save_and_compare_images("spatial_visium_embedding") + + +def test_spatial_general(image_comparer): # general coordinates + save_and_compare_images = partial(image_comparer, ROOT, tol=15) + + adata = sc.read_visium(DATA_DIR / "visium_data" / "1.0.0") + adata.obs = adata.obs.astype({"array_row": "str"}) + spatial_metadata = adata.uns.pop( + "spatial" + ) # spatial data don't have imgs, so remove entry from uns + # Required argument for now + spot_size = list(spatial_metadata.values())[0]["scalefactors"][ + "spot_diameter_fullres" + ] + + sc.pl.spatial(adata, show=False, spot_size=spot_size) + save_and_compare_images("spatial_general_nocol") + + # category + sc.pl.spatial(adata, show=False, spot_size=spot_size, color="array_row") + save_and_compare_images("spatial_general_cat") + + # continuous + sc.pl.spatial(adata, show=False, spot_size=spot_size, color="array_col") + save_and_compare_images("spatial_general_cont") + + +def test_spatial_external_img(image_comparer): # external image + save_and_compare_images = partial(image_comparer, ROOT, tol=15) + + adata = sc.read_visium(DATA_DIR / "visium_data" / "1.0.0") + adata.obs = adata.obs.astype({"array_row": "str"}) + + img = adata.uns["spatial"]["custom"]["images"]["hires"] + scalef = adata.uns["spatial"]["custom"]["scalefactors"]["tissue_hires_scalef"] + sc.pl.spatial( + adata, + color="array_row", + scale_factor=scalef, + img=img, + basis="spatial", + show=False, + ) + save_and_compare_images("spatial_external_img") + + +@pytest.fixture(scope="module") +def equivalent_spatial_plotters(adata): + no_spatial = adata.copy() + del no_spatial.uns["spatial"] + + img_key = "hires" + library_id = list(adata.uns["spatial"])[0] + spatial_data = adata.uns["spatial"][library_id] + img = spatial_data["images"][img_key] + scale_factor = spatial_data["scalefactors"][f"tissue_{img_key}_scalef"] + spot_size = spatial_data["scalefactors"]["spot_diameter_fullres"] + + orig_plotter = partial(sc.pl.spatial, adata, color="1", show=False) + removed_plotter = partial( + sc.pl.spatial, + no_spatial, + color="1", + img=img, + scale_factor=scale_factor, + spot_size=spot_size, + show=False, + ) + + return (orig_plotter, removed_plotter) + + +@pytest.fixture(scope="module") +def equivalent_spatial_plotters_no_img(equivalent_spatial_plotters): + orig, removed = equivalent_spatial_plotters + return (partial(orig, img_key=None), partial(removed, img=None, scale_factor=None)) + + +@pytest.fixture( + params=[ + pytest.param({"crop_coord": (50, 200, 0, 500)}, id="crop"), + pytest.param({"size": 0.5}, id="size:.5"), + pytest.param({"size": 2}, id="size:2"), + pytest.param({"spot_size": 5}, id="spotsize"), + pytest.param({"bw": True}, id="bw"), + # Shape of the image for particular fixture, should not be hardcoded like this + pytest.param({"img": np.ones((774, 1755, 4)), "scale_factor": 1.0}, id="img"), + pytest.param( + {"na_color": (0, 0, 0, 0), "color": "1_missing"}, id="na_color.transparent" + ), + pytest.param( + {"na_color": "lightgray", "color": "1_missing"}, id="na_color.lightgray" + ), + ] +) +def spatial_kwargs(request): + return request.param + + +def test_manual_equivalency(equivalent_spatial_plotters, tmp_path, spatial_kwargs): + """ + Tests that manually passing values to sc.pl.spatial is similar to automatic extraction. + """ + orig, removed = equivalent_spatial_plotters + + orig_pth = tmp_path / "orig.png" + removed_pth = tmp_path / "removed.png" + + orig(**spatial_kwargs) + plt.savefig(orig_pth, dpi=40) + plt.close() + removed(**spatial_kwargs) + plt.savefig(removed_pth, dpi=40) + plt.close() + + check_images(orig_pth, removed_pth, tol=1) + + +def test_manual_equivalency_no_img( + equivalent_spatial_plotters_no_img, tmp_path, spatial_kwargs +): + if "bw" in spatial_kwargs: + # Has no meaning when there is no image + pytest.skip() + orig, removed = equivalent_spatial_plotters_no_img + + orig_pth = tmp_path / "orig.png" + removed_pth = tmp_path / "removed.png" + + orig(**spatial_kwargs) + plt.savefig(orig_pth, dpi=40) + plt.close() + removed(**spatial_kwargs) + plt.savefig(removed_pth, dpi=40) + plt.close() + + check_images(orig_pth, removed_pth, tol=1) + + +def test_white_background_vs_no_img(adata, tmp_path, spatial_kwargs): + if {"bw", "img", "img_key", "na_color"}.intersection(spatial_kwargs): + # These arguments don't make sense for this check + pytest.skip() + + white_background = np.ones_like( + adata.uns["spatial"]["scanpy_img"]["images"]["hires"] + ) + white_pth = tmp_path / "white_background.png" + noimg_pth = tmp_path / "no_img.png" + + sc.pl.spatial( + adata, + color="2", + img=white_background, + scale_factor=1.0, + show=False, + **spatial_kwargs, + ) + plt.savefig(white_pth) + sc.pl.spatial(adata, color="2", img_key=None, show=False, **spatial_kwargs) + plt.savefig(noimg_pth) + + check_images(white_pth, noimg_pth, tol=1) + + +def test_spatial_na_color(adata, tmp_path): + """ + Check that na_color defaults to transparent when an image is present, light gray when not. + """ + white_background = np.ones_like( + adata.uns["spatial"]["scanpy_img"]["images"]["hires"] + ) + lightgray_pth = tmp_path / "lightgray.png" + transparent_pth = tmp_path / "transparent.png" + noimg_pth = tmp_path / "noimg.png" + whiteimg_pth = tmp_path / "whiteimg.png" + + def plot(pth, **kwargs): + sc.pl.spatial(adata, color="1_missing", show=False, **kwargs) + plt.savefig(pth, dpi=40) + plt.close() + + plot(lightgray_pth, na_color="lightgray", img_key=None) + plot(transparent_pth, na_color=(0.0, 0.0, 0.0, 0.0), img_key=None) + plot(noimg_pth, img_key=None) + plot(whiteimg_pth, img=white_background, scale_factor=1.0) + + check_images(lightgray_pth, noimg_pth, tol=1) + check_images(transparent_pth, whiteimg_pth, tol=1) + with pytest.raises(AssertionError): + check_images(lightgray_pth, transparent_pth, tol=1) diff --git a/tests/test_read_10x.py b/tests/test_read_10x.py index 7b31f6bddf..301a156bec 100644 --- a/tests/test_read_10x.py +++ b/tests/test_read_10x.py @@ -143,6 +143,7 @@ def visium_pth(request, tmp_path) -> Path: pytest.fail("add branch for new visium version") +@pytest.mark.filterwarnings("ignore:Use `squidpy.*` instead:FutureWarning") def test_read_visium_counts(visium_pth): """Test checking that read_visium reads the right genome""" spec_genome_v3 = sc.read_visium(visium_pth, genome="GRCh38") From e8cd544ae41afd766c385c788266f41049f3f5e4 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 20 Dec 2024 14:19:20 +0100 Subject: [PATCH 103/118] Add sample probabilities (#3410) --- docs/release-notes/3410.feature.md | 1 + src/scanpy/get/_aggregated.py | 3 +- src/scanpy/get/get.py | 49 +++++++++++++----- src/scanpy/plotting/_tools/scatterplots.py | 3 +- src/scanpy/preprocessing/_scale.py | 2 +- src/scanpy/preprocessing/_simple.py | 16 +++++- src/scanpy/tools/_rank_genes_groups.py | 3 +- tests/test_preprocessing.py | 59 +++++++++++++++++----- 8 files changed, 102 insertions(+), 34 deletions(-) create mode 100644 docs/release-notes/3410.feature.md diff --git a/docs/release-notes/3410.feature.md b/docs/release-notes/3410.feature.md new file mode 100644 index 0000000000..d95ad201ba --- /dev/null +++ b/docs/release-notes/3410.feature.md @@ -0,0 +1 @@ +Add sampling probabilities/mask parameter `p` to {func}`~scanpy.pp.sample` {smaller}`P Angerer` diff --git a/src/scanpy/get/_aggregated.py b/src/scanpy/get/_aggregated.py index 13ca54b5c4..53a18bb47c 100644 --- a/src/scanpy/get/_aggregated.py +++ b/src/scanpy/get/_aggregated.py @@ -263,8 +263,7 @@ def aggregate( if axis is None: axis = 1 if varm else 0 axis, axis_name = _resolve_axis(axis) - if mask is not None: - mask = _check_mask(adata, mask, axis_name) + mask = _check_mask(adata, mask, axis_name) data = adata.X if sum(p is not None for p in [varm, obsm, layer]) > 1: raise TypeError("Please only provide one (or none) of varm, obsm, or layer") diff --git a/src/scanpy/get/get.py b/src/scanpy/get/get.py index f3172ed45e..c36ddde8f8 100644 --- a/src/scanpy/get/get.py +++ b/src/scanpy/get/get.py @@ -2,11 +2,12 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, TypeVar import numpy as np import pandas as pd from anndata import AnnData +from numpy.typing import NDArray from packaging.version import Version from scipy.sparse import spmatrix @@ -16,7 +17,11 @@ from anndata._core.sparse_dataset import BaseCompressedSparseDataset from anndata._core.views import ArrayView - from numpy.typing import NDArray + from scipy.sparse import csc_matrix, csr_matrix + + from .._compat import DaskArray + + CSMatrix = csr_matrix | csc_matrix # -------------------------------------------------------------------------------- # Plotting data helpers @@ -485,11 +490,16 @@ def _set_obs_rep( raise AssertionError(msg) +M = TypeVar("M", bound=NDArray[np.bool_] | NDArray[np.floating] | pd.Series | None) + + def _check_mask( - data: AnnData | np.ndarray, - mask: NDArray[np.bool_] | str, + data: AnnData | np.ndarray | CSMatrix | DaskArray, + mask: str | M, dim: Literal["obs", "var"], -) -> NDArray[np.bool_]: # Could also be a series, but should be one or the other + *, + allow_probabilities: bool = False, +) -> M: # Could also be a series, but should be one or the other """ Validate mask argument Params @@ -497,30 +507,45 @@ def _check_mask( data Annotated data matrix or numpy array. mask - The mask. Either an appropriatley sized boolean array, or name of a column which will be used to mask. + Mask (or probabilities if `allow_probabilities=True`). + Either an appropriatley sized array, or name of a column. dim The dimension being masked. + allow_probabilities + Whether to allow probabilities as `mask` """ + if mask is None: + return mask + desc = "mask/probabilities" if allow_probabilities else "mask" + if isinstance(mask, str): if not isinstance(data, AnnData): - msg = "Cannot refer to mask with string without providing anndata object as argument" + msg = f"Cannot refer to {desc} with string without providing anndata object as argument" raise ValueError(msg) annot: pd.DataFrame = getattr(data, dim) if mask not in annot.columns: msg = ( f"Did not find `adata.{dim}[{mask!r}]`. " - f"Either add the mask first to `adata.{dim}`" - "or consider using the mask argument with a boolean array." + f"Either add the {desc} first to `adata.{dim}`" + f"or consider using the {desc} argument with an array." ) raise ValueError(msg) mask_array = annot[mask].to_numpy() else: if len(mask) != data.shape[0 if dim == "obs" else 1]: - raise ValueError("The shape of the mask do not match the data.") + msg = f"The shape of the {desc} do not match the data." + raise ValueError(msg) mask_array = mask - if not pd.api.types.is_bool_dtype(mask_array.dtype): - raise ValueError("Mask array must be boolean.") + is_bool = pd.api.types.is_bool_dtype(mask_array.dtype) + if not allow_probabilities and not is_bool: + msg = "Mask array must be boolean." + raise ValueError(msg) + elif allow_probabilities and not ( + is_bool or pd.api.types.is_float_dtype(mask_array.dtype) + ): + msg = f"{desc} array must be boolean or floating point." + raise ValueError(msg) return mask_array diff --git a/src/scanpy/plotting/_tools/scatterplots.py b/src/scanpy/plotting/_tools/scatterplots.py index e2564eb17f..b54897678f 100644 --- a/src/scanpy/plotting/_tools/scatterplots.py +++ b/src/scanpy/plotting/_tools/scatterplots.py @@ -150,8 +150,7 @@ def embedding( # Checking the mask format and if used together with groups if groups is not None and mask_obs is not None: raise ValueError("Groups and mask arguments are incompatible.") - if mask_obs is not None: - mask_obs = _check_mask(adata, mask_obs, "obs") + mask_obs = _check_mask(adata, mask_obs, "obs") # Figure out if we're using raw if use_raw is None: diff --git a/src/scanpy/preprocessing/_scale.py b/src/scanpy/preprocessing/_scale.py index d7123d5f65..bac08f246b 100644 --- a/src/scanpy/preprocessing/_scale.py +++ b/src/scanpy/preprocessing/_scale.py @@ -164,8 +164,8 @@ def scale_array( ): if copy: X = X.copy() + mask_obs = _check_mask(X, mask_obs, "obs") if mask_obs is not None: - mask_obs = _check_mask(X, mask_obs, "obs") scale_rv = scale_array( X[mask_obs, :], zero_center=zero_center, diff --git a/src/scanpy/preprocessing/_simple.py b/src/scanpy/preprocessing/_simple.py index 14f2b9d382..b8ae00bd18 100644 --- a/src/scanpy/preprocessing/_simple.py +++ b/src/scanpy/preprocessing/_simple.py @@ -31,7 +31,7 @@ sanitize_anndata, view_to_actual, ) -from ..get import _get_obs_rep, _set_obs_rep +from ..get import _check_mask, _get_obs_rep, _set_obs_rep from ._distributed import materialize_as_ndarray from ._utils import _to_dense @@ -909,6 +909,7 @@ def sample( copy: Literal[False] = False, replace: bool = False, axis: Literal["obs", 0, "var", 1] = "obs", + p: str | NDArray[np.bool_] | NDArray[np.floating] | None = None, ) -> None: ... @overload def sample( @@ -920,6 +921,7 @@ def sample( copy: Literal[True], replace: bool = False, axis: Literal["obs", 0, "var", 1] = "obs", + p: str | NDArray[np.bool_] | NDArray[np.floating] | None = None, ) -> AnnData: ... @overload def sample( @@ -931,6 +933,7 @@ def sample( copy: bool = False, replace: bool = False, axis: Literal["obs", 0, "var", 1] = "obs", + p: str | NDArray[np.bool_] | NDArray[np.floating] | None = None, ) -> tuple[A, NDArray[np.int64]]: ... def sample( data: AnnData | np.ndarray | CSMatrix | DaskArray, @@ -941,6 +944,7 @@ def sample( copy: bool = False, replace: bool = False, axis: Literal["obs", 0, "var", 1] = "obs", + p: str | NDArray[np.bool_] | NDArray[np.floating] | None = None, ) -> AnnData | None | tuple[np.ndarray | CSMatrix | DaskArray, NDArray[np.int64]]: """\ Sample observations or variables with or without replacement. @@ -952,6 +956,7 @@ def sample( Rows correspond to cells and columns to genes. fraction Sample to this `fraction` of the number of observations or variables. + (All of them, even if there are `0`s/`False`s in `p`.) This can be larger than 1.0, if `replace=True`. See `axis` and `replace`. n @@ -965,6 +970,10 @@ def sample( If True, samples are drawn with replacement. axis Sample `obs`\\ ervations (axis 0) or `var`\\ iables (axis 1). + p + Drawing probabilities (floats) or mask (bools). + Either an `axis`-sized array, or the name of a column. + If `p` is an array of probabilities, it must sum to 1. Returns ------- @@ -981,6 +990,9 @@ def sample( msg = "Inplace sampling (`copy=False`) is not implemented for backed objects." raise NotImplementedError(msg) axis, axis_name = _resolve_axis(axis) + p = _check_mask(data, p, dim=axis_name, allow_probabilities=True) + if p is not None and p.dtype == bool: + p = p.astype(np.float64) / p.sum() old_n = data.shape[axis] match (fraction, n): case (None, None): @@ -1004,7 +1016,7 @@ def sample( # actually do subsampling rng = np.random.default_rng(rng) - indices = rng.choice(old_n, size=n, replace=replace) + indices = rng.choice(old_n, size=n, replace=replace, p=p) # overload 1: inplace AnnData subset if not copy and isinstance(data, AnnData): diff --git a/src/scanpy/tools/_rank_genes_groups.py b/src/scanpy/tools/_rank_genes_groups.py index aa4428dad1..2c214fcfdd 100644 --- a/src/scanpy/tools/_rank_genes_groups.py +++ b/src/scanpy/tools/_rank_genes_groups.py @@ -594,8 +594,7 @@ def rank_genes_groups( >>> # to visualize the results >>> sc.pl.rank_genes_groups(adata) """ - if mask_var is not None: - mask_var = _check_mask(adata, mask_var, "var") + mask_var = _check_mask(adata, mask_var, "var") if use_raw is None: use_raw = adata.raw is not None diff --git a/tests/test_preprocessing.py b/tests/test_preprocessing.py index 36283e7ed0..6282c5ccf4 100644 --- a/tests/test_preprocessing.py +++ b/tests/test_preprocessing.py @@ -29,6 +29,8 @@ from collections.abc import Callable from typing import Any, Literal + from numpy.typing import NDArray + CSMatrix = sp.csc_matrix | sp.csr_matrix @@ -144,31 +146,55 @@ def test_normalize_per_cell(): assert adata.X.sum(axis=1).tolist() == adata_sparse.X.sum(axis=1).A1.tolist() +def _random_probs(n: int, frac_zero: float) -> NDArray[np.float64]: + """ + Generate a random probability distribution of `n` values between 0 and 1. + """ + probs = np.random.randint(0, 10000, n).astype(np.float64) + probs[probs < np.quantile(probs, frac_zero)] = 0 + probs /= probs.sum() + np.testing.assert_almost_equal(probs.sum(), 1) + return probs + + @pytest.mark.parametrize("array_type", ARRAY_TYPES) @pytest.mark.parametrize("which", ["copy", "inplace", "array"]) @pytest.mark.parametrize( - ("axis", "fraction", "n", "replace", "expected"), + ("axis", "f_or_n", "replace"), + [ + pytest.param(0, 40, False, id="obs-40-no_replace"), + pytest.param(0, 0.1, False, id="obs-0.1-no_replace"), + pytest.param(0, 201, True, id="obs-201-replace"), + pytest.param(0, 1, True, id="obs-1-replace"), + pytest.param(1, 10, False, id="var-10-no_replace"), + pytest.param(1, 11, True, id="var-11-replace"), + pytest.param(1, 2.0, True, id="var-2.0-replace"), + ], +) +@pytest.mark.parametrize( + "ps", [ - pytest.param(0, None, 40, False, 40, id="obs-40-no_replace"), - pytest.param(0, 0.1, None, False, 20, id="obs-0.1-no_replace"), - pytest.param(0, None, 201, True, 201, id="obs-201-replace"), - pytest.param(0, None, 1, True, 1, id="obs-1-replace"), - pytest.param(1, None, 10, False, 10, id="var-10-no_replace"), - pytest.param(1, None, 11, True, 11, id="var-11-replace"), - pytest.param(1, 2.0, None, True, 20, id="var-2.0-replace"), + dict(obs=None, var=None), + dict(obs=np.tile([True, False], 100), var=np.tile([True, False], 5)), + dict(obs=_random_probs(200, 0.3), var=_random_probs(10, 0.7)), ], + ids=["all", "mask", "p"], ) def test_sample( *, + request: pytest.FixtureRequest, array_type: Callable[[np.ndarray], np.ndarray | CSMatrix], which: Literal["copy", "inplace", "array"], axis: Literal[0, 1], - fraction: float | None, - n: int | None, + f_or_n: float | int, # noqa: PYI041 replace: bool, - expected: int, + ps: dict[Literal["obs", "var"], NDArray[np.bool_] | None], ): adata = AnnData(array_type(np.ones((200, 10)))) + p = ps["obs" if axis == 0 else "var"] + expected = int(adata.shape[axis] * f_or_n) if isinstance(f_or_n, float) else f_or_n + if p is not None and not replace and expected > (n_possible := (p != 0).sum()): + request.applymarker(pytest.xfail(f"Can’t draw {expected} out of {n_possible}")) # ignoring this warning declaratively is a pain so do it here if find_spec("dask"): @@ -182,12 +208,13 @@ def test_sample( ) rv = sc.pp.sample( adata.X if which == "array" else adata, - fraction, - n=n, + f_or_n if isinstance(f_or_n, float) else None, + n=f_or_n if isinstance(f_or_n, int) else None, replace=replace, axis=axis, # `copy` only effects AnnData inputs copy=dict(copy=True, inplace=False, array=False)[which], + p=p, ) match which: @@ -232,6 +259,12 @@ def test_sample( r"`fraction=-0\.3` needs to be nonnegative", id="frac<0", ), + pytest.param( + dict(n=3, p=np.ones(200, dtype=np.int32)), + ValueError, + r"mask/probabilities array must be boolean or floating point", + id="type(p)", + ), ], ) def test_sample_error(args: dict[str, Any], exc: type[Exception], pattern: str): From a578d836bb9344be7b8cfc0bb33bdb0d774ab2c6 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 20 Dec 2024 14:45:40 +0100 Subject: [PATCH 104/118] (chore): generate 1.11.0 release notes (#3412) --- ci/scripts/towncrier_automation.py | 6 +++- docs/release-notes/1.11.0.md | 38 ++++++++++++++++++++++++++ docs/release-notes/2921.feature.md | 1 - docs/release-notes/3155.feature.md | 1 - docs/release-notes/3180.feature.md | 1 - docs/release-notes/3184.feature.md | 1 - docs/release-notes/3263.feature.md | 1 - docs/release-notes/3267.feature.md | 1 - docs/release-notes/3284.performance.md | 1 - docs/release-notes/3296.feature.md | 1 - docs/release-notes/3307.feature.md | 1 - docs/release-notes/3324.feature.md | 1 - docs/release-notes/3335.feature.md | 1 - docs/release-notes/3362.doc.md | 1 - docs/release-notes/3380.bugfix.md | 1 - docs/release-notes/3384.feature.md | 1 - docs/release-notes/3393.bugfix.md | 1 - docs/release-notes/3407.misc.md | 7 ----- docs/release-notes/3410.feature.md | 1 - docs/release-notes/943.feature.md | 1 - 20 files changed, 43 insertions(+), 25 deletions(-) create mode 100644 docs/release-notes/1.11.0.md delete mode 100644 docs/release-notes/2921.feature.md delete mode 100644 docs/release-notes/3155.feature.md delete mode 100644 docs/release-notes/3180.feature.md delete mode 100644 docs/release-notes/3184.feature.md delete mode 100644 docs/release-notes/3263.feature.md delete mode 100644 docs/release-notes/3267.feature.md delete mode 100644 docs/release-notes/3284.performance.md delete mode 100644 docs/release-notes/3296.feature.md delete mode 100644 docs/release-notes/3307.feature.md delete mode 100644 docs/release-notes/3324.feature.md delete mode 100644 docs/release-notes/3335.feature.md delete mode 100644 docs/release-notes/3362.doc.md delete mode 100644 docs/release-notes/3380.bugfix.md delete mode 100644 docs/release-notes/3384.feature.md delete mode 100644 docs/release-notes/3393.bugfix.md delete mode 100644 docs/release-notes/3407.misc.md delete mode 100644 docs/release-notes/3410.feature.md delete mode 100644 docs/release-notes/943.feature.md diff --git a/ci/scripts/towncrier_automation.py b/ci/scripts/towncrier_automation.py index c532883036..10a8b0c9dc 100755 --- a/ci/scripts/towncrier_automation.py +++ b/ci/scripts/towncrier_automation.py @@ -92,7 +92,11 @@ def main(argv: Sequence[str] | None = None) -> None: f"--base={base_branch}", f"--title={pr_title}", f"--body={pr_description}", - *(["--label=no milestone"] if base_branch == "main" else []), + *( + ["--label=no milestone", "--label=Development Process 🚀"] + if base_branch == "main" + else [] + ), *(["--dry-run"] if args.dry_run else []), ], check=True, diff --git a/docs/release-notes/1.11.0.md b/docs/release-notes/1.11.0.md new file mode 100644 index 0000000000..8c51fe8a37 --- /dev/null +++ b/docs/release-notes/1.11.0.md @@ -0,0 +1,38 @@ +(v1.11.0)= +### 1.11.0 {small}`2024-12-20` + +### Features + +- {func}`~scanpy.pp.sample` supports both upsampling and downsampling of observations and variables. {func}`~scanpy.pp.subsample` is now deprecated. {smaller}`G Eraslan & P Angerer` ({pr}`943`) +- Add `layer` argument to {func}`scanpy.tl.score_genes` and {func}`scanpy.tl.score_genes_cell_cycle` {smaller}`L Zappia` ({pr}`2921`) +- Prevent `raw` conflict with `layer` in {func}`~scanpy.tl.score_genes` {smaller}`S Dicks` ({pr}`3155`) +- Add support for `median` as an aggregation function to the `Aggregation` class in `scanpy.get._aggregated.py`. This allows for median-based aggregation of data (e.g., pseudobulk), complementing existing methods like mean- and sum-based aggregation {smaller}`M Dehkordi (Farhad)` ({pr}`3180`) +- Add `key_added` argument to {func}`~scanpy.pp.pca`, {func}`~scanpy.tl.tsne` and {func}`~scanpy.tl.umap` {smaller}`P Angerer` ({pr}`3184`) +- Support running {func}`scanpy.pp.pca` on sparse Dask arrays with the `'covariance_eigh'` solver {smaller}`P Angerer` ({pr}`3263`) +- Use upstreamed {class}`~sklearn.decomposition.PCA` implementation for {class}`~scipy.sparse.csr_array` and {class}`~scipy.sparse.csr_matrix` (see {ref}`sklearn:changes_1_4`) {smaller}`P Angerer` ({pr}`3267`) +- Add explicit support to {func}`scanpy.pp.pca` for `svd_solver='covariance_eigh'` {smaller}`P Angerer` ({pr}`3296`) +- Add support {class}`dask.array.Array` to {func}`scanpy.pp.calculate_qc_metrics` {smaller}`I Gold` ({pr}`3307`) +- Support `layer` parameter in {func}`scanpy.pl.highest_expr_genes` {smaller}`P Angerer` ({pr}`3324`) +- Run numba functions single-threaded when called from inside of a ThreadPool {smaller}`P Angerer` ({pr}`3335`) +- Switch {func}`~scanpy.logging.print_header` and {func}`~scanpy.logging.print_versions` to {mod}`session_info2` {smaller}`P Angerer` ({pr}`3384`) +- Add sampling probabilities/mask parameter `p` to {func}`~scanpy.pp.sample` {smaller}`P Angerer` ({pr}`3410`) + +### Performance + +- Speed up {func}`~scanpy.pp.regress_out` {smaller}`P Ashish, P Angerer & S Dicks` ({pr}`3284`) + +### Documentation + +- Improve {func}`~scanpy.external.pp.harmony_integrate` docs {smaller}`D Kühl` ({pr}`3362`) +- Raise {exc}`FutureWarning` when calling deprecated {mod}`scanpy.pp` functions {smaller}`P Angerer` ({pr}`3380`) +- | Deprecate … | in favor of … | + | --- | --- | + | {func}`scanpy.read_visium` | {func}`squidpy.read.visium` | + | {func}`scanpy.datasets.visium_sge` | {func}`squidpy.datasets.visium` | + | {func}`scanpy.pl.spatial` | {func}`squidpy.pl.spatial_scatter` | + + {smaller}`P Angerer` ({pr}`3407`) + +### Bug fixes + +- Upper-bound {mod}`sklearn` `<1.6.0` due to {issue}`dask/dask-ml#1002` {smaller}`Ilan Gold` ({pr}`3393`) diff --git a/docs/release-notes/2921.feature.md b/docs/release-notes/2921.feature.md deleted file mode 100644 index e3c964abb2..0000000000 --- a/docs/release-notes/2921.feature.md +++ /dev/null @@ -1 +0,0 @@ -Add `layer` argument to {func}`scanpy.tl.score_genes` and {func}`scanpy.tl.score_genes_cell_cycle` {smaller}`L Zappia` diff --git a/docs/release-notes/3155.feature.md b/docs/release-notes/3155.feature.md deleted file mode 100644 index 770c504348..0000000000 --- a/docs/release-notes/3155.feature.md +++ /dev/null @@ -1 +0,0 @@ -Prevent `raw` conflict with `layer` in {func}`~scanpy.tl.score_genes` {smaller}`S Dicks` diff --git a/docs/release-notes/3180.feature.md b/docs/release-notes/3180.feature.md deleted file mode 100644 index ab73dfe18e..0000000000 --- a/docs/release-notes/3180.feature.md +++ /dev/null @@ -1 +0,0 @@ -Add support for `median` as an aggregation function to the `Aggregation` class in `scanpy.get._aggregated.py`. This allows for median-based aggregation of data (e.g., pseudobulk), complementing existing methods like mean- and sum-based aggregation {smaller}`M Dehkordi (Farhad)` diff --git a/docs/release-notes/3184.feature.md b/docs/release-notes/3184.feature.md deleted file mode 100644 index 3cc976b141..0000000000 --- a/docs/release-notes/3184.feature.md +++ /dev/null @@ -1 +0,0 @@ -Add `key_added` argument to {func}`~scanpy.pp.pca`, {func}`~scanpy.tl.tsne` and {func}`~scanpy.tl.umap` {smaller}`P Angerer` diff --git a/docs/release-notes/3263.feature.md b/docs/release-notes/3263.feature.md deleted file mode 100644 index 8e924e1799..0000000000 --- a/docs/release-notes/3263.feature.md +++ /dev/null @@ -1 +0,0 @@ -Support running {func}`scanpy.pp.pca` on sparse Dask arrays with the `'covariance_eigh'` solver {smaller}`P Angerer` diff --git a/docs/release-notes/3267.feature.md b/docs/release-notes/3267.feature.md deleted file mode 100644 index 6ea7fb20a2..0000000000 --- a/docs/release-notes/3267.feature.md +++ /dev/null @@ -1 +0,0 @@ -Use upstreamed {class}`~sklearn.decomposition.PCA` implementation for {class}`~scipy.sparse.csr_array` and {class}`~scipy.sparse.csr_matrix` (see {ref}`sklearn:changes_1_4`) {smaller}`P Angerer` diff --git a/docs/release-notes/3284.performance.md b/docs/release-notes/3284.performance.md deleted file mode 100644 index 31c95245ff..0000000000 --- a/docs/release-notes/3284.performance.md +++ /dev/null @@ -1 +0,0 @@ -* Speed up {func}`~scanpy.pp.regress_out` {smaller}`P Ashish, P Angerer & S Dicks` diff --git a/docs/release-notes/3296.feature.md b/docs/release-notes/3296.feature.md deleted file mode 100644 index 74b89945dd..0000000000 --- a/docs/release-notes/3296.feature.md +++ /dev/null @@ -1 +0,0 @@ -Add explicit support to {func}`scanpy.pp.pca` for `svd_solver='covariance_eigh'` {smaller}`P Angerer` diff --git a/docs/release-notes/3307.feature.md b/docs/release-notes/3307.feature.md deleted file mode 100644 index 1505befb40..0000000000 --- a/docs/release-notes/3307.feature.md +++ /dev/null @@ -1 +0,0 @@ -Add support {class}`dask.array.Array` to {func}`scanpy.pp.calculate_qc_metrics` {smaller}`I Gold` diff --git a/docs/release-notes/3324.feature.md b/docs/release-notes/3324.feature.md deleted file mode 100644 index 03d14dceb6..0000000000 --- a/docs/release-notes/3324.feature.md +++ /dev/null @@ -1 +0,0 @@ -Support `layer` parameter in {func}`scanpy.pl.highest_expr_genes` {smaller}`P Angerer` diff --git a/docs/release-notes/3335.feature.md b/docs/release-notes/3335.feature.md deleted file mode 100644 index 77a1723a8e..0000000000 --- a/docs/release-notes/3335.feature.md +++ /dev/null @@ -1 +0,0 @@ -Run numba functions single-threaded when called from inside of a ThreadPool {smaller}`P Angerer` diff --git a/docs/release-notes/3362.doc.md b/docs/release-notes/3362.doc.md deleted file mode 100644 index 1dae77b3e2..0000000000 --- a/docs/release-notes/3362.doc.md +++ /dev/null @@ -1 +0,0 @@ -Improve {func}`~scanpy.external.pp.harmony_integrate` docs {smaller}`D Kühl` diff --git a/docs/release-notes/3380.bugfix.md b/docs/release-notes/3380.bugfix.md deleted file mode 100644 index 633ce346af..0000000000 --- a/docs/release-notes/3380.bugfix.md +++ /dev/null @@ -1 +0,0 @@ -Raise {exc}`FutureWarning` when calling deprecated {mod}`scanpy.pp` functions {smaller}`P Angerer` diff --git a/docs/release-notes/3384.feature.md b/docs/release-notes/3384.feature.md deleted file mode 100644 index 755af9a8a3..0000000000 --- a/docs/release-notes/3384.feature.md +++ /dev/null @@ -1 +0,0 @@ -Switch {func}`~scanpy.logging.print_header` and {func}`~scanpy.logging.print_versions` to {mod}`session_info2` {smaller}`P Angerer` diff --git a/docs/release-notes/3393.bugfix.md b/docs/release-notes/3393.bugfix.md deleted file mode 100644 index 22af00f124..0000000000 --- a/docs/release-notes/3393.bugfix.md +++ /dev/null @@ -1 +0,0 @@ -Upper-bound {mod}`sklearn` `<1.6.0` due to {issue}`dask/dask-ml#1002` {smaller}`Ilan Gold` diff --git a/docs/release-notes/3407.misc.md b/docs/release-notes/3407.misc.md deleted file mode 100644 index 4670de6fd4..0000000000 --- a/docs/release-notes/3407.misc.md +++ /dev/null @@ -1,7 +0,0 @@ -| Deprecate … | in favor of … | -| --- | --- | -| {func}`scanpy.read_visium` | {func}`squidpy.read.visium` | -| {func}`scanpy.datasets.visium_sge` | {func}`squidpy.datasets.visium` | -| {func}`scanpy.pl.spatial` | {func}`squidpy.pl.spatial_scatter` | - -{smaller}`P Angerer` diff --git a/docs/release-notes/3410.feature.md b/docs/release-notes/3410.feature.md deleted file mode 100644 index d95ad201ba..0000000000 --- a/docs/release-notes/3410.feature.md +++ /dev/null @@ -1 +0,0 @@ -Add sampling probabilities/mask parameter `p` to {func}`~scanpy.pp.sample` {smaller}`P Angerer` diff --git a/docs/release-notes/943.feature.md b/docs/release-notes/943.feature.md deleted file mode 100644 index 4f5474d762..0000000000 --- a/docs/release-notes/943.feature.md +++ /dev/null @@ -1 +0,0 @@ -{func}`~scanpy.pp.sample` supports both upsampling and downsampling of observations and variables. {func}`~scanpy.pp.subsample` is now deprecated. {smaller}`G Eraslan` & {smaller}`P Angerer` From 9f22db24026b24a45254364691a0e27d84ff563f Mon Sep 17 00:00:00 2001 From: Phil Schaf Date: Fri, 20 Dec 2024 14:51:48 +0100 Subject: [PATCH 105/118] =?UTF-8?q?Note=20that=20it=E2=80=99s=20an=20rc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/release-notes/1.11.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/release-notes/1.11.0.md b/docs/release-notes/1.11.0.md index 8c51fe8a37..c7258ea271 100644 --- a/docs/release-notes/1.11.0.md +++ b/docs/release-notes/1.11.0.md @@ -1,5 +1,5 @@ (v1.11.0)= -### 1.11.0 {small}`2024-12-20` +### 1.11.0rc1 {small}`2024-12-20` ### Features From be9ae60438b8b1971537016de05e2f6cb0b54a3d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 9 Jan 2025 09:53:46 +0100 Subject: [PATCH 106/118] [pre-commit.ci] pre-commit autoupdate (#3404) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6c91285096..e891103226 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.8.2 + rev: v0.8.6 hooks: - id: ruff types_or: [python, pyi, jupyter] From e4dc24b4548d3078d648172efcd04db66b0a5a9f Mon Sep 17 00:00:00 2001 From: Dina Kazemi <50038942+dinakazemi@users.noreply.github.com> Date: Thu, 9 Jan 2025 21:10:39 +1100 Subject: [PATCH 107/118] Fix Markdown syntax for preprocessing docs page (#3418) Co-authored-by: Phil Schaf --- docs/api/preprocessing.md | 2 +- docs/api/tools.md | 2 ++ docs/release-notes/3418.doc.md | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 docs/release-notes/3418.doc.md diff --git a/docs/api/preprocessing.md b/docs/api/preprocessing.md index 36e732a6dc..1834d934a4 100644 --- a/docs/api/preprocessing.md +++ b/docs/api/preprocessing.md @@ -49,7 +49,7 @@ For visual quality control, see {func}`~scanpy.pl.highest_expr_genes` and ### Batch effect correction -Also see [Data integration]. Note that a simple batch correction method is available via {func}`pp.regress_out`. Checkout {mod}`scanpy.external` for more. +Also see {ref}`data-integration`. Note that a simple batch correction method is available via {func}`pp.regress_out`. Checkout {mod}`scanpy.external` for more. ```{eval-rst} .. autosummary:: diff --git a/docs/api/tools.md b/docs/api/tools.md index 1d51559e5a..13d82b46c7 100644 --- a/docs/api/tools.md +++ b/docs/api/tools.md @@ -48,6 +48,8 @@ Compute densities on embeddings. tl.paga ``` +(data-integration)= + ### Data integration ```{eval-rst} diff --git a/docs/release-notes/3418.doc.md b/docs/release-notes/3418.doc.md new file mode 100644 index 0000000000..d46304bf59 --- /dev/null +++ b/docs/release-notes/3418.doc.md @@ -0,0 +1 @@ +Fix reference in {mod}`scanpy.pp` page {smaller}`D Kazemi` From 49b54394a40f60f094530bb9c09e38560f8e0e2e Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 9 Jan 2025 15:34:47 +0100 Subject: [PATCH 108/118] Doc fixes for 1.11 (#3415) --- docs/release-notes/1.11.0.md | 8 ++++---- src/scanpy/preprocessing/_simple.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/release-notes/1.11.0.md b/docs/release-notes/1.11.0.md index c7258ea271..a41103e0ec 100644 --- a/docs/release-notes/1.11.0.md +++ b/docs/release-notes/1.11.0.md @@ -6,14 +6,14 @@ - {func}`~scanpy.pp.sample` supports both upsampling and downsampling of observations and variables. {func}`~scanpy.pp.subsample` is now deprecated. {smaller}`G Eraslan & P Angerer` ({pr}`943`) - Add `layer` argument to {func}`scanpy.tl.score_genes` and {func}`scanpy.tl.score_genes_cell_cycle` {smaller}`L Zappia` ({pr}`2921`) - Prevent `raw` conflict with `layer` in {func}`~scanpy.tl.score_genes` {smaller}`S Dicks` ({pr}`3155`) -- Add support for `median` as an aggregation function to the `Aggregation` class in `scanpy.get._aggregated.py`. This allows for median-based aggregation of data (e.g., pseudobulk), complementing existing methods like mean- and sum-based aggregation {smaller}`M Dehkordi (Farhad)` ({pr}`3180`) +- Add support for `median` as an aggregation function to {func}`~scanpy.get.aggregate`. This allows for median-based aggregation of data (e.g., pseudobulk), complementing existing methods like mean- and sum-based aggregation {smaller}`M Dehkordi (Farhad)` ({pr}`3180`) - Add `key_added` argument to {func}`~scanpy.pp.pca`, {func}`~scanpy.tl.tsne` and {func}`~scanpy.tl.umap` {smaller}`P Angerer` ({pr}`3184`) - Support running {func}`scanpy.pp.pca` on sparse Dask arrays with the `'covariance_eigh'` solver {smaller}`P Angerer` ({pr}`3263`) -- Use upstreamed {class}`~sklearn.decomposition.PCA` implementation for {class}`~scipy.sparse.csr_array` and {class}`~scipy.sparse.csr_matrix` (see {ref}`sklearn:changes_1_4`) {smaller}`P Angerer` ({pr}`3267`) +- Use upstreamed {class}`~sklearn.decomposition.PCA` implementation for {class}`~scipy.sparse.csr_array` and {class}`~scipy.sparse.csr_matrix` (see scikit-learn {ref}`sklearn:changes_1_4`) {smaller}`P Angerer` ({pr}`3267`) - Add explicit support to {func}`scanpy.pp.pca` for `svd_solver='covariance_eigh'` {smaller}`P Angerer` ({pr}`3296`) -- Add support {class}`dask.array.Array` to {func}`scanpy.pp.calculate_qc_metrics` {smaller}`I Gold` ({pr}`3307`) +- Add support for {class}`dask.array.Array` to {func}`scanpy.pp.calculate_qc_metrics` {smaller}`I Gold` ({pr}`3307`) - Support `layer` parameter in {func}`scanpy.pl.highest_expr_genes` {smaller}`P Angerer` ({pr}`3324`) -- Run numba functions single-threaded when called from inside of a ThreadPool {smaller}`P Angerer` ({pr}`3335`) +- Run numba functions single-threaded when called from inside of a {class}`~multiprocessing.pool.ThreadPool` {smaller}`P Angerer` ({pr}`3335`) - Switch {func}`~scanpy.logging.print_header` and {func}`~scanpy.logging.print_versions` to {mod}`session_info2` {smaller}`P Angerer` ({pr}`3384`) - Add sampling probabilities/mask parameter `p` to {func}`~scanpy.pp.sample` {smaller}`P Angerer` ({pr}`3410`) diff --git a/src/scanpy/preprocessing/_simple.py b/src/scanpy/preprocessing/_simple.py index b8ae00bd18..0c73d2c4e8 100644 --- a/src/scanpy/preprocessing/_simple.py +++ b/src/scanpy/preprocessing/_simple.py @@ -956,7 +956,7 @@ def sample( Rows correspond to cells and columns to genes. fraction Sample to this `fraction` of the number of observations or variables. - (All of them, even if there are `0`s/`False`s in `p`.) + (All of them, even if there are `0`\\ s/`False`\\ s in `p`.) This can be larger than 1.0, if `replace=True`. See `axis` and `replace`. n From 0d750f428d6ec7b4dc47fa2be766bce10319f88e Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 9 Jan 2025 15:43:16 +0100 Subject: [PATCH 109/118] Mention towncrier in contribution docs (#3427) --- docs/dev/code.md | 1 + docs/dev/documentation.md | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/dev/code.md b/docs/dev/code.md index 1e9d295725..3ca393c8f7 100644 --- a/docs/dev/code.md +++ b/docs/dev/code.md @@ -9,6 +9,7 @@ 5. {ref}`Make sure all tests are passing ` 6. {ref}`Build and visually check any changed documentation ` 7. {ref}`Open a PR back to the main repository ` +8. {ref}`Add a release note to your PR ` ## Code style diff --git a/docs/dev/documentation.md b/docs/dev/documentation.md index d9c3f6e034..dcad9533ed 100644 --- a/docs/dev/documentation.md +++ b/docs/dev/documentation.md @@ -12,10 +12,12 @@ Sometimes these caches are not invalidated when you've updated the docs. If docs are not updating the way you expect, first try "force reloading" your browser page – e.g. reload the page without using the cache. Next, if problems persist, clear the sphinx cache (`hatch run docs:clean`) and try building them again. +(adding-to-the-docs)= + ## Adding to the docs For any user-visible changes, please make sure a note has been added to the release notes using [`hatch run towncrier:create`][towncrier create]. -We recommend waiting on this until your PR is close to done since this can often causes merge conflicts. +When asked for “Issue number (`+` if none)”, enter the *PR number* instead. Once you've added a new function to the documentation, you'll need to make sure there is a link somewhere in the documentation site pointing to it. This should be added to `docs/api.md` under a relevant heading. From 765661ff1180a48ff9917fa9ecd25d11a0fd195a Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 9 Jan 2025 15:46:02 +0100 Subject: [PATCH 110/118] Fix wilcoxon for >10M cells (#3426) --- docs/release-notes/3426.bugfix.md | 1 + src/scanpy/tools/_rank_genes_groups.py | 11 +++++------ tests/test_rank_genes_groups.py | 7 +++++++ 3 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 docs/release-notes/3426.bugfix.md diff --git a/docs/release-notes/3426.bugfix.md b/docs/release-notes/3426.bugfix.md new file mode 100644 index 0000000000..4565f1ee35 --- /dev/null +++ b/docs/release-notes/3426.bugfix.md @@ -0,0 +1 @@ +Fix {func}`~scanpy.tl.rank_genes_groups` compatibility with data >10M cells {smaller}`P Angerer` diff --git a/src/scanpy/tools/_rank_genes_groups.py b/src/scanpy/tools/_rank_genes_groups.py index 2c214fcfdd..cafb78c6f1 100644 --- a/src/scanpy/tools/_rank_genes_groups.py +++ b/src/scanpy/tools/_rank_genes_groups.py @@ -2,7 +2,6 @@ from __future__ import annotations -from math import floor from typing import TYPE_CHECKING, Literal import numpy as np @@ -32,6 +31,8 @@ # Used with get_literal_vals _Method = Literal["logreg", "t-test", "wilcoxon", "t-test_overestim_var"] +_CONST_MAX_SIZE = 10000000 + def _select_top_n(scores: NDArray, n_top: int): n_from = scores.shape[0] @@ -47,9 +48,7 @@ def _ranks( X: np.ndarray | sparse.csr_matrix | sparse.csc_matrix, mask_obs: NDArray[np.bool_] | None = None, mask_obs_rest: NDArray[np.bool_] | None = None, -): - CONST_MAX_SIZE = 10000000 - +) -> Generator[tuple[pd.DataFrame, int, int], None, None]: n_genes = X.shape[1] if issparse(X): @@ -71,7 +70,7 @@ def _ranks( get_chunk = lambda X, left, right: adapt(X[:, left:right]) # Calculate chunk frames - max_chunk = floor(CONST_MAX_SIZE / n_cells) + max_chunk = max(_CONST_MAX_SIZE // n_cells, 1) for left in range(0, n_genes, max_chunk): right = min(left + max_chunk, n_genes) @@ -81,7 +80,7 @@ def _ranks( yield ranks, left, right -def _tiecorrect(ranks): +def _tiecorrect(ranks: pd.DataFrame) -> np.float64: size = np.float64(ranks.shape[0]) if size < 2: return np.repeat(ranks.shape[1], 1.0) diff --git a/tests/test_rank_genes_groups.py b/tests/test_rank_genes_groups.py index a36e6b14f1..788c7e705d 100644 --- a/tests/test_rank_genes_groups.py +++ b/tests/test_rank_genes_groups.py @@ -307,6 +307,13 @@ def test_wilcoxon_tie_correction(reference): np.testing.assert_allclose(test_obj.stats[groups[0]]["pvals"], pvals) +def test_wilcoxon_huge_data(monkeypatch): + max_size = 300 + adata = pbmc68k_reduced() + monkeypatch.setattr(sc.tl._rank_genes_groups, "_CONST_MAX_SIZE", max_size) + rank_genes_groups(adata, groupby="bulk_labels", method="wilcoxon") + + @pytest.mark.parametrize( ("n_genes_add", "n_genes_out_add"), [pytest.param(0, 0, id="equal"), pytest.param(2, 1, id="more")], From ca3dd8fcced40deaa9c48bf62d18806f59e6da7c Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 9 Jan 2025 16:01:16 +0100 Subject: [PATCH 111/118] Update author/maintainer metadata (#3413) --- docs/contributors.md | 19 +++++++++++-------- pyproject.toml | 10 ++++++---- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/docs/contributors.md b/docs/contributors.md index a9b2d79e3c..2e9c62d255 100644 --- a/docs/contributors.md +++ b/docs/contributors.md @@ -1,22 +1,25 @@ # Contributors [anndata graph](https://github.com/scverse/anndata/graphs/contributors>) | [scanpy graph](https://github.com/scverse/scanpy/graphs/contributors)| ☀ = maintainer + ## Current developers -- [Isaac Virshup](https://github.com/ivirshup), lead developer since 2019 ☀ -- [Gökcen Eraslan](https://twitter.com/gokcen), developer, diverse contributions ☀ -- [Sergei Rybakov](https://github.com/Koncopd), developer, diverse contributions ☀ -- [Fidel Ramirez](https://github.com/fidelram) developer, plotting ☀ -- [Giovanni Palla](https://twitter.com/g_palla1), developer, spatial data -- [Malte Luecken](https://twitter.com/MDLuecken), developer, community & forum +- [Philipp Angerer](https://github.com/flying-sheep), lead developer since 2023, software quality, initial anndata conception ☀ +- [Ilan Gold](https://github.com/ilan-gold), developer, Dask ☀ +- [Severin Dicks](https://github.com/SeverinDicks), developer, performance ☀ - [Lukas Heumos](https://twitter.com/LukasHeumos), developer, diverse contributions -- [Philipp Angerer](https://github.com/flying-sheep), developer, software quality, initial anndata conception ☀ ## Other roles +- [Isaac Virshup](https://github.com/ivirshup), lead developer 2019-2023 - [Alex Wolf](https://twitter.com/falexwolf): lead developer 2016-2019, initial anndata & scanpy conception - [Fabian Theis](https://twitter.com/fabian_theis) & lab: enabling guidance, support and environment ## Former developers -- Tom White: developer 2018-2019, distributed computing +- [Tom White](https://github.com/tomwhite): developer 2018-2019, distributed computing +- [Gökcen Eraslan](https://twitter.com/gokcen), developer, diverse contributions +- [Sergei Rybakov](https://github.com/Koncopd), developer, diverse contributions +- [Fidel Ramirez](https://github.com/fidelram) developer, plotting +- [Giovanni Palla](https://twitter.com/g_palla1), developer, spatial data +- [Malte Luecken](https://twitter.com/MDLuecken), developer, community & forum diff --git a/pyproject.toml b/pyproject.toml index 8e23afb14b..00f02ad27c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,9 +22,9 @@ authors = [ {name = "Andrés R. Muñoz-Rojas"}, ] maintainers = [ - {name = "Isaac Virshup", email = "ivirshup@gmail.com"}, {name = "Philipp Angerer", email = "phil.angerer@gmail.com"}, - {name = "Alex Wolf", email = "f.alex.wolf@gmx.de"}, + {name = "Ilan Gold"}, + {name = "Severin Dicks"}, ] readme = "README.md" classifiers = [ @@ -70,12 +70,14 @@ dependencies = [ ] dynamic = ["version"] +# https://docs.pypi.org/project_metadata/#project-urls [project.urls] Documentation = "https://scanpy.readthedocs.io/" Source = "https://github.com/scverse/scanpy" -Home-page = "https://scanpy.org" +Homepage = "https://scanpy.org" Discourse = "https://discourse.scverse.org/c/help/scanpy/37" -Twitter = "https://twitter.com/scverse_team" +Bluesky = "https://bsky.app/profile/scverse.bsky.social" +Twitter = "https://x.com/scverse_team" [project.scripts] scanpy = "scanpy.cli:console_main" From f9894b758d41dc8ae1db089bb2d2da9899e76a2c Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 10 Jan 2025 08:52:06 +0100 Subject: [PATCH 112/118] Formatting (#3414) Co-authored-by: Ilan Gold --- .gitignore | 1 - .pre-commit-config.yaml | 15 ++-- .taplo.toml | 5 ++ .vscode/launch.json | 26 ++++++ .vscode/settings.json | 22 +++++ biome.jsonc | 21 +++++ hatch.toml | 24 ++--- pyproject.toml | 90 +++++++++---------- .../1.0.0/spatial/scalefactors_json.json | 7 +- 9 files changed, 146 insertions(+), 65 deletions(-) create mode 100644 .taplo.toml create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 biome.jsonc diff --git a/.gitignore b/.gitignore index d21120ee95..65f9de7e0a 100644 --- a/.gitignore +++ b/.gitignore @@ -42,7 +42,6 @@ Thumbs.db # IDEs and editors /.idea/ -/.vscode/ # asv benchmark files /benchmarks/.asv diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e891103226..e87eb88663 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,14 +3,11 @@ repos: rev: v0.8.6 hooks: - id: ruff - types_or: [python, pyi, jupyter] args: ["--fix"] - id: ruff-format - types_or: [python, pyi, jupyter] # The following can be removed once PLR0917 is out of preview - name: ruff preview rules id: ruff - types_or: [python, pyi, jupyter] args: ["--preview", "--select=PLR0917"] - repo: https://github.com/flying-sheep/bibfmt rev: v4.3.0 @@ -19,6 +16,15 @@ repos: args: - --sort-by-bibkey - --drop=abstract +- repo: https://github.com/biomejs/pre-commit + rev: v0.6.1 + hooks: + - id: biome-format + additional_dependencies: ["@biomejs/biome@1.9.4"] +- repo: https://github.com/ComPWA/taplo-pre-commit + rev: v0.9.3 + hooks: + - id: taplo-format - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 hooks: @@ -34,6 +40,3 @@ repos: - id: detect-private-key - id: no-commit-to-branch args: ["--branch=main"] - -ci: - autofix_prs: false diff --git a/.taplo.toml b/.taplo.toml new file mode 100644 index 0000000000..41a6cdc5cc --- /dev/null +++ b/.taplo.toml @@ -0,0 +1,5 @@ +[formatting] +array_auto_collapse = false +column_width = 120 +compact_arrays = false +indent_string = ' ' diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..d87ef7c54f --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Build Documentation", + "type": "debugpy", + "request": "launch", + "module": "sphinx", + "args": ["-M", "html", ".", "_build"], + "cwd": "${workspaceFolder}/docs", + "console": "internalConsole", + "justMyCode": false, + }, + { + "name": "Python: Debug Test", + "type": "debugpy", + "request": "launch", + "program": "${file}", + "purpose": ["debug-test"], + "console": "internalConsole", + "justMyCode": false, + "env": { "PYTEST_ADDOPTS": "--color=yes" }, + "presentation": { "hidden": true }, + }, + ], +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000..ae719a4ec8 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,22 @@ +{ + "[python][toml][json][jsonc]": { + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.organizeImports": "explicit", + "source.fixAll": "explicit", + }, + }, + "[python]": { + "editor.defaultFormatter": "charliermarsh.ruff", + }, + "[toml]": { + "editor.defaultFormatter": "tamasfe.even-better-toml", + }, + "[json][jsonc]": { + "editor.defaultFormatter": "biomejs.biome", + }, + "python.analysis.typeCheckingMode": "basic", + "python.testing.pytestArgs": ["-vv", "--color=yes"], + "python.testing.pytestEnabled": true, + "python.terminal.activateEnvironment": true, +} diff --git a/biome.jsonc b/biome.jsonc new file mode 100644 index 0000000000..cf4a677503 --- /dev/null +++ b/biome.jsonc @@ -0,0 +1,21 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", + "formatter": { + "indentStyle": "space", + "indentWidth": 4, + }, + "overrides": [ + { + "include": ["./.vscode/*.json", "**/*.jsonc", "**/asv.conf.json"], + "json": { + "formatter": { + "trailingCommas": "all", + }, + "parser": { + "allowComments": true, + "allowTrailingCommas": true, + }, + }, + }, + ], +} diff --git a/hatch.toml b/hatch.toml index 3163d5d82d..b0a1084c61 100644 --- a/hatch.toml +++ b/hatch.toml @@ -1,9 +1,9 @@ [envs.default] installer = "uv" -features = ["dev"] +features = [ "dev" ] [envs.docs] -features = ["doc"] +features = [ "doc" ] scripts.build = "sphinx-build -M html docs docs/_build -W --keep-going {args}" scripts.open = "python3 -m webbrowser -t docs/_build/html/index.html" scripts.clean = "git clean -fdX -- {args:docs}" @@ -14,23 +14,23 @@ scripts.build = "python3 ci/scripts/towncrier_automation.py {args}" scripts.clean = "git restore --source=HEAD --staged --worktree -- docs/release-notes" [envs.hatch-test] -default-args = [] -features = ["test", "dask-ml"] -extra-dependencies = ["ipykernel"] +default-args = [ ] +features = [ "test", "dask-ml" ] +extra-dependencies = [ "ipykernel" ] overrides.matrix.deps.env-vars = [ - { if = ["pre"], key = "UV_PRERELEASE", value = "allow" }, - { if = ["min"], key = "UV_CONSTRAINT", value = "ci/scanpy-min-deps.txt" }, + { if = [ "pre" ], key = "UV_PRERELEASE", value = "allow" }, + { if = [ "min" ], key = "UV_CONSTRAINT", value = "ci/scanpy-min-deps.txt" }, ] overrides.matrix.deps.pre-install-commands = [ - { if = ["min"], value = "uv run ci/scripts/min-deps.py pyproject.toml --all-extras -o ci/scanpy-min-deps.txt" }, + { if = [ "min" ], value = "uv run ci/scripts/min-deps.py pyproject.toml --all-extras -o ci/scanpy-min-deps.txt" }, ] overrides.matrix.deps.python = [ - { if = ["min"], value = "3.10" }, - { if = ["stable", "full", "pre"], value = "3.12" }, + { if = [ "min" ], value = "3.10" }, + { if = [ "stable", "full", "pre" ], value = "3.12" }, ] overrides.matrix.deps.features = [ - { if = ["full"], value = "test-full" }, + { if = [ "full" ], value = "test-full" }, ] [[envs.hatch-test.matrix]] -deps = ["stable", "full", "pre", "min"] +deps = [ "stable", "full", "pre", "min" ] diff --git a/pyproject.toml b/pyproject.toml index 00f02ad27c..94654363e3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [build-system] build-backend = "hatchling.build" -requires = ["hatchling", "hatch-vcs"] +requires = [ "hatchling", "hatch-vcs" ] [project] name = "scanpy" @@ -8,23 +8,23 @@ description = "Single-Cell Analysis in Python." requires-python = ">=3.10" license = "BSD-3-clause" authors = [ - {name = "Alex Wolf"}, - {name = "Philipp Angerer"}, - {name = "Fidel Ramirez"}, - {name = "Isaac Virshup"}, - {name = "Sergei Rybakov"}, - {name = "Gokcen Eraslan"}, - {name = "Tom White"}, - {name = "Malte Luecken"}, - {name = "Davide Cittaro"}, - {name = "Tobias Callies"}, - {name = "Marius Lange"}, - {name = "Andrés R. Muñoz-Rojas"}, + { name = "Alex Wolf" }, + { name = "Philipp Angerer" }, + { name = "Fidel Ramirez" }, + { name = "Isaac Virshup" }, + { name = "Sergei Rybakov" }, + { name = "Gokcen Eraslan" }, + { name = "Tom White" }, + { name = "Malte Luecken" }, + { name = "Davide Cittaro" }, + { name = "Tobias Callies" }, + { name = "Marius Lange" }, + { name = "Andrés R. Muñoz-Rojas" }, ] maintainers = [ - {name = "Philipp Angerer", email = "phil.angerer@gmail.com"}, - {name = "Ilan Gold"}, - {name = "Severin Dicks"}, + { name = "Philipp Angerer", email = "phil.angerer@gmail.com" }, + { name = "Ilan Gold", email = "ilan.gold@helmholtz-munich.de" }, + { name = "Severin Dicks" }, ] readme = "README.md" classifiers = [ @@ -56,7 +56,7 @@ dependencies = [ "tqdm", "scikit-learn>=1.1,<1.6.0", "statsmodels>=0.13", - "patsy!=1.0.0", # https://github.com/pydata/patsy/issues/215 + "patsy!=1.0.0", # https://github.com/pydata/patsy/issues/215 "networkx>=2.7", "natsort", "joblib", @@ -65,10 +65,10 @@ dependencies = [ "pynndescent>=0.5", "packaging>=21.3", "session-info2", - "legacy-api-wrap>=1.4", # for positional API deprecations + "legacy-api-wrap>=1.4", # for positional API deprecations "typing-extensions; python_version < '3.13'", ] -dynamic = ["version"] +dynamic = [ "version" ] # https://docs.pypi.org/project_metadata/#project-urls [project.urls] @@ -120,13 +120,13 @@ doc = [ "sphinx-design", "sphinx-tabs", "readthedocs-sphinx-search", - "sphinxext-opengraph", # for nice cards when sharing on social + "sphinxext-opengraph", # for nice cards when sharing on social "sphinx-copybutton", "nbsphinx>=0.9", - "ipython>=7.20", # for nbsphinx code highlighting + "ipython>=7.20", # for nbsphinx code highlighting "matplotlib!=3.6.1", "sphinxcontrib-bibtex", - "setuptools", # undeclared dependency of sphinxcontrib-bibtex→pybtex + "setuptools", # undeclared dependency of sphinxcontrib-bibtex→pybtex # TODO: remove necessity for being able to import doc-linked classes "scanpy[paga,dask-ml]", "sam-algorithm", @@ -139,22 +139,22 @@ dev = [ "towncrier", ] # Algorithms -paga = ["igraph"] -louvain = ["igraph", "louvain>=0.6.0,!=0.6.2"] # Louvain community detection -leiden = ["igraph>=0.10", "leidenalg>=0.9.0"] # Leiden community detection -bbknn = ["bbknn"] # Batch balanced KNN (batch correction) -magic = ["magic-impute>=2.0"] # MAGIC imputation method -skmisc = ["scikit-misc>=0.1.3"] # highly_variable_genes method 'seurat_v3' -harmony = ["harmonypy"] # Harmony dataset integration -scanorama = ["scanorama"] # Scanorama dataset integration -scrublet = ["scikit-image"] # Doublet detection with automatic thresholds +paga = [ "igraph" ] +louvain = [ "igraph", "louvain>=0.6.0,!=0.6.2" ] # Louvain community detection +leiden = [ "igraph>=0.10", "leidenalg>=0.9.0" ] # Leiden community detection +bbknn = [ "bbknn" ] # Batch balanced KNN (batch correction) +magic = [ "magic-impute>=2.0" ] # MAGIC imputation method +skmisc = [ "scikit-misc>=0.1.3" ] # highly_variable_genes method 'seurat_v3' +harmony = [ "harmonypy" ] # Harmony dataset integration +scanorama = [ "scanorama" ] # Scanorama dataset integration +scrublet = [ "scikit-image" ] # Doublet detection with automatic thresholds # Acceleration -rapids = ["cudf>=0.9", "cuml>=0.9", "cugraph>=0.9"] # GPU accelerated calculation of neighbors -dask = ["dask[array]>=2022.09.2,<2024.8.0"] # Use the Dask parallelization engine -dask-ml = ["dask-ml", "scanpy[dask]"] # Dask-ML for sklearn-like API +rapids = [ "cudf>=0.9", "cuml>=0.9", "cugraph>=0.9" ] # GPU accelerated calculation of neighbors +dask = [ "dask[array]>=2022.09.2,<2024.8.0" ] # Use the Dask parallelization engine +dask-ml = [ "dask-ml", "scanpy[dask]" ] # Dask-ML for sklearn-like API [tool.hatch.build.targets.wheel] -packages = ["src/testing", "src/scanpy"] +packages = [ "src/testing", "src/scanpy" ] [tool.hatch.version] source = "vcs" raw-options.version_scheme = "release-branch-semver" @@ -169,8 +169,8 @@ addopts = [ "-ptesting.scanpy._pytest", "--pyargs", ] -testpaths = ["./tests", "./ci", "scanpy"] -norecursedirs = ["tests/_images"] +testpaths = [ "./tests", "./ci", "scanpy" ] +norecursedirs = [ "tests/_images" ] xfail_strict = true nunit_attach_on = "fail" markers = [ @@ -203,12 +203,12 @@ filterwarnings = [ [tool.coverage.run] data_file = "test-data/coverage" -source_pkgs = ["scanpy"] -omit = ["tests/*", "src/testing/*"] +source_pkgs = [ "scanpy" ] +omit = [ "tests/*", "src/testing/*" ] [tool.coverage.xml] output = "test-data/coverage.xml" [tool.coverage.paths] -source = [".", "**/site-packages"] +source = [ ".", "**/site-packages" ] [tool.coverage.report] exclude_also = [ "if __name__ == .__main__.:", @@ -218,7 +218,7 @@ exclude_also = [ ] [tool.ruff] -src = ["src"] +src = [ "src" ] [tool.ruff.format] docstring-code-format = true @@ -254,10 +254,10 @@ ignore = [ ] [tool.ruff.lint.per-file-ignores] # Do not assign a lambda expression, use a def -"src/scanpy/tools/_rank_genes_groups.py" = ["E731"] +"src/scanpy/tools/_rank_genes_groups.py" = [ "E731" ] [tool.ruff.lint.isort] -known-first-party = ["scanpy", "testing.scanpy"] -required-imports = ["from __future__ import annotations"] +known-first-party = [ "scanpy", "testing.scanpy" ] +required-imports = [ "from __future__ import annotations" ] [tool.ruff.lint.flake8-tidy-imports.banned-api] "pytest.importorskip".msg = "Use the “@needs” decorator/mark instead" "pandas.api.types.is_categorical_dtype".msg = "Use isinstance(s.dtype, CategoricalDtype) instead" @@ -267,7 +267,7 @@ required-imports = ["from __future__ import annotations"] "numba.jit".msg = "Use `scanpy._compat.njit` instead" "numba.njit".msg = "Use `scanpy._compat.njit` instead" [tool.ruff.lint.flake8-type-checking] -exempt-modules = [] +exempt-modules = [ ] strict = true [tool.towncrier] diff --git a/tests/_data/visium_data/1.0.0/spatial/scalefactors_json.json b/tests/_data/visium_data/1.0.0/spatial/scalefactors_json.json index 9f47f51518..5479b589c0 100644 --- a/tests/_data/visium_data/1.0.0/spatial/scalefactors_json.json +++ b/tests/_data/visium_data/1.0.0/spatial/scalefactors_json.json @@ -1 +1,6 @@ -{"spot_diameter_fullres": 89.42751063343188, "tissue_hires_scalef": 0.150015, "fiducial_diameter_fullres": 144.45982486939, "tissue_lowres_scalef": 0.045004502} \ No newline at end of file +{ + "spot_diameter_fullres": 89.42751063343188, + "tissue_hires_scalef": 0.150015, + "fiducial_diameter_fullres": 144.45982486939, + "tissue_lowres_scalef": 0.045004502 +} From 723a246dfcdc27d47d5fad3262b50cda1a95fdab Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 10 Jan 2025 15:25:02 +0100 Subject: [PATCH 113/118] (chore) upper bound zarr version in tests to <3 (#3432) --- benchmarks/asv.conf.json | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/benchmarks/asv.conf.json b/benchmarks/asv.conf.json index 98192b3725..404e0b83dd 100644 --- a/benchmarks/asv.conf.json +++ b/benchmarks/asv.conf.json @@ -78,7 +78,7 @@ "natsort": [""], "pandas": [""], "memory_profiler": [""], - "zarr": [""], + "zarr": ["2.18.4"], "pytest": [""], "scanpy": [""], "python-igraph": [""], diff --git a/pyproject.toml b/pyproject.toml index 94654363e3..cd26d2f9a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,7 +94,7 @@ test = [ "scanpy[test-min]", # Optional but important dependencies "scanpy[leiden]", - "zarr", + "zarr<3", "scanpy[dask]", "scanpy[scrublet]", ] From 30f83d876224ae74e89d32ba6cafd179c4ba724f Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Mon, 13 Jan 2025 10:36:35 +0100 Subject: [PATCH 114/118] Fix flaky doublet test (#3436) --- tests/external/test_hashsolo.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tests/external/test_hashsolo.py b/tests/external/test_hashsolo.py index a6f0a79971..d338d1b6ec 100644 --- a/tests/external/test_hashsolo.py +++ b/tests/external/test_hashsolo.py @@ -1,6 +1,7 @@ from __future__ import annotations import numpy as np +import pandas as pd from anndata import AnnData import scanpy.external as sce @@ -27,9 +28,11 @@ def test_cell_demultiplexing(): sce.pp.hashsolo(test_data, test_data.obs.columns) doublets = ["Doublet"] * 10 - classes = list( - np.repeat(np.arange(10), 98).reshape(98, 10, order="F").ravel().astype(str) - ) + classes = np.repeat(np.arange(10), 98).reshape(98, 10, order="F").ravel().tolist() negatives = ["Negative"] * 10 - classification = doublets + classes + negatives - assert test_data.obs["Classification"].astype(str).tolist() == classification + expected = pd.array(doublets + classes + negatives, dtype="string") + classification = test_data.obs["Classification"].array.astype("string") + # This is a bit flaky, so allow some mismatches: + if (expected != classification).sum() > 3: + # Compare lists for better error message + assert classification.tolist() == expected.tolist() From 1c0afeef1d86bd6528e15b03f88fa0baf2882761 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Mon, 13 Jan 2025 13:00:01 +0100 Subject: [PATCH 115/118] (chore): Update to Ruff 0.9 and add EM lints (#3437) --- .pre-commit-config.yaml | 2 +- ci/scripts/min-deps.py | 4 +- docs/extensions/param_police.py | 3 +- pyproject.toml | 3 +- src/scanpy/__init__.py | 5 +- src/scanpy/_settings.py | 12 ++- src/scanpy/_utils/__init__.py | 77 ++++++++------- src/scanpy/_utils/_doctests.py | 3 +- src/scanpy/_utils/compute/is_constant.py | 6 +- .../experimental/pp/_highly_variable_genes.py | 17 ++-- src/scanpy/experimental/pp/_normalization.py | 9 +- src/scanpy/external/exporting.py | 8 +- src/scanpy/external/pl.py | 5 +- src/scanpy/external/pp/_bbknn.py | 3 +- src/scanpy/external/pp/_dca.py | 3 +- src/scanpy/external/pp/_harmony_integrate.py | 3 +- src/scanpy/external/pp/_hashsolo.py | 8 +- src/scanpy/external/pp/_magic.py | 12 ++- src/scanpy/external/pp/_mnn_correct.py | 6 +- .../external/pp/_scanorama_integrate.py | 6 +- src/scanpy/external/tl/_harmony_timeseries.py | 6 +- src/scanpy/external/tl/_palantir.py | 3 +- src/scanpy/external/tl/_phate.py | 5 +- src/scanpy/external/tl/_phenograph.py | 6 +- src/scanpy/external/tl/_pypairs.py | 6 +- src/scanpy/external/tl/_sam.py | 3 +- src/scanpy/external/tl/_trimap.py | 6 +- src/scanpy/external/tl/_wishbone.py | 11 ++- src/scanpy/get/_aggregated.py | 18 ++-- src/scanpy/get/get.py | 33 ++++--- src/scanpy/logging.py | 2 +- src/scanpy/metrics/_gearys_c.py | 3 +- src/scanpy/metrics/_morans_i.py | 3 +- src/scanpy/neighbors/__init__.py | 20 ++-- src/scanpy/plotting/_anndata.py | 97 +++++++++++-------- src/scanpy/plotting/_baseplot_class.py | 16 ++- src/scanpy/plotting/_dotplot.py | 10 +- src/scanpy/plotting/_scrublet.py | 5 +- src/scanpy/plotting/_stacked_violin.py | 2 +- src/scanpy/plotting/_tools/__init__.py | 53 +++++----- src/scanpy/plotting/_tools/paga.py | 41 +++++--- src/scanpy/plotting/_tools/scatterplots.py | 50 ++++++---- src/scanpy/plotting/_utils.py | 37 ++++--- src/scanpy/preprocessing/_combat.py | 14 +-- .../preprocessing/_deprecated/__init__.py | 3 +- .../_deprecated/highly_variable_genes.py | 6 +- .../preprocessing/_highly_variable_genes.py | 19 ++-- src/scanpy/preprocessing/_normalization.py | 14 +-- src/scanpy/preprocessing/_pca/__init__.py | 15 ++- src/scanpy/preprocessing/_qc.py | 8 +- src/scanpy/preprocessing/_recipes.py | 3 +- src/scanpy/preprocessing/_scale.py | 12 +-- .../preprocessing/_scrublet/pipeline.py | 6 +- src/scanpy/preprocessing/_simple.py | 37 ++++--- src/scanpy/preprocessing/_utils.py | 3 +- src/scanpy/queries/_queries.py | 16 +-- src/scanpy/readwrite.py | 77 +++++++++------ src/scanpy/tools/_dendrogram.py | 8 +- src/scanpy/tools/_diffmap.py | 8 +- src/scanpy/tools/_dpt.py | 20 ++-- src/scanpy/tools/_draw_graph.py | 3 +- src/scanpy/tools/_embedding_density.py | 12 ++- src/scanpy/tools/_ingest.py | 22 +++-- src/scanpy/tools/_leiden.py | 20 ++-- src/scanpy/tools/_louvain.py | 8 +- src/scanpy/tools/_marker_gene_overlap.py | 21 ++-- src/scanpy/tools/_paga.py | 22 +++-- src/scanpy/tools/_rank_genes_groups.py | 26 +++-- src/scanpy/tools/_score_genes.py | 14 +-- src/scanpy/tools/_sim.py | 36 +++---- src/scanpy/tools/_umap.py | 8 +- src/scanpy/tools/_utils.py | 16 +-- src/scanpy/tools/_utils_clustering.py | 8 +- src/testing/scanpy/_pytest/__init__.py | 9 +- tests/conftest.py | 3 +- tests/external/test_wishbone.py | 6 +- tests/test_dendrogram.py | 2 +- tests/test_get.py | 2 +- tests/test_highly_variable_genes.py | 3 +- tests/test_normalization.py | 12 +-- tests/test_rank_genes_groups.py | 14 ++- 81 files changed, 662 insertions(+), 505 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e87eb88663..c5e0e91d8c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.8.6 + rev: v0.9.1 hooks: - id: ruff args: ["--fix"] diff --git a/ci/scripts/min-deps.py b/ci/scripts/min-deps.py index 0d49d151ef..4efc304cb6 100755 --- a/ci/scripts/min-deps.py +++ b/ci/scripts/min-deps.py @@ -71,7 +71,9 @@ def extract_min_deps( # If we are referring to other optional dependency lists, resolve them if req.name == project_name: - assert req.extras, f"Project included itself as dependency, without specifying extras: {req}" + assert req.extras, ( + f"Project included itself as dependency, without specifying extras: {req}" + ) for extra in req.extras: extra_deps = pyproject["project"]["optional-dependencies"][extra] dependencies += map(Requirement, extra_deps) diff --git a/docs/extensions/param_police.py b/docs/extensions/param_police.py index 37942d3687..234ad28e62 100644 --- a/docs/extensions/param_police.py +++ b/docs/extensions/param_police.py @@ -37,7 +37,8 @@ def show_param_warnings(app, exception): line, ) if param_warnings: - raise RuntimeError("Encountered text parameter type. Use annotations.") + msg = "Encountered text parameter type. Use annotations." + raise RuntimeError(msg) def setup(app: Sphinx): diff --git a/pyproject.toml b/pyproject.toml index cd26d2f9a2..71f7f1c482 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -230,7 +230,7 @@ select = [ "W", # Warning detected by Pycodestyle "UP", # pyupgrade "I", # isort - "TCH", # manage type checking blocks + "TC", # manage type checking blocks "TID251", # Banned imports "ICN", # Follow import conventions "PTH", # Pathlib instead of os.path @@ -239,6 +239,7 @@ select = [ "FBT", # No positional boolean parameters "PT", # Pytest style "SIM", # Simplify control flow + "EM", # Traceback-friendly error messages ] ignore = [ # line too long -> we accept long comment lines; black gets rid of long code lines diff --git a/src/scanpy/__init__.py b/src/scanpy/__init__.py index bbcc86437b..b844372d1e 100644 --- a/src/scanpy/__init__.py +++ b/src/scanpy/__init__.py @@ -15,9 +15,8 @@ try: from ._version import __version__ except ModuleNotFoundError: - raise RuntimeError( - "scanpy is not correctly installed. Please install it, e.g. with pip." - ) + msg = "scanpy is not correctly installed. Please install it, e.g. with pip." + raise RuntimeError(msg) from ._utils import check_versions diff --git a/src/scanpy/_settings.py b/src/scanpy/_settings.py index 5543689ef7..fc9ead09b0 100644 --- a/src/scanpy/_settings.py +++ b/src/scanpy/_settings.py @@ -83,7 +83,8 @@ def _type_check(var: Any, varname: str, types: type | tuple[type, ...]): else: type_names = [t.__name__ for t in types] possible_types_str = f"{', '.join(type_names[:-1])} or {type_names[-1]}" - raise TypeError(f"{varname} must be of type {possible_types_str}") + msg = f"{varname} must be of type {possible_types_str}" + raise TypeError(msg) class ScanpyConfig: @@ -180,10 +181,11 @@ def verbosity(self, verbosity: Verbosity | int | str): elif isinstance(verbosity, str): verbosity = verbosity.lower() if verbosity not in verbosity_str_options: - raise ValueError( + msg = ( f"Cannot set verbosity to {verbosity}. " f"Accepted string values are: {verbosity_str_options}" ) + raise ValueError(msg) else: self._verbosity = Verbosity(verbosity_str_options.index(verbosity)) else: @@ -214,10 +216,11 @@ def file_format_data(self, file_format: str): _type_check(file_format, "file_format_data", str) file_format_options = {"txt", "csv", "h5ad"} if file_format not in file_format_options: - raise ValueError( + msg = ( f"Cannot set file_format_data to {file_format}. " f"Must be one of {file_format_options}" ) + raise ValueError(msg) self._file_format_data = file_format @property @@ -322,10 +325,11 @@ def cache_compression(self) -> str | None: @cache_compression.setter def cache_compression(self, cache_compression: str | None): if cache_compression not in {"lzf", "gzip", None}: - raise ValueError( + msg = ( f"`cache_compression` ({cache_compression}) " "must be in {'lzf', 'gzip', None}" ) + raise ValueError(msg) self._cache_compression = cache_compression @property diff --git a/src/scanpy/_utils/__init__.py b/src/scanpy/_utils/__init__.py index 67e2ae03c8..326ea216d1 100644 --- a/src/scanpy/_utils/__init__.py +++ b/src/scanpy/_utils/__init__.py @@ -93,11 +93,12 @@ def __getattr__(self, attr: str): def ensure_igraph() -> None: if importlib.util.find_spec("igraph"): return - raise ImportError( + msg = ( "Please install the igraph package: " "`conda install -c conda-forge python-igraph` or " "`pip3 install igraph`." ) + raise ImportError(msg) @contextmanager @@ -120,10 +121,11 @@ def check_versions(): if Version(anndata_version) < Version("0.6.10"): from .. import __version__ - raise ImportError( + msg = ( f"Scanpy {__version__} needs anndata version >=0.6.10, " f"not {anndata_version}.\nRun `pip install anndata -U --no-deps`." ) + raise ImportError(msg) def getdoc(c_or_f: Callable | type) -> str | None: @@ -195,7 +197,8 @@ def _import_name(name: str) -> Any: try: obj = getattr(obj, name) except AttributeError: - raise RuntimeError(f"{parts[:i]}, {parts[i + 1:]}, {obj} {name}") + msg = f"{parts[:i]}, {parts[i + 1 :]}, {obj} {name}" + raise RuntimeError(msg) return obj @@ -255,9 +258,8 @@ def _check_array_function_arguments(**kwargs): # TODO: Figure out a better solution for documenting dispatched functions invalid_args = [k for k, v in kwargs.items() if v is not None] if len(invalid_args) > 0: - raise TypeError( - f"Arguments {invalid_args} are only valid if an AnnData object is passed." - ) + msg = f"Arguments {invalid_args} are only valid if an AnnData object is passed." + raise TypeError(msg) def _check_use_raw( @@ -350,16 +352,14 @@ def compute_association_matrix_of_groups( reference labels, entries are proportional to degree of association. """ if normalization not in {"prediction", "reference"}: - raise ValueError( - '`normalization` needs to be either "prediction" or "reference".' - ) + msg = '`normalization` needs to be either "prediction" or "reference".' + raise ValueError(msg) sanitize_anndata(adata) cats = adata.obs[reference].cat.categories for cat in cats: if cat in settings.categories_to_ignore: logg.info( - f"Ignoring category {cat!r} " - "as it’s in `settings.categories_to_ignore`." + f"Ignoring category {cat!r} as it’s in `settings.categories_to_ignore`." ) asso_names: list[str] = [] asso_matrix: list[list[float]] = [] @@ -604,7 +604,8 @@ def broadcast_axis(divisor: Scaling_T, axis: Literal[0, 1]) -> Scaling_T: def check_op(op): if op not in {truediv, mul}: - raise ValueError(f"{op} not one of truediv or mul") + msg = f"{op} not one of truediv or mul" + raise ValueError(msg) @singledispatch @@ -639,9 +640,8 @@ def _( ) -> sparse.csr_matrix | sparse.csc_matrix: check_op(op) if out is not None and X.data is not out.data: - raise ValueError( - "`out` argument provided but not equal to X. This behavior is not supported for sparse matrix scaling." - ) + msg = "`out` argument provided but not equal to X. This behavior is not supported for sparse matrix scaling." + raise ValueError(msg) if not allow_divide_by_zero and op is truediv: scaling_array = scaling_array.copy() + (scaling_array == 0) @@ -697,9 +697,8 @@ def _( ) -> DaskArray: check_op(op) if out is not None: - raise TypeError( - "`out` is not `None`. Do not do in-place modifications on dask arrays." - ) + msg = "`out` is not `None`. Do not do in-place modifications on dask arrays." + raise TypeError(msg) import dask.array as da @@ -805,9 +804,8 @@ def sum_drop_keepdims(*args, **kwargs): axis = kwargs["axis"] if isinstance(axis, tuple): if len(axis) != 1: - raise ValueError( - f"`axis_sum` can only sum over one axis when `axis` arg is provided but got {axis} instead" - ) + msg = f"`axis_sum` can only sum over one axis when `axis` arg is provided but got {axis} instead" + raise ValueError(msg) kwargs["axis"] = axis[0] # returns a np.matrix normally, which is undesireable return np.array(np.sum(*args, dtype=dtype, **kwargs)) @@ -959,7 +957,8 @@ def subsample( Xsampled = np.array(X[rows]) else: if seed < 0: - raise ValueError(f"Invalid seed value < 0: {seed}") + msg = f"Invalid seed value < 0: {seed}" + raise ValueError(msg) n = int(X.shape[0] / subsample) np.random.seed(seed) Xsampled, rows = subsample_n(X, n=n) @@ -989,7 +988,8 @@ def subsample_n( Indices of rows that are stored in Xsampled. """ if n < 0: - raise ValueError("n must be greater 0") + msg = "n must be greater 0" + raise ValueError(msg) np.random.seed(seed) n = X.shape[0] if (n == 0 or n > X.shape[0]) else n rows = np.random.choice(X.shape[0], size=n, replace=False) @@ -1069,13 +1069,15 @@ def __init__(self, adata: AnnData, key=None): if key is None or key == "neighbors": if "neighbors" not in adata.uns: - raise KeyError('No "neighbors" in .uns') + msg = 'No "neighbors" in .uns' + raise KeyError(msg) self._neighbors_dict = adata.uns["neighbors"] self._conns_key = "connectivities" self._dists_key = "distances" else: if key not in adata.uns: - raise KeyError(f'No "{key}" in .uns') + msg = f"No {key!r} in .uns" + raise KeyError(msg) self._neighbors_dict = adata.uns[key] self._conns_key = self._neighbors_dict["connectivities_key"] self._dists_key = self._neighbors_dict["distances_key"] @@ -1108,11 +1110,13 @@ def __getitem__(self, key: Literal["connectivities_key"]) -> str: ... def __getitem__(self, key: str): if key == "distances": if "distances" not in self: - raise KeyError(f'No "{self._dists_key}" in .obsp') + msg = f"No {self._dists_key!r} in .obsp" + raise KeyError(msg) return self._distances elif key == "connectivities": if "connectivities" not in self: - raise KeyError(f'No "{self._conns_key}" in .obsp') + msg = f"No {self._conns_key!r} in .obsp" + raise KeyError(msg) return self._connectivities elif key == "connectivities_key": return self._conns_key @@ -1131,19 +1135,18 @@ def __contains__(self, key: str) -> bool: def _choose_graph(adata, obsp, neighbors_key): """Choose connectivities from neighbbors or another obsp column""" if obsp is not None and neighbors_key is not None: - raise ValueError( - "You can't specify both obsp, neighbors_key. " "Please select only one." - ) + msg = "You can't specify both obsp, neighbors_key. Please select only one." + raise ValueError(msg) if obsp is not None: return adata.obsp[obsp] else: neighbors = NeighborsView(adata, neighbors_key) if "connectivities" not in neighbors: - raise ValueError( - "You need to run `pp.neighbors` first " - "to compute a neighborhood graph." + msg = ( + "You need to run `pp.neighbors` first to compute a neighborhood graph." ) + raise ValueError(msg) return neighbors["connectivities"] @@ -1154,7 +1157,8 @@ def _resolve_axis( return (0, "obs") if axis in {1, "var"}: return (1, "var") - raise ValueError(f"`axis` must be either 0, 1, 'obs', or 'var', was {axis!r}") + msg = f"`axis` must be either 0, 1, 'obs', or 'var', was {axis!r}" + raise ValueError(msg) def is_backed_type(X: object) -> bool: @@ -1163,6 +1167,5 @@ def is_backed_type(X: object) -> bool: def raise_not_implemented_error_if_backed_type(X: object, method_name: str) -> None: if is_backed_type(X): - raise NotImplementedError( - f"{method_name} is not implemented for matrices of type {type(X)}" - ) + msg = f"{method_name} is not implemented for matrices of type {type(X)}" + raise NotImplementedError(msg) diff --git a/src/scanpy/_utils/_doctests.py b/src/scanpy/_utils/_doctests.py index 6a08099a24..0b3be18bbe 100644 --- a/src/scanpy/_utils/_doctests.py +++ b/src/scanpy/_utils/_doctests.py @@ -19,7 +19,8 @@ def decorator(func: F) -> F: def doctest_skip(reason: str) -> Callable[[F], F]: """Mark function so doctest is skipped.""" if not reason: - raise ValueError("reason must not be empty") + msg = "reason must not be empty" + raise ValueError(msg) def decorator(func: F) -> F: func._doctest_skip_reason = reason diff --git a/src/scanpy/_utils/compute/is_constant.py b/src/scanpy/_utils/compute/is_constant.py index 1bc147d68e..c9fac4abf0 100644 --- a/src/scanpy/_utils/compute/is_constant.py +++ b/src/scanpy/_utils/compute/is_constant.py @@ -24,9 +24,11 @@ def _check_axis_supported(wrapped: C) -> C: def func(a, axis=None): if axis is not None: if not isinstance(axis, Integral): - raise TypeError("axis must be integer or None.") + msg = "axis must be integer or None." + raise TypeError(msg) if axis not in (0, 1): - raise NotImplementedError("We only support axis 0 and 1 at the moment") + msg = "We only support axis 0 and 1 at the moment" + raise NotImplementedError(msg) return wrapped(a, axis) return func diff --git a/src/scanpy/experimental/pp/_highly_variable_genes.py b/src/scanpy/experimental/pp/_highly_variable_genes.py index ab78f0a74a..7ad9f36bd7 100644 --- a/src/scanpy/experimental/pp/_highly_variable_genes.py +++ b/src/scanpy/experimental/pp/_highly_variable_genes.py @@ -159,7 +159,8 @@ def _highly_variable_pearson_residuals( if theta <= 0: # TODO: would "underdispersion" with negative theta make sense? # then only theta=0 were undefined.. - raise ValueError("Pearson residuals require theta > 0") + msg = "Pearson residuals require theta > 0" + raise ValueError(msg) # prepare clipping if batch_key is None: @@ -185,7 +186,8 @@ def _highly_variable_pearson_residuals( n = X_batch.shape[0] clip = np.sqrt(n) if clip < 0: - raise ValueError("Pearson residuals require `clip>=0` or `clip=None`.") + msg = "Pearson residuals require `clip>=0` or `clip=None`." + raise ValueError(msg) if sp_sparse.issparse(X_batch): X_batch = X_batch.tocsc() @@ -378,17 +380,19 @@ def highly_variable_genes( logg.info("extracting highly variable genes") if not isinstance(adata, AnnData): - raise ValueError( + msg = ( "`pp.highly_variable_genes` expects an `AnnData` argument, " "pass `inplace=False` if you want to return a `pd.DataFrame`." ) + raise ValueError(msg) if flavor == "pearson_residuals": if n_top_genes is None: - raise ValueError( + msg = ( "`pp.highly_variable_genes` requires the argument `n_top_genes`" " for `flavor='pearson_residuals'`" ) + raise ValueError(msg) return _highly_variable_pearson_residuals( adata, layer=layer, @@ -402,6 +406,5 @@ def highly_variable_genes( inplace=inplace, ) else: - raise ValueError( - "This is an experimental API and only `flavor=pearson_residuals` is available." - ) + msg = "This is an experimental API and only `flavor=pearson_residuals` is available." + raise ValueError(msg) diff --git a/src/scanpy/experimental/pp/_normalization.py b/src/scanpy/experimental/pp/_normalization.py index bc4dedbaf9..ef3d0311d7 100644 --- a/src/scanpy/experimental/pp/_normalization.py +++ b/src/scanpy/experimental/pp/_normalization.py @@ -42,13 +42,15 @@ def _pearson_residuals(X, theta, clip, check_values, *, copy: bool = False): if theta <= 0: # TODO: would "underdispersion" with negative theta make sense? # then only theta=0 were undefined.. - raise ValueError("Pearson residuals require theta > 0") + msg = "Pearson residuals require theta > 0" + raise ValueError(msg) # prepare clipping if clip is None: n = X.shape[0] clip = np.sqrt(n) if clip < 0: - raise ValueError("Pearson residuals require `clip>=0` or `clip=None`.") + msg = "Pearson residuals require `clip>=0` or `clip=None`." + raise ValueError(msg) if check_values and not check_nonnegative_integers(X): warn( @@ -128,7 +130,8 @@ def normalize_pearson_residuals( if copy: if not inplace: - raise ValueError("`copy=True` cannot be used with `inplace=False`.") + msg = "`copy=True` cannot be used with `inplace=False`." + raise ValueError(msg) adata = adata.copy() view_to_actual(adata) diff --git a/src/scanpy/external/exporting.py b/src/scanpy/external/exporting.py index 9364b7d368..8379720ea6 100644 --- a/src/scanpy/external/exporting.py +++ b/src/scanpy/external/exporting.py @@ -86,7 +86,8 @@ def spring_project( neighbors_key = "neighbors" if neighbors_key not in adata.uns: - raise ValueError("Run `sc.pp.neighbors` first.") + msg = "Run `sc.pp.neighbors` first." + raise ValueError(msg) # check that requested 2-D embedding has been generated if embedding_method not in adata.obsm_keys(): @@ -101,9 +102,8 @@ def spring_project( + adata.uns[embedding_method]["params"]["layout"] ) else: - raise ValueError( - f"Run the specified embedding method `{embedding_method}` first." - ) + msg = f"Run the specified embedding method `{embedding_method}` first." + raise ValueError(msg) coords = adata.obsm[embedding_method] diff --git a/src/scanpy/external/pl.py b/src/scanpy/external/pl.py index a6ad48f718..ce305e2f06 100644 --- a/src/scanpy/external/pl.py +++ b/src/scanpy/external/pl.py @@ -198,9 +198,8 @@ def sam( try: dt = adata.obsm[projection] except KeyError: - raise ValueError( - "Please create a projection first using run_umap or run_tsne" - ) + msg = "Please create a projection first using run_umap or run_tsne" + raise ValueError(msg) else: dt = projection diff --git a/src/scanpy/external/pp/_bbknn.py b/src/scanpy/external/pp/_bbknn.py index 07d6e41f93..ee280cc824 100644 --- a/src/scanpy/external/pp/_bbknn.py +++ b/src/scanpy/external/pp/_bbknn.py @@ -133,7 +133,8 @@ def bbknn( try: from bbknn import bbknn except ImportError: - raise ImportError("Please install bbknn: `pip install bbknn`.") + msg = "Please install bbknn: `pip install bbknn`." + raise ImportError(msg) return bbknn( adata=adata, batch_key=batch_key, diff --git a/src/scanpy/external/pp/_dca.py b/src/scanpy/external/pp/_dca.py index c47fff90f2..20a97034b8 100644 --- a/src/scanpy/external/pp/_dca.py +++ b/src/scanpy/external/pp/_dca.py @@ -181,7 +181,8 @@ def dca( try: from dca.api import dca except ImportError: - raise ImportError("Please install dca package (>= 0.2.1) via `pip install dca`") + msg = "Please install dca package (>= 0.2.1) via `pip install dca`" + raise ImportError(msg) return dca( adata, diff --git a/src/scanpy/external/pp/_harmony_integrate.py b/src/scanpy/external/pp/_harmony_integrate.py index 1104690d53..824309f817 100644 --- a/src/scanpy/external/pp/_harmony_integrate.py +++ b/src/scanpy/external/pp/_harmony_integrate.py @@ -91,7 +91,8 @@ def harmony_integrate( try: import harmonypy except ImportError: - raise ImportError("\nplease install harmonypy:\n\n\tpip install harmonypy") + msg = "\nplease install harmonypy:\n\n\tpip install harmonypy" + raise ImportError(msg) X = adata.obsm[basis].astype(np.float64) diff --git a/src/scanpy/external/pp/_hashsolo.py b/src/scanpy/external/pp/_hashsolo.py index 256c863eee..dcb44239b1 100644 --- a/src/scanpy/external/pp/_hashsolo.py +++ b/src/scanpy/external/pp/_hashsolo.py @@ -352,15 +352,15 @@ def hashsolo( adata = adata.copy() if not inplace else adata data = adata.obs[cell_hashing_columns].values if not check_nonnegative_integers(data): - raise ValueError("Cell hashing counts must be non-negative") + msg = "Cell hashing counts must be non-negative" + raise ValueError(msg) if (number_of_noise_barcodes is not None) and ( number_of_noise_barcodes >= len(cell_hashing_columns) ): - raise ValueError( - "number_of_noise_barcodes must be at least one less \ + msg = "number_of_noise_barcodes must be at least one less \ than the number of samples you have as determined by the number of \ cell_hashing_columns you've given as input " - ) + raise ValueError(msg) num_of_cells = adata.shape[0] results = pd.DataFrame( np.zeros((num_of_cells, 6)), diff --git a/src/scanpy/external/pp/_magic.py b/src/scanpy/external/pp/_magic.py index 132d2a6448..12e93f1a8e 100644 --- a/src/scanpy/external/pp/_magic.py +++ b/src/scanpy/external/pp/_magic.py @@ -142,34 +142,38 @@ def magic( try: from magic import MAGIC, __version__ except ImportError: - raise ImportError( + msg = ( "Please install magic package via `pip install --user " "git+git://github.com/KrishnaswamyLab/MAGIC.git#subdirectory=python`" ) + raise ImportError(msg) else: if Version(__version__) < Version(MIN_VERSION): - raise ImportError( + msg = ( "scanpy requires magic-impute >= " f"v{MIN_VERSION} (detected: v{__version__}). " "Please update magic package via `pip install --user " "--upgrade magic-impute`" ) + raise ImportError(msg) start = logg.info("computing MAGIC") all_or_pca = isinstance(name_list, str | NoneType) if all_or_pca and name_list not in {"all_genes", "pca_only", None}: - raise ValueError( + msg = ( "Invalid string value for `name_list`: " "Only `'all_genes'` and `'pca_only'` are allowed." ) + raise ValueError(msg) if copy is None: copy = not all_or_pca elif not all_or_pca and not copy: - raise ValueError( + msg = ( "Can only perform MAGIC in-place with `name_list=='all_genes' or " f"`name_list=='pca_only'` (got {name_list}). Consider setting " "`copy=True`" ) + raise ValueError(msg) adata = adata.copy() if copy else adata n_jobs = settings.n_jobs if n_jobs is None else n_jobs diff --git a/src/scanpy/external/pp/_mnn_correct.py b/src/scanpy/external/pp/_mnn_correct.py index a497189913..518686dc75 100644 --- a/src/scanpy/external/pp/_mnn_correct.py +++ b/src/scanpy/external/pp/_mnn_correct.py @@ -133,10 +133,8 @@ def mnn_correct( import mnnpy from mnnpy import mnn_correct except ImportError: - raise ImportError( - "Please install the package mnnpy " - "(https://github.com/chriscainx/mnnpy). " - ) + msg = "Please install the package mnnpy (https://github.com/chriscainx/mnnpy). " + raise ImportError(msg) n_jobs = settings.n_jobs if n_jobs is None else n_jobs diff --git a/src/scanpy/external/pp/_scanorama_integrate.py b/src/scanpy/external/pp/_scanorama_integrate.py index ca847f8351..c5fb2683b4 100644 --- a/src/scanpy/external/pp/_scanorama_integrate.py +++ b/src/scanpy/external/pp/_scanorama_integrate.py @@ -111,7 +111,8 @@ def scanorama_integrate( try: import scanorama except ImportError: - raise ImportError("\nplease install Scanorama:\n\n\tpip install scanorama") + msg = "\nplease install Scanorama:\n\n\tpip install scanorama" + raise ImportError(msg) # Get batch indices in linear time. curr_batch = None @@ -123,7 +124,8 @@ def scanorama_integrate( curr_batch = batch_name if batch_name in batch_names: # Contiguous batches important for preserving cell order. - raise ValueError("Detected non-contiguous batches.") + msg = "Detected non-contiguous batches." + raise ValueError(msg) batch_names.append(batch_name) # Preserve name order. name2idx[batch_name] = [] name2idx[batch_name].append(idx) diff --git a/src/scanpy/external/tl/_harmony_timeseries.py b/src/scanpy/external/tl/_harmony_timeseries.py index d1746af45a..de3f8cde26 100644 --- a/src/scanpy/external/tl/_harmony_timeseries.py +++ b/src/scanpy/external/tl/_harmony_timeseries.py @@ -140,13 +140,15 @@ def harmony_timeseries( try: import harmony except ImportError: - raise ImportError("\nplease install harmony:\n\n\tpip install harmonyTS") + msg = "\nplease install harmony:\n\n\tpip install harmonyTS" + raise ImportError(msg) adata = adata.copy() if copy else adata logg.info("Harmony augmented affinity matrix") if adata.obs[tp].dtype.name != "category": - raise ValueError(f"{tp!r} column does not contain Categorical data") + msg = f"{tp!r} column does not contain Categorical data" + raise ValueError(msg) timepoints = adata.obs[tp].cat.categories.tolist() timepoint_connections = pd.DataFrame(np.array([timepoints[:-1], timepoints[1:]]).T) diff --git a/src/scanpy/external/tl/_palantir.py b/src/scanpy/external/tl/_palantir.py index 854301466a..eb060bbbe0 100644 --- a/src/scanpy/external/tl/_palantir.py +++ b/src/scanpy/external/tl/_palantir.py @@ -340,4 +340,5 @@ def _check_import(): try: import palantir # noqa: F401 except ImportError: - raise ImportError("\nplease install palantir:\n\tpip install palantir") + msg = "\nplease install palantir:\n\tpip install palantir" + raise ImportError(msg) diff --git a/src/scanpy/external/tl/_phate.py b/src/scanpy/external/tl/_phate.py index ff50a1e6f7..91d8191e60 100644 --- a/src/scanpy/external/tl/_phate.py +++ b/src/scanpy/external/tl/_phate.py @@ -154,10 +154,11 @@ def phate( try: import phate except ImportError: - raise ImportError( + msg = ( "You need to install the package `phate`: please run `pip install " "--user phate` in a terminal." ) + raise ImportError(msg) X_phate = phate.PHATE( n_components=n_components, k=k, @@ -179,6 +180,6 @@ def phate( logg.info( " finished", time=start, - deep=("added\n" " 'X_phate', PHATE coordinates (adata.obsm)"), + deep=("added\n 'X_phate', PHATE coordinates (adata.obsm)"), ) return adata if copy else None diff --git a/src/scanpy/external/tl/_phenograph.py b/src/scanpy/external/tl/_phenograph.py index 24e10bcb85..fdc3973771 100644 --- a/src/scanpy/external/tl/_phenograph.py +++ b/src/scanpy/external/tl/_phenograph.py @@ -226,17 +226,19 @@ def phenograph( assert phenograph.__version__ >= "1.5.3" except (ImportError, AssertionError, AttributeError): - raise ImportError( + msg = ( "please install the latest release of phenograph:\n\t" "pip install -U PhenoGraph" ) + raise ImportError(msg) if isinstance(data, AnnData): adata = data try: data = data.obsm["X_pca"] except KeyError: - raise KeyError("Please run `sc.pp.pca` on `data` and try again!") + msg = "Please run `sc.pp.pca` on `data` and try again!" + raise KeyError(msg) else: adata = None copy = True diff --git a/src/scanpy/external/tl/_pypairs.py b/src/scanpy/external/tl/_pypairs.py index 255334fe7a..2db98ff9a7 100644 --- a/src/scanpy/external/tl/_pypairs.py +++ b/src/scanpy/external/tl/_pypairs.py @@ -153,8 +153,10 @@ def _check_import(): try: import pypairs except ImportError: - raise ImportError("You need to install the package `pypairs`.") + msg = "You need to install the package `pypairs`." + raise ImportError(msg) min_version = Version("3.0.9") if Version(pypairs.__version__) < min_version: - raise ImportError(f"Please only use `pypairs` >= {min_version}") + msg = f"Please only use `pypairs` >= {min_version}" + raise ImportError(msg) diff --git a/src/scanpy/external/tl/_sam.py b/src/scanpy/external/tl/_sam.py index ebf3156b9a..8daa2c0091 100644 --- a/src/scanpy/external/tl/_sam.py +++ b/src/scanpy/external/tl/_sam.py @@ -211,12 +211,13 @@ def sam( try: from samalg import SAM except ImportError: - raise ImportError( + msg = ( "\nplease install sam-algorithm: \n\n" "\tgit clone git://github.com/atarashansky/self-assembling-manifold.git\n" "\tcd self-assembling-manifold\n" "\tpip install ." ) + raise ImportError(msg) logg.info("Self-assembling manifold") diff --git a/src/scanpy/external/tl/_trimap.py b/src/scanpy/external/tl/_trimap.py index 9146e79b84..122a4792b7 100644 --- a/src/scanpy/external/tl/_trimap.py +++ b/src/scanpy/external/tl/_trimap.py @@ -108,7 +108,8 @@ def trimap( try: from trimap import TRIMAP except ImportError: - raise ImportError("\nplease install trimap: \n\n\tsudo pip install trimap") + msg = "\nplease install trimap: \n\n\tsudo pip install trimap" + raise ImportError(msg) adata = adata.copy() if copy else adata start = logg.info("computing TriMap") adata = adata.copy() if copy else adata @@ -121,10 +122,11 @@ def trimap( else: X = adata.X if scp.issparse(X): - raise ValueError( + msg = ( "trimap currently does not support sparse matrices. Please" "use a dense matrix or apply pca first." ) + raise ValueError(msg) logg.warning("`X_pca` not found. Run `sc.pp.pca` first for speedup.") X_trimap = TRIMAP( n_dims=n_components, diff --git a/src/scanpy/external/tl/_wishbone.py b/src/scanpy/external/tl/_wishbone.py index e857226feb..3b85ae14a1 100644 --- a/src/scanpy/external/tl/_wishbone.py +++ b/src/scanpy/external/tl/_wishbone.py @@ -104,17 +104,17 @@ def wishbone( try: from wishbone.core import wishbone as c_wishbone except ImportError: - raise ImportError( - "\nplease install wishbone:\n\n\thttps://github.com/dpeerlab/wishbone" - ) + msg = "\nplease install wishbone:\n\n\thttps://github.com/dpeerlab/wishbone" + raise ImportError(msg) # Start cell index s = np.where(adata.obs_names == start_cell)[0] if len(s) == 0: - raise RuntimeError( + msg = ( f"Start cell {start_cell} not found in data. " "Please rerun with correct start cell." ) + raise RuntimeError(msg) if isinstance(num_waypoints, Collection): diff = np.setdiff1d(num_waypoints, adata.obs.index) if diff.size > 0: @@ -124,10 +124,11 @@ def wishbone( ) num_waypoints = diff.tolist() elif num_waypoints > adata.shape[0]: - raise RuntimeError( + msg = ( "num_waypoints parameter is higher than the number of cells in the " "dataset. Please select a smaller number" ) + raise RuntimeError(msg) s = s[0] # Run the algorithm diff --git a/src/scanpy/get/_aggregated.py b/src/scanpy/get/_aggregated.py index 53a18bb47c..94bf202b69 100644 --- a/src/scanpy/get/_aggregated.py +++ b/src/scanpy/get/_aggregated.py @@ -256,25 +256,29 @@ def aggregate( Note that this filters out any combination of groups that wasn't present in the original data. """ if not isinstance(adata, AnnData): - raise NotImplementedError( + msg = ( "sc.get.aggregate is currently only implemented for AnnData input, " f"was passed {type(adata)}." ) + raise NotImplementedError(msg) if axis is None: axis = 1 if varm else 0 axis, axis_name = _resolve_axis(axis) mask = _check_mask(adata, mask, axis_name) data = adata.X if sum(p is not None for p in [varm, obsm, layer]) > 1: - raise TypeError("Please only provide one (or none) of varm, obsm, or layer") + msg = "Please only provide one (or none) of varm, obsm, or layer" + raise TypeError(msg) if varm is not None: if axis != 1: - raise ValueError("varm can only be used when axis is 1") + msg = "varm can only be used when axis is 1" + raise ValueError(msg) data = adata.varm[varm] elif obsm is not None: if axis != 0: - raise ValueError("obsm can only be used when axis is 0") + msg = "obsm can only be used when axis is 0" + raise ValueError(msg) data = adata.obsm[obsm] elif layer is not None: data = adata.layers[layer] @@ -324,7 +328,8 @@ def _aggregate( mask: NDArray[np.bool_] | None = None, dof: int = 1, ): - raise NotImplementedError(f"Data type {type(data)} not supported for aggregation") + msg = f"Data type {type(data)} not supported for aggregation" + raise NotImplementedError(msg) @_aggregate.register(pd.DataFrame) @@ -347,7 +352,8 @@ def aggregate_array( funcs = set([func] if isinstance(func, str) else func) if unknown := funcs - get_literal_vals(AggType): - raise ValueError(f"func {unknown} is not one of {get_literal_vals(AggType)}") + msg = f"func {unknown} is not one of {get_literal_vals(AggType)}" + raise ValueError(msg) if "sum" in funcs: # sum is calculated separately from the rest agg = groupby.sum() diff --git a/src/scanpy/get/get.py b/src/scanpy/get/get.py index c36ddde8f8..abfa51d1f9 100644 --- a/src/scanpy/get/get.py +++ b/src/scanpy/get/get.py @@ -149,18 +149,20 @@ def _check_indices( # be further duplicated when selecting them. if not dim_df.columns.is_unique: dup_cols = dim_df.columns[dim_df.columns.duplicated()].tolist() - raise ValueError( + msg = ( f"adata.{dim} contains duplicated columns. Please rename or remove " "these columns first.\n`" f"Duplicated columns {dup_cols}" ) + raise ValueError(msg) if not alt_index.is_unique: - raise ValueError( + msg = ( f"{alt_repr}.{alt_dim}_names contains duplicated items\n" f"Please rename these {alt_dim} names first for example using " f"`adata.{alt_dim}_names_make_unique()`" ) + raise ValueError(msg) # use only unique keys, otherwise duplicated keys will # further duplicate when reordering the keys later in the function @@ -168,27 +170,26 @@ def _check_indices( if key in dim_df.columns: col_keys.append(key) if key in alt_names.index: - raise KeyError( - f"The key '{key}' is found in both adata.{dim} and {alt_repr}.{alt_search_repr}." - ) + msg = f"The key {key!r} is found in both adata.{dim} and {alt_repr}.{alt_search_repr}." + raise KeyError(msg) elif key in alt_names.index: val = alt_names[key] if isinstance(val, pd.Series): # while var_names must be unique, adata.var[gene_symbols] does not # It's still ambiguous to refer to a duplicated entry though. assert alias_index is not None - raise KeyError( - f"Found duplicate entries for '{key}' in {alt_repr}.{alt_search_repr}." - ) + msg = f"Found duplicate entries for {key!r} in {alt_repr}.{alt_search_repr}." + raise KeyError(msg) index_keys.append(val) index_aliases.append(key) else: not_found.append(key) if len(not_found) > 0: - raise KeyError( - f"Could not find keys '{not_found}' in columns of `adata.{dim}` or in" + msg = ( + f"Could not find keys {not_found!r} in columns of `adata.{dim}` or in" f" {alt_repr}.{alt_search_repr}." ) + raise KeyError(msg) return col_keys, index_keys, index_aliases @@ -286,9 +287,9 @@ def obs_df( if isinstance(keys, str): keys = [keys] if use_raw: - assert ( - layer is None - ), "Cannot specify use_raw=True and a layer at the same time." + assert layer is None, ( + "Cannot specify use_raw=True and a layer at the same time." + ) var = adata.raw.var else: var = adata.var @@ -430,7 +431,8 @@ def _get_obs_rep( """ # https://github.com/scverse/scanpy/issues/1546 if not isinstance(use_raw, bool): - raise TypeError(f"use_raw expected to be bool, was {type(use_raw)}.") + msg = f"use_raw expected to be bool, was {type(use_raw)}." + raise TypeError(msg) is_layer = layer is not None is_raw = use_raw is not False @@ -448,10 +450,11 @@ def _get_obs_rep( return adata.obsm[obsm] if is_obsp: return adata.obsp[obsp] - raise AssertionError( + msg = ( "That was unexpected. Please report this bug at:\n\n\t" "https://github.com/scverse/scanpy/issues" ) + raise AssertionError(msg) def _set_obs_rep( diff --git a/src/scanpy/logging.py b/src/scanpy/logging.py index 3aa0ca494c..7bd678f568 100644 --- a/src/scanpy/logging.py +++ b/src/scanpy/logging.py @@ -181,7 +181,7 @@ def print_version_and_date(*, file=None): if file is None: file = sys.stdout print( - f"Running Scanpy {__version__}, " f"on {datetime.now():%Y-%m-%d %H:%M}.", + f"Running Scanpy {__version__}, on {datetime.now():%Y-%m-%d %H:%M}.", file=file, ) diff --git a/src/scanpy/metrics/_gearys_c.py b/src/scanpy/metrics/_gearys_c.py index 358a201eed..cf4220eb7a 100644 --- a/src/scanpy/metrics/_gearys_c.py +++ b/src/scanpy/metrics/_gearys_c.py @@ -113,7 +113,8 @@ def gearys_c( elif "neighbors" in adata.uns: g = adata.uns["neighbors"]["connectivities"] else: - raise ValueError("Must run neighbors first.") + msg = "Must run neighbors first." + raise ValueError(msg) else: raise NotImplementedError() if vals is None: diff --git a/src/scanpy/metrics/_morans_i.py b/src/scanpy/metrics/_morans_i.py index 5e4ab50788..c21c455f38 100644 --- a/src/scanpy/metrics/_morans_i.py +++ b/src/scanpy/metrics/_morans_i.py @@ -112,7 +112,8 @@ def morans_i( elif "neighbors" in adata.uns: g = adata.uns["neighbors"]["connectivities"] else: - raise ValueError("Must run neighbors first.") + msg = "Must run neighbors first." + raise ValueError(msg) else: raise NotImplementedError() if vals is None: diff --git a/src/scanpy/neighbors/__init__.py b/src/scanpy/neighbors/__init__.py index ec5957b325..214043727b 100644 --- a/src/scanpy/neighbors/__init__.py +++ b/src/scanpy/neighbors/__init__.py @@ -425,10 +425,11 @@ def count_nonzero(a: np.ndarray | csr_matrix) -> int: self._eigen_basis = _backwards_compat_get_full_X_diffmap(adata) if n_dcs is not None: if n_dcs > len(self._eigen_values): - raise ValueError( + msg = ( f"Cannot instantiate using `n_dcs`={n_dcs}. " "Compute diffmap/spectrum with more components first." ) + raise ValueError(msg) self._eigen_values = self._eigen_values[:n_dcs] self._eigen_basis = self._eigen_basis[:, :n_dcs] self.n_dcs = len(self._eigen_values) @@ -789,7 +790,8 @@ def compute_eigen( """ np.set_printoptions(precision=10) if self._transitions_sym is None: - raise ValueError("Run `.compute_transitions` first.") + msg = "Run `.compute_transitions` first." + raise ValueError(msg) matrix = self._transitions_sym # compute the spectrum if n_comps == 0: @@ -812,9 +814,7 @@ def compute_eigen( if sort == "decrease": evals = evals[::-1] evecs = evecs[:, ::-1] - logg.info( - f" eigenvalues of transition matrix\n" f"{indent(str(evals), ' ')}" - ) + logg.info(f" eigenvalues of transition matrix\n{indent(str(evals), ' ')}") if self._number_connected_components > len(evals) / 2: logg.warning("Transition matrix has many disconnected components!") self._eigen_values = evals @@ -825,10 +825,11 @@ def _init_iroot(self): # set iroot directly if "iroot" in self._adata.uns: if self._adata.uns["iroot"] >= self._adata.n_obs: - logg.warning( - f'Root cell index {self._adata.uns["iroot"]} does not ' + msg = ( + f"Root cell index {self._adata.uns['iroot']} does not " f"exist for {self._adata.n_obs} samples. It’s ignored." ) + logg.warning(msg) else: self.iroot = self._adata.uns["iroot"] return @@ -890,9 +891,8 @@ def _set_iroot_via_xroot(self, xroot: np.ndarray): condition, only relevant for computing pseudotime. """ if self._adata.shape[1] != xroot.size: - raise ValueError( - "The root vector you provided does not have the " "correct dimension." - ) + msg = "The root vector you provided does not have the correct dimension." + raise ValueError(msg) # this is the squared distance dsqroot = 1e10 iroot = 0 diff --git a/src/scanpy/plotting/_anndata.py b/src/scanpy/plotting/_anndata.py index a93d55699b..75dd210c0b 100755 --- a/src/scanpy/plotting/_anndata.py +++ b/src/scanpy/plotting/_anndata.py @@ -163,7 +163,8 @@ def scatter( if basis is not None: return _scatter_obs(**args) if x is None or y is None: - raise ValueError("Either provide a `basis` or `x` and `y`.") + msg = "Either provide a `basis` or `x` and `y`." + raise ValueError(msg) if _check_if_annotations(adata, "obs", x=x, y=y, colors=color, use_raw=use_raw): return _scatter_obs(**args) if _check_if_annotations(adata, "var", x=x, y=y, colors=color, use_raw=use_raw): @@ -172,10 +173,11 @@ def scatter( # store .uns annotations that were added to the new adata object adata.uns = args_t["adata"].uns return axs - raise ValueError( + msg = ( "`x`, `y`, and potential `color` inputs must all " "come from either `.obs` or `.var`" ) + raise ValueError(msg) def _check_if_annotations( @@ -259,22 +261,23 @@ def _scatter_obs( layers = tuple(layers) for layer in layers: if layer not in adata.layers and layer not in ["X", None]: - raise ValueError( + msg = ( "`layers` should have elements that are " "either None or in adata.layers.keys()." ) + raise ValueError(msg) else: - raise ValueError( + msg = ( "`layers` should be a string or a collection of strings " f"with length 3, had value '{layers}'" ) + raise ValueError(msg) if use_raw and layers not in [("X", "X", "X"), (None, None, None)]: ValueError("`use_raw` must be `False` if layers are used.") if legend_loc not in (valid_legend_locs := get_literal_vals(_utils._LegendLoc)): - raise ValueError( - f"Invalid `legend_loc`, need to be one of: {valid_legend_locs}." - ) + msg = f"Invalid `legend_loc`, need to be one of: {valid_legend_locs}." + raise ValueError(msg) if components is None: components = "1,2" if "2d" in projection else "1,2,3" if isinstance(components, str): @@ -294,9 +297,8 @@ def _scatter_obs( if basis == "diffmap": components -= 1 except KeyError: - raise KeyError( - f"compute coordinates using visualization tool {basis} first" - ) + msg = f"compute coordinates using visualization tool {basis} first" + raise KeyError(msg) elif x is not None and y is not None: if use_raw: if x in adata.obs.columns: @@ -313,7 +315,8 @@ def _scatter_obs( Y = np.c_[x_arr, y_arr] else: - raise ValueError("Either provide a `basis` or `x` and `y`.") + msg = "Either provide a `basis` or `x` and `y`." + raise ValueError(msg) if size is None: n = Y.shape[0] @@ -375,10 +378,11 @@ def _scatter_obs( c = key colorbar = False else: - raise ValueError( + msg = ( f"key {key!r} is invalid! pass valid observation annotation, " f"one of {adata.obs_keys()} or a gene name {adata.var_names}" ) + raise ValueError(msg) if colorbar is None: colorbar = not categorical colorbars.append(colorbar) @@ -451,10 +455,11 @@ def add_centroid(centroids, name, Y, mask): groups = [groups] if isinstance(groups, str) else groups for name in groups: if name not in set(adata.obs[key].cat.categories): - raise ValueError( + msg = ( f"{name!r} is invalid! specify valid name, " f"one of {adata.obs[key].cat.categories}" ) + raise ValueError(msg) else: iname = np.flatnonzero( adata.obs[key].cat.categories.values == name @@ -844,23 +849,21 @@ def violin( ylabel = [ylabel] * (1 if groupby is None else len(keys)) if groupby is None: if len(ylabel) != 1: - raise ValueError( - f"Expected number of y-labels to be `1`, found `{len(ylabel)}`." - ) + msg = f"Expected number of y-labels to be `1`, found `{len(ylabel)}`." + raise ValueError(msg) elif len(ylabel) != len(keys): - raise ValueError( - f"Expected number of y-labels to be `{len(keys)}`, " - f"found `{len(ylabel)}`." - ) + msg = f"Expected number of y-labels to be `{len(keys)}`, found `{len(ylabel)}`." + raise ValueError(msg) if groupby is not None: obs_df = get.obs_df(adata, keys=[groupby] + keys, layer=layer, use_raw=use_raw) if kwds.get("palette") is None: if not isinstance(adata.obs[groupby].dtype, CategoricalDtype): - raise ValueError( + msg = ( f"The column `adata.obs[{groupby!r}]` needs to be categorical, " f"but is of dtype {adata.obs[groupby].dtype}." ) + raise ValueError(msg) _utils.add_colors_for_categorical_sample_annotation(adata, groupby) kwds["hue"] = groupby kwds["palette"] = dict( @@ -1022,7 +1025,8 @@ def clustermap( import seaborn as sns # Slow import, only import if called if not isinstance(obs_keys, str | NoneType): - raise ValueError("Currently, only a single key is supported.") + msg = "Currently, only a single key is supported." + raise ValueError(msg) sanitize_anndata(adata) use_raw = _check_use_raw(adata, use_raw) X = adata.raw.X if use_raw else adata.X @@ -1555,11 +1559,12 @@ def tracksplot( """ if groupby not in adata.obs_keys() or adata.obs[groupby].dtype.name != "category": - raise ValueError( + msg = ( "groupby has to be a valid categorical observation. " f"Given value: {groupby}, valid categorical observations: " - f'{[x for x in adata.obs_keys() if adata.obs[x].dtype.name == "category"]}' + f"{[x for x in adata.obs_keys() if adata.obs[x].dtype.name == 'category']}" ) + raise ValueError(msg) var_names, var_group_labels, var_group_positions = _check_var_names_type( var_names, var_group_labels, var_group_positions @@ -1891,7 +1896,8 @@ def correlation_matrix( dendrogram = ax is None if dendrogram: if ax is not None: - raise ValueError("Can only plot dendrogram when not plotting to an axis") + msg = "Can only plot dendrogram when not plotting to an axis" + raise ValueError(msg) assert (len(index)) == corr_matrix.shape[0] corr_matrix = corr_matrix[index, :] corr_matrix = corr_matrix[:, index] @@ -2059,10 +2065,11 @@ def _prepare_dataframe( f"Given {group}, is not in observations: {adata.obs_keys()}" + msg ) if group in adata.obs.columns and group == adata.obs.index.name: - raise ValueError( + msg = ( f"Given group {group} is both and index and a column level, " "which is ambiguous." ) + raise ValueError(msg) if group == adata.obs.index.name: groupby_index = group if groupby_index is not None: @@ -2277,19 +2284,12 @@ def _reorder_categories_after_dendrogram( 'var_group_labels', and 'var_group_positions' """ - dendrogram_key = _get_dendrogram_key(adata, dendrogram_key, groupby) - if isinstance(groupby, str): groupby = [groupby] - dendro_info = adata.uns[dendrogram_key] - if groupby != dendro_info["groupby"]: - raise ValueError( - "Incompatible observations. The precomputed dendrogram contains " - f"information for the observation: '{groupby}' while the plot is " - f"made for the observation: '{dendro_info['groupby']}. " - "Please run `sc.tl.dendrogram` using the right observation.'" - ) + dendro_info = adata.uns[ + _get_dendrogram_key(adata, dendrogram_key, groupby, validate_groupby=True) + ] if categories is None: categories = adata.obs[dendro_info["groupby"]].cat.categories @@ -2299,7 +2299,7 @@ def _reorder_categories_after_dendrogram( categories_ordered = dendro_info["categories_ordered"] if len(categories) != len(categories_idx_ordered): - raise ValueError( + msg = ( "Incompatible observations. Dendrogram data has " f"{len(categories_idx_ordered)} categories but current groupby " f"observation {groupby!r} contains {len(categories)} categories. " @@ -2307,6 +2307,7 @@ def _reorder_categories_after_dendrogram( "initial computation of `sc.tl.dendrogram`. " "Please run `sc.tl.dendrogram` again.'" ) + raise ValueError(msg) # reorder var_groups (if any) if var_group_positions is None or var_group_labels is None: @@ -2362,7 +2363,11 @@ def _format_first_three_categories(categories): def _get_dendrogram_key( - adata: AnnData, dendrogram_key: str | None, groupby: str | Sequence[str] + adata: AnnData, + dendrogram_key: str | None, + groupby: str | Sequence[str], + *, + validate_groupby: bool = False, ) -> str: # the `dendrogram_key` can be a bool an NoneType or the name of the # dendrogram key. By default the name of the dendrogram key is 'dendrogram' @@ -2370,7 +2375,7 @@ def _get_dendrogram_key( if isinstance(groupby, str): dendrogram_key = f"dendrogram_{groupby}" elif isinstance(groupby, Sequence): - dendrogram_key = f'dendrogram_{"_".join(groupby)}' + dendrogram_key = f"dendrogram_{'_'.join(groupby)}" else: msg = f"groupby has wrong type: {type(groupby).__name__}." raise AssertionError(msg) @@ -2386,10 +2391,22 @@ def _get_dendrogram_key( dendrogram(adata, groupby, key_added=dendrogram_key) if "dendrogram_info" not in adata.uns[dendrogram_key]: - raise ValueError( + msg = ( f"The given dendrogram key ({dendrogram_key!r}) does not contain " "valid dendrogram information." ) + raise ValueError(msg) + + if validate_groupby: + existing_groupby = adata.uns[dendrogram_key]["groupby"] + if groupby != existing_groupby: + msg = ( + "Incompatible observations. The precomputed dendrogram contains " + f"information for the observation: {groupby!r} while the plot is " + f"made for the observation: {existing_groupby!r}. " + "Please run `sc.tl.dendrogram` using the right observation.'" + ) + raise ValueError(msg) return dendrogram_key diff --git a/src/scanpy/plotting/_baseplot_class.py b/src/scanpy/plotting/_baseplot_class.py index fff1b40322..e14d387f84 100644 --- a/src/scanpy/plotting/_baseplot_class.py +++ b/src/scanpy/plotting/_baseplot_class.py @@ -899,23 +899,18 @@ def _format_first_three_categories(_categories): _categories = _categories[:3] + ["etc."] return ", ".join(_categories) - key = _get_dendrogram_key(self.adata, dendrogram_key, self.groupby) - - dendro_info = self.adata.uns[key] - if self.groupby != dendro_info["groupby"]: - raise ValueError( - "Incompatible observations. The precomputed dendrogram contains " - f"information for the observation: '{self.groupby}' while the plot is " - f"made for the observation: '{dendro_info['groupby']}. " - "Please run `sc.tl.dendrogram` using the right observation.'" + dendro_info = self.adata.uns[ + _get_dendrogram_key( + self.adata, dendrogram_key, self.groupby, validate_groupby=True ) + ] # order of groupby categories categories_idx_ordered = dendro_info["categories_idx_ordered"] categories_ordered = dendro_info["categories_ordered"] if len(self.categories) != len(categories_idx_ordered): - raise ValueError( + msg = ( "Incompatible observations. Dendrogram data has " f"{len(categories_idx_ordered)} categories but current groupby " f"observation {self.groupby!r} contains {len(self.categories)} categories. " @@ -923,6 +918,7 @@ def _format_first_three_categories(_categories): "initial computation of `sc.tl.dendrogram`. " "Please run `sc.tl.dendrogram` again.'" ) + raise ValueError(msg) # reorder var_groups (if any) if self.var_names is not None: diff --git a/src/scanpy/plotting/_dotplot.py b/src/scanpy/plotting/_dotplot.py index e2ae434db6..da3d16379b 100644 --- a/src/scanpy/plotting/_dotplot.py +++ b/src/scanpy/plotting/_dotplot.py @@ -681,11 +681,11 @@ def _dotplot( """ assert dot_size.shape == dot_color.shape, ( - "please check that dot_size " "and dot_color dataframes have the same shape" + "please check that dot_size and dot_color dataframes have the same shape" ) assert list(dot_size.index) == list(dot_color.index), ( - "please check that dot_size " "and dot_color dataframes have the same index" + "please check that dot_size and dot_color dataframes have the same index" ) assert list(dot_size.columns) == list(dot_color.columns), ( @@ -721,12 +721,14 @@ def _dotplot( dot_max = np.ceil(max(frac) * 10) / 10 else: if dot_max < 0 or dot_max > 1: - raise ValueError("`dot_max` value has to be between 0 and 1") + msg = "`dot_max` value has to be between 0 and 1" + raise ValueError(msg) if dot_min is None: dot_min = 0 else: if dot_min < 0 or dot_min > 1: - raise ValueError("`dot_min` value has to be between 0 and 1") + msg = "`dot_min` value has to be between 0 and 1" + raise ValueError(msg) if dot_min != 0 or dot_max != 1: # clip frac between dot_min and dot_max diff --git a/src/scanpy/plotting/_scrublet.py b/src/scanpy/plotting/_scrublet.py index 4a1247574d..050aec6f53 100644 --- a/src/scanpy/plotting/_scrublet.py +++ b/src/scanpy/plotting/_scrublet.py @@ -72,9 +72,8 @@ def scrublet_score_distribution( """ if "scrublet" not in adata.uns: - raise ValueError( - "Please run scrublet before trying to generate the scrublet plot." - ) + msg = "Please run scrublet before trying to generate the scrublet plot." + raise ValueError(msg) # If batched_by is populated, then we know Scrublet was run over multiple batches diff --git a/src/scanpy/plotting/_stacked_violin.py b/src/scanpy/plotting/_stacked_violin.py index e47680facc..3c58ead35f 100644 --- a/src/scanpy/plotting/_stacked_violin.py +++ b/src/scanpy/plotting/_stacked_violin.py @@ -750,7 +750,7 @@ def stacked_violin( e.g. `'red'` or `'#cc33ff'`. {show_save_ax} {vminmax} - kwds + **kwds Are passed to :func:`~seaborn.violinplot`. Returns diff --git a/src/scanpy/plotting/_tools/__init__.py b/src/scanpy/plotting/_tools/__init__.py index a421f6b94a..8f189121e2 100644 --- a/src/scanpy/plotting/_tools/__init__.py +++ b/src/scanpy/plotting/_tools/__init__.py @@ -158,14 +158,14 @@ def pca_loadings( components = np.array(components) - 1 if np.any(components < 0): - raise ValueError("Component indices must be greater than zero.") + msg = "Component indices must be greater than zero." + raise ValueError(msg) if n_points is None: n_points = min(30, adata.n_vars) elif adata.n_vars < n_points: - raise ValueError( - f"Tried to plot {n_points} variables, but passed anndata only has {adata.n_vars}." - ) + msg = f"Tried to plot {n_points} variables, but passed anndata only has {adata.n_vars}." + raise ValueError(msg) ranking( adata, @@ -398,10 +398,11 @@ def rank_genes_groups( """ n_panels_per_row = kwds.get("n_panels_per_row", ncols) if n_genes < 1: - raise NotImplementedError( + msg = ( "Specifying a negative number for n_genes has not been implemented for " - f"this plot. Received n_genes={n_genes}." + f"this plot. Received {n_genes=!r}." ) + raise NotImplementedError(msg) reference = str(adata.uns[key]["params"]["reference"]) group_names = adata.uns[key]["names"].dtype.names if groups is None else groups @@ -517,10 +518,11 @@ def _rank_genes_groups_plot( Common function to call the different rank_genes_groups_* plots """ if var_names is not None and n_genes is not None: - raise ValueError( + msg = ( "The arguments n_genes and var_names are mutually exclusive. Please " "select only one." ) + raise ValueError(msg) if var_names is None and n_genes is None: # set n_genes = 10 as default when none of the options is given @@ -694,7 +696,6 @@ def rank_genes_groups_heatmap( {show_save_ax} **kwds Are passed to :func:`~scanpy.pl.heatmap`. - {show_save_ax} Examples -------- @@ -778,7 +779,6 @@ def rank_genes_groups_tracksplot( {show_save_ax} **kwds Are passed to :func:`~scanpy.pl.tracksplot`. - {show_save_ax} Examples -------- @@ -1313,9 +1313,7 @@ def rank_genes_groups_violin( _ax.set_ylabel("expression") _ax.set_xticklabels(new_gene_names, rotation="vertical") writekey = ( - f"rank_genes_groups_" - f"{adata.uns[key]['params']['groupby']}_" - f"{group_name}" + f"rank_genes_groups_{adata.uns[key]['params']['groupby']}_{group_name}" ) savefig_or_show(writekey, show=show, save=save) axs.append(_ax) @@ -1527,7 +1525,8 @@ def embedding_density( basis = "draw_graph_fa" if key is not None and groupby is not None: - raise ValueError("either pass key or groupby but not both") + msg = "either pass key or groupby but not both" + raise ValueError(msg) if key is None: key = "umap_density" @@ -1535,16 +1534,17 @@ def embedding_density( key += f"_{groupby}" if f"X_{basis}" not in adata.obsm_keys(): - raise ValueError( - f"Cannot find the embedded representation `adata.obsm[X_{basis!r}]`. " + msg = ( + f"Cannot find the embedded representation `adata.obsm['X_{basis}']`. " "Compute the embedding first." ) + raise ValueError(msg) if key not in adata.obs or f"{key}_params" not in adata.uns: - raise ValueError( - "Please run `sc.tl.embedding_density()` first " - "and specify the correct key." + msg = ( + "Please run `sc.tl.embedding_density()` first and specify the correct key." ) + raise ValueError(msg) if "components" in kwargs: logg.warning( @@ -1563,10 +1563,11 @@ def embedding_density( group = [group] if group is None and groupby is not None: - raise ValueError( + msg = ( "Densities were calculated over an `.obs` covariate. " "Please specify a group from this covariate to plot." ) + raise ValueError(msg) if group is not None and groupby is None: logg.warning( @@ -1576,7 +1577,8 @@ def embedding_density( group = None if np.min(adata.obs[key]) < 0 or np.max(adata.obs[key]) > 1: - raise ValueError("Densities should be scaled between 0 and 1.") + msg = "Densities should be scaled between 0 and 1." + raise ValueError(msg) if wspace is None: # try to set a wspace that is not too large or too small given the @@ -1601,17 +1603,19 @@ def embedding_density( # (even if only one group is set) if group is not None and not isinstance(group, str) and isinstance(group, Sequence): if ax is not None: - raise ValueError("Can only specify `ax` if no `group` sequence is given.") + msg = "Can only specify `ax` if no `group` sequence is given." + raise ValueError(msg) fig, gs = _panel_grid(hspace, wspace, ncols, len(group)) axs = [] for count, group_name in enumerate(group): if group_name not in adata.obs[groupby].cat.categories: - raise ValueError( + msg = ( "Please specify a group from the `.obs` category " "over which the density was calculated. " f"Invalid group name: {group_name}" ) + raise ValueError(msg) ax = plt.subplot(gs[count]) # Define plotting data @@ -1743,9 +1747,8 @@ def _get_values_to_plot( "log10_pvals_adj", ] if values_to_plot not in valid_options: - raise ValueError( - f"given value_to_plot: '{values_to_plot}' is not valid. Valid options are {valid_options}" - ) + msg = f"given value_to_plot: '{values_to_plot}' is not valid. Valid options are {valid_options}" + raise ValueError(msg) values_df = None check_done = False diff --git a/src/scanpy/plotting/_tools/paga.py b/src/scanpy/plotting/_tools/paga.py index e67e6e2ece..a4b2de3441 100644 --- a/src/scanpy/plotting/_tools/paga.py +++ b/src/scanpy/plotting/_tools/paga.py @@ -239,10 +239,11 @@ def _compute_pos( nx_g_tree = nx.Graph(adj_tree) pos = _utils.hierarchy_pos(nx_g_tree, root) if len(pos) < adjacency_solid.shape[0]: - raise ValueError( + msg = ( "This is a forest and not a single tree. " "Try another `layout`, e.g., {'fr'}." ) + raise ValueError(msg) else: # igraph layouts random.seed(random_state.bytes(8)) @@ -547,10 +548,8 @@ def is_flat(x): if isinstance(root, str): if root not in labels: - raise ValueError( - "If `root` is a string, " - f"it needs to be one of {labels} not {root!r}." - ) + msg = f"If `root` is a string, it needs to be one of {labels} not {root!r}." + raise ValueError(msg) root = list(labels).index(root) if isinstance(root, Sequence) and root[0] in labels: root = [list(labels).index(r) for r in root] @@ -731,10 +730,11 @@ def _paga_graph( else: pos = Path(pos) if pos.suffix != ".gdf": - raise ValueError( + msg = ( "Currently only supporting reading positions from .gdf files. " "Consider generating them using, for instance, Gephi." ) + raise ValueError(msg) s = "" # read the node definition from the file with pos.open() as f: f.readline() @@ -762,7 +762,8 @@ def _paga_graph( elif colors == "degree_solid": colors = [d for _, d in nx_g_solid.degree(weight="weight")] else: - raise ValueError('`degree` either "degree_dashed" or "degree_solid".') + msg = '`degree` either "degree_dashed" or "degree_solid".' + raise ValueError(msg) colors = (np.array(colors) - np.min(colors)) / (np.max(colors) - np.min(colors)) # plot gene expression @@ -811,10 +812,11 @@ def _paga_graph( colors = asso_colors if len(colors) != len(node_labels): - raise ValueError( + msg = ( f"Expected `colors` to be of length `{len(node_labels)}`, " f"found `{len(colors)}`." ) + raise ValueError(msg) # count number of connected components n_components, labels = scipy.sparse.csgraph.connected_components(adjacency_solid) @@ -839,7 +841,8 @@ def _paga_graph( ) nx_g_solid = nx.Graph(adjacency_solid) if dashed_edges is not None: - raise ValueError("`single_component` only if `dashed_edges` is `None`.") + msg = "`single_component` only if `dashed_edges` is `None`." + raise ValueError(msg) # edge widths base_edge_width = edge_width_scale * 5 * rcParams["lines.linewidth"] @@ -958,10 +961,11 @@ def _paga_graph( else: for ix, (xx, yy) in enumerate(zip(pos_array[:, 0], pos_array[:, 1])): if not isinstance(colors[ix], Mapping): - raise ValueError( + msg = ( f"{colors[ix]} is neither a dict of valid " "matplotlib colors nor a valid matplotlib color." ) + raise ValueError(msg) color_single = colors[ix].keys() fracs = [colors[ix][c] for c in color_single] total = sum(fracs) @@ -971,10 +975,11 @@ def _paga_graph( color_single.append("grey") fracs.append(1 - sum(fracs)) elif not np.isclose(total, 1): - raise ValueError( + msg = ( f"Expected fractions for node `{ix}` to be " f"close to 1, found `{total}`." ) + raise ValueError(msg) cumsum = np.cumsum(fracs) cumsum = cumsum / cumsum[-1] @@ -1125,18 +1130,20 @@ def paga_path( if groups_key is None: if "groups" not in adata.uns["paga"]: - raise KeyError( + msg = ( "Pass the key of the grouping with which you ran PAGA, " "using the parameter `groups_key`." ) + raise KeyError(msg) groups_key = adata.uns["paga"]["groups"] groups_names = adata.obs[groups_key].cat.categories if "dpt_pseudotime" not in adata.obs.columns: - raise ValueError( + msg = ( "`pl.paga_path` requires computation of a pseudotime `tl.dpt` " "for ordering at single-cell resolution" ) + raise ValueError(msg) if palette_groups is None: _utils.add_colors_for_categorical_sample_annotation(adata, groups_key) @@ -1157,10 +1164,11 @@ def moving_average(a): groups_names_set = set(groups_names) for node in nodes: if node not in groups_names_set: - raise ValueError( + msg = ( f"Each node/group needs to be in {groups_names.tolist()} " - f"(`groups_key`={groups_key!r}) not {node!r}." + f"({groups_key=!r}) not {node!r}." ) + raise ValueError(msg) nodes_ints.append(groups_names.get_loc(node)) nodes_strs = nodes else: @@ -1178,12 +1186,13 @@ def moving_average(a): adata.obs[groups_key].values == nodes_strs[igroup] ] if len(idcs) == 0: - raise ValueError( + msg = ( "Did not find data points that match " f"`adata.obs[{groups_key!r}].values == {str(group)!r}`. " f"Check whether `adata.obs[{groups_key!r}]` " "actually contains what you expect." ) + raise ValueError(msg) idcs_group = np.argsort( adata.obs["dpt_pseudotime"].values[ adata.obs[groups_key].values == nodes_strs[igroup] diff --git a/src/scanpy/plotting/_tools/scatterplots.py b/src/scanpy/plotting/_tools/scatterplots.py index b54897678f..cb3c9d7c66 100644 --- a/src/scanpy/plotting/_tools/scatterplots.py +++ b/src/scanpy/plotting/_tools/scatterplots.py @@ -149,7 +149,8 @@ def embedding( # Checking the mask format and if used together with groups if groups is not None and mask_obs is not None: - raise ValueError("Groups and mask arguments are incompatible.") + msg = "Groups and mask arguments are incompatible." + raise ValueError(msg) mask_obs = _check_mask(adata, mask_obs, "obs") # Figure out if we're using raw @@ -157,15 +158,17 @@ def embedding( # check if adata.raw is set use_raw = layer is None and adata.raw is not None if use_raw and layer is not None: - raise ValueError( - "Cannot use both a layer and the raw representation. Was passed:" - f"use_raw={use_raw}, layer={layer}." + msg = ( + "Cannot use both a layer and the raw representation. " + f"Was passed: {use_raw=!r}, {layer=!r}." ) + raise ValueError(msg) if use_raw and adata.raw is None: - raise ValueError( + msg = ( "`use_raw` is set to True but AnnData object does not have raw. " "Please check." ) + raise ValueError(msg) if isinstance(groups, str): groups = [groups] @@ -173,7 +176,8 @@ def embedding( # Color map if color_map is not None: if cmap is not None: - raise ValueError("Cannot specify both `color_map` and `cmap`.") + msg = "Cannot specify both `color_map` and `cmap`." + raise ValueError(msg) else: cmap = color_map cmap = copy(colormaps.get_cmap(cmap)) @@ -245,10 +249,11 @@ def embedding( not isinstance(color, str) and isinstance(color, Sequence) and len(color) > 1 ) or len(dimensions) > 1: if ax is not None: - raise ValueError( + msg = ( "Cannot specify `ax` when plotting multiple panels " "(each for a given value of 'color')." ) + raise ValueError(msg) # each plot needs to be its own panel fig, grid = _panel_grid(hspace, wspace, ncols, len(color)) @@ -810,9 +815,8 @@ def draw_graph( layout = str(adata.uns["draw_graph"]["params"]["layout"]) basis = f"draw_graph_{layout}" if f"X_{basis}" not in adata.obsm_keys(): - raise ValueError( - f"Did not find {basis} in adata.obs. Did you compute layout {layout}?" - ) + msg = f"Did not find {basis} in adata.obs. Did you compute layout {layout}?" + raise ValueError(msg) return embedding(adata, basis, **kwargs) @@ -883,10 +887,11 @@ def pca( adata, "pca", show=show, return_fig=return_fig, save=save, **kwargs ) if "pca" not in adata.obsm and "X_pca" not in adata.obsm: - raise KeyError( + msg = ( f"Could not find entry in `obsm` for 'pca'.\n" f"Available keys are: {list(adata.obsm.keys())}." ) + raise KeyError(msg) label_dict = { f"PC{i + 1}": f"PC{i + 1} ({round(v * 100, 2)}%)" @@ -1060,7 +1065,8 @@ def _components_to_dimensions( if components is None and dimensions is None: dimensions = [tuple(i for i in range(ndims))] elif components is not None and dimensions is not None: - raise ValueError("Cannot provide both dimensions and components") + msg = "Cannot provide both dimensions and components" + raise ValueError(msg) # TODO: Consider deprecating this # If components is not None, parse them and set dimensions @@ -1099,9 +1105,8 @@ def _add_categorical_legend( """Add a legend to the passed Axes.""" if na_in_legend and pd.isnull(color_source_vector).any(): if "NA" in color_source_vector: - raise NotImplementedError( - "No fallback for null labels has been defined if NA already in categories." - ) + msg = "No fallback for null labels has been defined if NA already in categories." + raise NotImplementedError(msg) color_source_vector = color_source_vector.add_categories("NA").fillna("NA") palette = palette.copy() palette["NA"] = na_color @@ -1162,7 +1167,8 @@ def _get_basis(adata: AnnData, basis: str) -> np.ndarray: elif f"X_{basis}" in adata.obsm: return adata.obsm[f"X_{basis}"] else: - raise KeyError(f"Could not find '{basis}' or 'X_{basis}' in .obsm") + msg = f"Could not find {basis!r} or 'X_{basis}' in .obsm" + raise KeyError(msg) def _get_color_source_vector( @@ -1294,10 +1300,11 @@ def _check_spot_size(spatial_data: Mapping | None, spot_size: float | None) -> f This is a required argument for spatial plots. """ if spatial_data is None and spot_size is None: - raise ValueError( + msg = ( "When .uns['spatial'][library_id] does not exist, spot_size must be " "provided directly." ) + raise ValueError(msg) elif spot_size is None: return spatial_data["scalefactors"]["spot_diameter_fullres"] else: @@ -1329,10 +1336,11 @@ def _check_spatial_data( spatial_mapping = uns.get("spatial", {}) if library_id is _empty: if len(spatial_mapping) > 1: - raise ValueError( + msg = ( "Found multiple possible libraries in `.uns['spatial']. Please specify." f" Options are:\n\t{list(spatial_mapping.keys())}" ) + raise ValueError(msg) elif len(spatial_mapping) == 1: library_id = list(spatial_mapping.keys())[0] else: @@ -1370,7 +1378,8 @@ def _check_crop_coord( if crop_coord is None: return None if len(crop_coord) != 4: - raise ValueError("Invalid crop_coord of length {len(crop_coord)}(!=4)") + msg = "Invalid crop_coord of length {len(crop_coord)}(!=4)" + raise ValueError(msg) crop_coord = tuple(c * scale_factor for c in crop_coord) return crop_coord @@ -1389,7 +1398,8 @@ def _broadcast_args(*args): lens = [len(arg) for arg in args] longest = max(lens) if not (set(lens) == {1, longest} or set(lens) == {longest}): - raise ValueError(f"Could not broadcast together arguments with shapes: {lens}.") + msg = f"Could not broadcast together arguments with shapes: {lens}." + raise ValueError(msg) return list( [[arg[0] for _ in range(longest)] if len(arg) == 1 else arg for arg in args] ) diff --git a/src/scanpy/plotting/_utils.py b/src/scanpy/plotting/_utils.py index 09a01a9bc5..b6cd920039 100644 --- a/src/scanpy/plotting/_utils.py +++ b/src/scanpy/plotting/_utils.py @@ -398,7 +398,7 @@ def _validate_palette(adata: AnnData, key: str) -> None: else: logg.warning( f"The following color value found in adata.uns['{key}_colors'] " - f"is not valid: '{color}'. Default colors will be used instead." + f"is not valid: {color!r}. Default colors will be used instead." ) _set_default_colors_for_categorical_obs(adata, key) _palette = None @@ -466,21 +466,24 @@ def _set_colors_for_categorical_obs( if color in additional_colors: color = additional_colors[color] else: - raise ValueError( + msg = ( "The following color value of the given palette " f"is not valid: {color}" ) + raise ValueError(msg) _color_list.append(color) palette = cycler(color=_color_list) if not isinstance(palette, Cycler): - raise ValueError( + msg = ( "Please check that the value of 'palette' is a valid " "matplotlib colormap string (eg. Set2), a list of color names " "or a cycler with a 'color' key." ) + raise ValueError(msg) if "color" not in palette.keys: - raise ValueError("Please set the palette key 'color'.") + msg = "Please set the palette key 'color'." + raise ValueError(msg) cc = palette() colors_list = [to_hex(next(cc)["color"]) for x in range(len(categories))] @@ -556,7 +559,8 @@ def plot_edges(axs, adata, basis, edges_width, edges_color, *, neighbors_key=Non if neighbors_key is None: neighbors_key = "neighbors" if neighbors_key not in adata.uns: - raise ValueError("`edges=True` requires `pp.neighbors` to be run before.") + msg = "`edges=True` requires `pp.neighbors` to be run before." + raise ValueError(msg) neighbors = NeighborsView(adata, neighbors_key) g = nx.Graph(neighbors["connectivities"]) basis_key = _get_basis(adata, basis) @@ -582,11 +586,12 @@ def plot_arrows(axs, adata, basis, arrows_kwds=None): (p for p in ["velocity", "Delta"] if f"{p}_{basis}" in adata.obsm), None ) if v_prefix is None: - raise ValueError( + msg = ( "`arrows=True` requires " f"`'velocity_{basis}'` from scvelo or " f"`'Delta_{basis}'` from velocyto." ) + raise ValueError(msg) if v_prefix == "velocity": logg.warning( "The module `scvelo` has improved plotting facilities. " @@ -628,7 +633,8 @@ def scatter_group( color = rgb2hex(adata.uns[key + "_colors"][cat_code]) if not is_color_like(color): - raise ValueError(f'"{color}" is not a valid matplotlib color.') + msg = f"{color!r} is not a valid matplotlib color." + raise ValueError(msg) data = [Y[mask_obs, 0], Y[mask_obs, 1]] if projection == "3d": data.append(Y[mask_obs, 2]) @@ -658,7 +664,8 @@ def setup_axes( """Grid of axes for plotting, legends and colorbars.""" check_projection(projection) if left_margin is not None: - raise NotImplementedError("We currently don’t support `left_margin`.") + msg = "We currently don’t support `left_margin`." + raise NotImplementedError(msg) if np.any(colorbars) and right_margin is None: right_margin = 1 - rcParams["figure.subplot.right"] + 0.21 # 0.25 elif right_margin is None: @@ -801,7 +808,8 @@ def scatter_base( elif projection == "3d": data = Y_sort[:, 0], Y_sort[:, 1], Y_sort[:, 2] else: - raise ValueError(f"Unknown projection {projection!r} not in '2d', '3d'") + msg = f"Unknown projection {projection!r} not in '2d', '3d'" + raise ValueError(msg) if not isinstance(color, str) or color != "white": sct = ax.scatter( *data, @@ -1148,15 +1156,15 @@ def data_to_axis_points(ax: Axes, points_data: np.ndarray): def check_projection(projection): """Validation for projection argument.""" if projection not in {"2d", "3d"}: - raise ValueError(f"Projection must be '2d' or '3d', was '{projection}'.") + msg = f"Projection must be '2d' or '3d', was '{projection}'." + raise ValueError(msg) if projection == "3d": from packaging.version import parse mpl_version = parse(mpl.__version__) if mpl_version < parse("3.3.3"): - raise ImportError( - f"3d plotting requires matplotlib > 3.3.3. Found {mpl.__version__}" - ) + msg = f"3d plotting requires matplotlib > 3.3.3. Found {mpl.__version__}" + raise ImportError(msg) def circles( @@ -1300,7 +1308,8 @@ def check_colornorm(vmin=None, vmax=None, vcenter=None, norm=None): if norm is not None: if (vmin is not None) or (vmax is not None) or (vcenter is not None): - raise ValueError("Passing both norm and vmin/vmax/vcenter is not allowed.") + msg = "Passing both norm and vmin/vmax/vcenter is not allowed." + raise ValueError(msg) else: if vcenter is not None: norm = DivNorm(vmin=vmin, vmax=vmax, vcenter=vcenter) diff --git a/src/scanpy/preprocessing/_combat.py b/src/scanpy/preprocessing/_combat.py index caeb9a0b45..93052f356c 100644 --- a/src/scanpy/preprocessing/_combat.py +++ b/src/scanpy/preprocessing/_combat.py @@ -179,21 +179,23 @@ def combat( # check the input if key not in adata.obs_keys(): - raise ValueError(f"Could not find the key {key!r} in adata.obs") + msg = f"Could not find the key {key!r} in adata.obs" + raise ValueError(msg) if covariates is not None: cov_exist = np.isin(covariates, adata.obs_keys()) if np.any(~cov_exist): missing_cov = np.array(covariates)[~cov_exist].tolist() - raise ValueError( - f"Could not find the covariate(s) {missing_cov!r} in adata.obs" - ) + msg = f"Could not find the covariate(s) {missing_cov!r} in adata.obs" + raise ValueError(msg) if key in covariates: - raise ValueError("Batch key and covariates cannot overlap") + msg = "Batch key and covariates cannot overlap" + raise ValueError(msg) if len(covariates) != len(set(covariates)): - raise ValueError("Covariates must be unique") + msg = "Covariates must be unique" + raise ValueError(msg) # only works on dense matrices so far X = adata.X.toarray().T if issparse(adata.X) else adata.X.T diff --git a/src/scanpy/preprocessing/_deprecated/__init__.py b/src/scanpy/preprocessing/_deprecated/__init__.py index c23361631a..b821417c0b 100644 --- a/src/scanpy/preprocessing/_deprecated/__init__.py +++ b/src/scanpy/preprocessing/_deprecated/__init__.py @@ -36,7 +36,8 @@ def normalize_per_cell_weinreb16_deprecated( Normalized version of the original expression matrix. """ if max_fraction < 0 or max_fraction > 1: - raise ValueError("Choose max_fraction between 0 and 1.") + msg = "Choose max_fraction between 0 and 1." + raise ValueError(msg) counts_per_cell = x.sum(1).A1 if issparse(x) else x.sum(1) gene_subset = np.all(x <= counts_per_cell[:, None] * max_fraction, axis=0) diff --git a/src/scanpy/preprocessing/_deprecated/highly_variable_genes.py b/src/scanpy/preprocessing/_deprecated/highly_variable_genes.py index 27e8f1f846..bba4fb9bbf 100644 --- a/src/scanpy/preprocessing/_deprecated/highly_variable_genes.py +++ b/src/scanpy/preprocessing/_deprecated/highly_variable_genes.py @@ -214,7 +214,8 @@ def filter_genes_dispersion( / disp_mad_bin[df["mean_bin"].values].values ) else: - raise ValueError('`flavor` needs to be "seurat" or "cell_ranger"') + msg = '`flavor` needs to be "seurat" or "cell_ranger"' + raise ValueError(msg) dispersion_norm = df["dispersion_norm"].values.astype("float32") if n_top_genes is not None: dispersion_norm = dispersion_norm[~np.isnan(dispersion_norm)] @@ -268,7 +269,8 @@ def filter_genes_fano_deprecated(X, Ecutoff, Vcutoff): def _filter_genes(X, e_cutoff, v_cutoff, meth): """See `filter_genes_dispersion` :cite:p:`Weinreb2017`.""" if issparse(X): - raise ValueError("Not defined for sparse input. See `filter_genes_dispersion`.") + msg = "Not defined for sparse input. See `filter_genes_dispersion`." + raise ValueError(msg) mean_filter = np.mean(X, axis=0) > e_cutoff var_filter = meth(X, axis=0) / (np.mean(X, axis=0) + 0.0001) > v_cutoff gene_subset = np.nonzero(np.all([mean_filter, var_filter], axis=0))[0] diff --git a/src/scanpy/preprocessing/_highly_variable_genes.py b/src/scanpy/preprocessing/_highly_variable_genes.py index e34340b256..356fa8f03f 100644 --- a/src/scanpy/preprocessing/_highly_variable_genes.py +++ b/src/scanpy/preprocessing/_highly_variable_genes.py @@ -65,15 +65,14 @@ def _highly_variable_genes_seurat_v3( try: from skmisc.loess import loess except ImportError: - raise ImportError( - "Please install skmisc package via `pip install --user scikit-misc" - ) + msg = "Please install skmisc package via `pip install --user scikit-misc" + raise ImportError(msg) df = pd.DataFrame(index=adata.var_names) data = _get_obs_rep(adata, layer=layer) if check_values and not check_nonnegative_integers(data): warnings.warn( - f"`flavor='{flavor}'` expects raw count data, but non-integers were found.", + f"`{flavor=!r}` expects raw count data, but non-integers were found.", UserWarning, ) @@ -159,7 +158,8 @@ def _highly_variable_genes_seurat_v3( sort_cols = ["highly_variable_nbatches", "highly_variable_rank"] sort_ascending = [False, True] else: - raise ValueError(f"Did not recognize flavor {flavor}") + msg = f"Did not recognize flavor {flavor}" + raise ValueError(msg) sorted_index = ( df[sort_cols] .sort_values(sort_cols, ascending=sort_ascending, na_position="last") @@ -332,7 +332,8 @@ def _get_mean_bins( elif flavor == "cell_ranger": bins = np.r_[-np.inf, np.percentile(means, np.arange(10, 105, 5)), np.inf] else: - raise ValueError('`flavor` needs to be "seurat" or "cell_ranger"') + msg = '`flavor` needs to be "seurat" or "cell_ranger"' + raise ValueError(msg) return pd.cut(means, bins=bins) @@ -347,7 +348,8 @@ def _get_disp_stats( elif flavor == "cell_ranger": disp_bin_stats = disp_grouped.agg(avg="median", dev=_mad) else: - raise ValueError('`flavor` needs to be "seurat" or "cell_ranger"') + msg = '`flavor` needs to be "seurat" or "cell_ranger"' + raise ValueError(msg) return disp_bin_stats.loc[df["mean_bin"]].set_index(df.index) @@ -647,10 +649,11 @@ def highly_variable_genes( start = logg.info("extracting highly variable genes") if not isinstance(adata, AnnData): - raise ValueError( + msg = ( "`pp.highly_variable_genes` expects an `AnnData` argument, " "pass `inplace=False` if you want to return a `pd.DataFrame`." ) + raise ValueError(msg) if flavor in {"seurat_v3", "seurat_v3_paper"}: if n_top_genes is None: diff --git a/src/scanpy/preprocessing/_normalization.py b/src/scanpy/preprocessing/_normalization.py index c888ded9c6..e1ee3d4822 100644 --- a/src/scanpy/preprocessing/_normalization.py +++ b/src/scanpy/preprocessing/_normalization.py @@ -175,11 +175,13 @@ def normalize_total( """ if copy: if not inplace: - raise ValueError("`copy=True` cannot be used with `inplace=False`.") + msg = "`copy=True` cannot be used with `inplace=False`." + raise ValueError(msg) adata = adata.copy() if max_fraction < 0 or max_fraction > 1: - raise ValueError("Choose max_fraction between 0 and 1.") + msg = "Choose max_fraction between 0 and 1." + raise ValueError(msg) # Deprecated features if layers is not None: @@ -200,9 +202,8 @@ def normalize_total( if layers == "all": layers = adata.layers.keys() elif isinstance(layers, str): - raise ValueError( - f"`layers` needs to be a list of strings or 'all', not {layers!r}" - ) + msg = f"`layers` needs to be a list of strings or 'all', not {layers!r}" + raise ValueError(msg) view_to_actual(adata) @@ -254,7 +255,8 @@ def normalize_total( elif layer_norm is None: after = None else: - raise ValueError('layer_norm should be "after", "X" or None') + msg = 'layer_norm should be "after", "X" or None' + raise ValueError(msg) for layer_to_norm in layers if layers is not None else (): res = normalize_total( diff --git a/src/scanpy/preprocessing/_pca/__init__.py b/src/scanpy/preprocessing/_pca/__init__.py index 3fd288ad93..db7886a29f 100644 --- a/src/scanpy/preprocessing/_pca/__init__.py +++ b/src/scanpy/preprocessing/_pca/__init__.py @@ -208,7 +208,8 @@ def pca( logg_start = logg.info("computing PCA") if layer is not None and chunked: # Current chunking implementation relies on pca being called on X - raise NotImplementedError("Cannot use `layer` and `chunked` at the same time.") + msg = "Cannot use `layer` and `chunked` at the same time." + raise NotImplementedError(msg) # chunked calculation is not randomized, anyways if svd_solver in {"auto", "randomized"} and not chunked: @@ -220,9 +221,8 @@ def pca( data_is_AnnData = isinstance(data, AnnData) if data_is_AnnData: if layer is None and not chunked and is_backed_type(data.X): - raise NotImplementedError( - f"PCA is not implemented for matrices of type {type(data.X)} with chunked as False" - ) + msg = f"PCA is not implemented for matrices of type {type(data.X)} with chunked as False" + raise NotImplementedError(msg) adata = data.copy() if copy else data else: if pkg_version("anndata") < Version("0.8.0rc1"): @@ -239,13 +239,12 @@ def pca( min_dim = min(adata_comp.n_vars, adata_comp.n_obs) n_comps = min_dim - 1 if min_dim <= settings.N_PCS else settings.N_PCS - logg.info(f" with n_comps={n_comps}") + logg.info(f" with {n_comps=}") X = _get_obs_rep(adata_comp, layer=layer) if is_backed_type(X) and layer is not None: - raise NotImplementedError( - f"PCA is not implemented for matrices of type {type(X)} from layers" - ) + msg = f"PCA is not implemented for matrices of type {type(X)} from layers" + raise NotImplementedError(msg) # See: https://github.com/scverse/scanpy/pull/2816#issuecomment-1932650529 if ( Version(ad.__version__) < Version("0.9") diff --git a/src/scanpy/preprocessing/_qc.py b/src/scanpy/preprocessing/_qc.py index 87ad51d420..5af8def042 100644 --- a/src/scanpy/preprocessing/_qc.py +++ b/src/scanpy/preprocessing/_qc.py @@ -32,10 +32,11 @@ def _choose_mtx_rep(adata, *, use_raw: bool = False, layer: str | None = None): is_layer = layer is not None if use_raw and is_layer: - raise ValueError( + msg = ( "Cannot use expression from both layer and raw. You provided:" - f"'use_raw={use_raw}' and 'layer={layer}'" + f"{use_raw=!r} and {layer=!r}" ) + raise ValueError(msg) if is_layer: return adata.layers[layer] elif use_raw: @@ -384,7 +385,8 @@ def top_proportions_sparse_csr(data, indptr, n): def check_ns(func): def check_ns_inner(mtx: np.ndarray | spmatrix | DaskArray, ns: Collection[int]): if not (max(ns) <= mtx.shape[1] and min(ns) > 0): - raise IndexError("Positions outside range of features.") + msg = "Positions outside range of features." + raise IndexError(msg) return func(mtx, ns) return check_ns_inner diff --git a/src/scanpy/preprocessing/_recipes.py b/src/scanpy/preprocessing/_recipes.py index 4b97405df9..4748d75e5c 100644 --- a/src/scanpy/preprocessing/_recipes.py +++ b/src/scanpy/preprocessing/_recipes.py @@ -59,7 +59,8 @@ def recipe_weinreb17( from ._deprecated import normalize_per_cell_weinreb16_deprecated, zscore_deprecated if issparse(adata.X): - raise ValueError("`recipe_weinreb16 does not support sparse matrices.") + msg = "`recipe_weinreb16 does not support sparse matrices." + raise ValueError(msg) if copy: adata = adata.copy() if log: diff --git a/src/scanpy/preprocessing/_scale.py b/src/scanpy/preprocessing/_scale.py index bac08f246b..ee15f977b9 100644 --- a/src/scanpy/preprocessing/_scale.py +++ b/src/scanpy/preprocessing/_scale.py @@ -133,13 +133,11 @@ def scale( """ _check_array_function_arguments(layer=layer, obsm=obsm) if layer is not None: - raise ValueError( - f"`layer` argument inappropriate for value of type {type(data)}" - ) + msg = f"`layer` argument inappropriate for value of type {type(data)}" + raise ValueError(msg) if obsm is not None: - raise ValueError( - f"`obsm` argument inappropriate for value of type {type(data)}" - ) + msg = f"`obsm` argument inappropriate for value of type {type(data)}" + raise ValueError(msg) return scale_array( data, zero_center=zero_center, max_value=max_value, copy=copy, mask_obs=mask_obs ) @@ -184,7 +182,7 @@ def scale_array( if not zero_center and max_value is not None: logg.info( # Be careful of what? This should be more specific - "... be careful when using `max_value` " "without `zero_center`." + "... be careful when using `max_value` without `zero_center`." ) if np.issubdtype(X.dtype, np.integer): diff --git a/src/scanpy/preprocessing/_scrublet/pipeline.py b/src/scanpy/preprocessing/_scrublet/pipeline.py index 586587e2cf..6e52a6650c 100644 --- a/src/scanpy/preprocessing/_scrublet/pipeline.py +++ b/src/scanpy/preprocessing/_scrublet/pipeline.py @@ -53,7 +53,8 @@ def truncated_svd( algorithm: Literal["arpack", "randomized"] = "arpack", ) -> None: if self._counts_sim_norm is None: - raise RuntimeError("_counts_sim_norm is not set") + msg = "_counts_sim_norm is not set" + raise RuntimeError(msg) from sklearn.decomposition import TruncatedSVD svd = TruncatedSVD( @@ -72,7 +73,8 @@ def pca( svd_solver: Literal["auto", "full", "arpack", "randomized"] = "arpack", ) -> None: if self._counts_sim_norm is None: - raise RuntimeError("_counts_sim_norm is not set") + msg = "_counts_sim_norm is not set" + raise RuntimeError(msg) from sklearn.decomposition import PCA X_obs = self._counts_obs_norm.toarray() diff --git a/src/scanpy/preprocessing/_simple.py b/src/scanpy/preprocessing/_simple.py index 0c73d2c4e8..bbe20f13c9 100644 --- a/src/scanpy/preprocessing/_simple.py +++ b/src/scanpy/preprocessing/_simple.py @@ -174,10 +174,11 @@ def filter_cells( option is not None for option in [min_genes, min_counts, max_genes, max_counts] ) if n_given_options != 1: - raise ValueError( + msg = ( "Only provide one of the optional parameters `min_counts`, " "`min_genes`, `max_counts`, `max_genes` per call." ) + raise ValueError(msg) if isinstance(data, AnnData): raise_not_implemented_error_if_backed_type(data.X, "filter_cells") adata = data.copy() if copy else data @@ -308,10 +309,11 @@ def filter_genes( option is not None for option in [min_cells, min_counts, max_cells, max_counts] ) if n_given_options != 1: - raise ValueError( + msg = ( "Only provide one of the optional parameters `min_counts`, " "`min_cells`, `max_counts`, `max_cells` per call." ) + raise ValueError(msg) if isinstance(data, AnnData): raise_not_implemented_error_if_backed_type(data.X, "filter_genes") @@ -478,13 +480,13 @@ def log1p_anndata( if chunked: if (layer is not None) or (obsm is not None): - raise NotImplementedError( + msg = ( "Currently cannot perform chunked operations on arrays not stored in X." ) + raise NotImplementedError(msg) if adata.isbacked and adata.file._filemode != "r+": - raise NotImplementedError( - "log1p is not implemented for backed AnnData with backed mode not r+" - ) + msg = "log1p is not implemented for backed AnnData with backed mode not r+" + raise NotImplementedError(msg) for chunk, start, end in adata.chunked_X(chunk_size): adata.X[start:end] = log1p(chunk, base=base, copy=False) else: @@ -492,8 +494,10 @@ def log1p_anndata( if is_backed_type(X): msg = f"log1p is not implemented for matrices of type {type(X)}" if layer is not None: - raise NotImplementedError(f"{msg} from layers") - raise NotImplementedError(f"{msg} without `chunked=True`") + msg = f"{msg} from layers" + raise NotImplementedError(msg) + msg = f"{msg} without `chunked=True`" + raise NotImplementedError(msg) X = log1p(X, copy=False, base=base) _set_obs_rep(adata, X, layer=layer, obsm=obsm) @@ -666,7 +670,8 @@ def normalize_per_cell( elif use_rep is None: after = None else: - raise ValueError('use_rep should be "after", "X" or None') + msg = 'use_rep should be "after", "X" or None' + raise ValueError(msg) for layer in layers: _subset, counts = filter_cells(adata.layers[layer], min_counts=min_counts) temp = normalize_per_cell(adata.layers[layer], after, counts, copy=True) @@ -682,7 +687,8 @@ def normalize_per_cell( X = data.copy() if copy else data if counts_per_cell is None: if not copy: - raise ValueError("Can only be run with copy=True") + msg = "Can only be run with copy=True" + raise ValueError(msg) cell_subset, counts_per_cell = filter_cells(X, min_counts=min_counts) X = X[cell_subset] counts_per_cell = counts_per_cell[cell_subset] @@ -790,11 +796,12 @@ def regress_out( adata.obs[keys[0]].dtype, CategoricalDtype ): if len(keys) > 1: - raise ValueError( + msg = ( "If providing categorical variable, " "only a single one is allowed. For this one " "we regress on the mean for each category." ) + raise ValueError(msg) logg.debug("... regressing on per-gene means within categories") regressors = np.zeros(X.shape, dtype="float32") X = _to_dense(X, order="F") if issparse(X) else X @@ -1088,9 +1095,8 @@ def downsample_counts( total_counts_call = total_counts is not None counts_per_cell_call = counts_per_cell is not None if total_counts_call is counts_per_cell_call: - raise ValueError( - "Must specify exactly one of `total_counts` or `counts_per_cell`." - ) + msg = "Must specify exactly one of `total_counts` or `counts_per_cell`." + raise ValueError(msg) if copy: adata = adata.copy() if total_counts_call: @@ -1110,11 +1116,12 @@ def _downsample_per_cell(X, counts_per_cell, random_state, replace): # np.random.choice needs int arguments in numba code: counts_per_cell = counts_per_cell.astype(np.int_, copy=False) if not isinstance(counts_per_cell, np.ndarray) or len(counts_per_cell) != n_obs: - raise ValueError( + msg = ( "If provided, 'counts_per_cell' must be either an integer, or " "coercible to an `np.ndarray` of length as number of observations" " by `np.asarray(counts_per_cell)`." ) + raise ValueError(msg) if issparse(X): original_type = type(X) if not isspmatrix_csr(X): diff --git a/src/scanpy/preprocessing/_utils.py b/src/scanpy/preprocessing/_utils.py index b200e89ce8..3ca74734c0 100644 --- a/src/scanpy/preprocessing/_utils.py +++ b/src/scanpy/preprocessing/_utils.py @@ -64,7 +64,8 @@ def sparse_mean_variance_axis(mtx: sparse.spmatrix, axis: int): ax_minor = 0 shape = mtx.shape[::-1] else: - raise ValueError("This function only works on sparse csr and csc matrices") + msg = "This function only works on sparse csr and csc matrices" + raise ValueError(msg) if axis == ax_minor: return sparse_mean_var_major_axis( mtx.data, diff --git a/src/scanpy/queries/_queries.py b/src/scanpy/queries/_queries.py index 8da90151ce..e992f937e3 100644 --- a/src/scanpy/queries/_queries.py +++ b/src/scanpy/queries/_queries.py @@ -63,13 +63,13 @@ def simple_query( elif isinstance(attrs, Iterable): attrs = list(attrs) else: - raise TypeError(f"attrs must be of type list or str, was {type(attrs)}.") + msg = f"attrs must be of type list or str, was {type(attrs)}." + raise TypeError(msg) try: from pybiomart import Server except ImportError: - raise ImportError( - "This method requires the `pybiomart` module to be installed." - ) + msg = "This method requires the `pybiomart` module to be installed." + raise ImportError(msg) server = Server(host, use_cache=use_cache) dataset = server.marts["ENSEMBL_MART_ENSEMBL"].datasets[f"{org}_gene_ensembl"] res = dataset.query(attributes=attrs, filters=filters, use_attr_names=True) @@ -273,17 +273,17 @@ def enrich( try: from gprofiler import GProfiler except ImportError: - raise ImportError( - "This method requires the `gprofiler-official` module to be installed." - ) + msg = "This method requires the `gprofiler-official` module to be installed." + raise ImportError(msg) gprofiler = GProfiler(user_agent="scanpy", return_dataframe=True) gprofiler_kwargs = dict(gprofiler_kwargs) for k in ["organism"]: if gprofiler_kwargs.get(k) is not None: - raise ValueError( + msg = ( f"Argument `{k}` should be passed directly through `enrich`, " "not through `gprofiler_kwargs`" ) + raise ValueError(msg) return gprofiler.profile(container, organism=org, **gprofiler_kwargs) diff --git a/src/scanpy/readwrite.py b/src/scanpy/readwrite.py index 3333fbc0a1..c568519cd7 100644 --- a/src/scanpy/readwrite.py +++ b/src/scanpy/readwrite.py @@ -41,6 +41,7 @@ from ._utils import _empty if TYPE_CHECKING: + from datetime import datetime from typing import BinaryIO, Literal from ._utils import Empty @@ -155,13 +156,14 @@ def read( filekey = str(filename) filename = settings.writedir / (filekey + "." + settings.file_format_data) if not filename.exists(): - raise ValueError( + msg = ( f"Reading with filekey {filekey!r} failed, " f"the inferred filename {filename!r} does not exist. " "If you intended to provide a filename, either use a filename " f"ending on one of the available extensions {avail_exts} " "or pass the parameter `ext`." ) + raise ValueError(msg) return read_h5ad(filename, backed=backed) @@ -219,40 +221,46 @@ def read_10x_h5( adata = _read_v3_10x_h5(filename, start=start) if genome: if genome not in adata.var["genome"].values: - raise ValueError( - f"Could not find data corresponding to genome '{genome}' in '{filename}'. " - f'Available genomes are: {list(adata.var["genome"].unique())}.' + msg = ( + f"Could not find data corresponding to genome {genome!r} in {filename}. " + f"Available genomes are: {list(adata.var['genome'].unique())}." ) + raise ValueError(msg) adata = adata[:, adata.var["genome"] == genome] if gex_only: adata = adata[:, adata.var["feature_types"] == "Gene Expression"] if adata.is_view: adata = adata.copy() else: - adata = _read_legacy_10x_h5(filename, genome=genome, start=start) + adata = _read_legacy_10x_h5(Path(filename), genome=genome, start=start) return adata -def _read_legacy_10x_h5(filename, *, genome=None, start=None): +def _read_legacy_10x_h5( + path: Path, *, genome: str | None = None, start: datetime | None = None +): """ Read hdf5 file from Cell Ranger v2 or earlier versions. """ - with h5py.File(str(filename), "r") as f: + with h5py.File(str(path), "r") as f: try: children = list(f.keys()) if not genome: if len(children) > 1: - raise ValueError( - f"'{filename}' contains more than one genome. For legacy 10x h5 " - "files you must specify the genome if more than one is present. " + msg = ( + f"{path} contains more than one genome. " + "For legacy 10x h5 files you must specify the genome " + "if more than one is present. " f"Available genomes are: {children}" ) + raise ValueError(msg) genome = children[0] elif genome not in children: - raise ValueError( - f"Could not find genome '{genome}' in '{filename}'. " + msg = ( + f"Could not find genome {genome!r} in {path}. " f"Available genomes are: {children}" ) + raise ValueError(msg) dsets = {} _collect_datasets(dsets, f[genome]) @@ -283,7 +291,8 @@ def _read_legacy_10x_h5(filename, *, genome=None, start=None): logg.info("", time=start) return adata except KeyError: - raise Exception("File is missing one or more required datasets.") + msg = "File is missing one or more required datasets." + raise Exception(msg) def _collect_datasets(dsets: dict, group: h5py.Group): @@ -354,7 +363,8 @@ def _read_v3_10x_h5(filename, *, start=None): ] ) else: - raise ValueError("10x h5 has no features group") + msg = "10x h5 has no features group" + raise ValueError(msg) adata = AnnData( matrix, obs=obs_dict, @@ -363,7 +373,8 @@ def _read_v3_10x_h5(filename, *, start=None): logg.info("", time=start) return adata except KeyError: - raise Exception("File is missing one or more required datasets.") + msg = "File is missing one or more required datasets." + raise Exception(msg) @deprecated("Use `squidpy.read.visium` instead.") @@ -468,11 +479,11 @@ def read_visium( if not f.exists(): if any(x in str(f) for x in ["hires_image", "lowres_image"]): logg.warning( - f"You seem to be missing an image file.\n" - f"Could not find '{f}'." + f"You seem to be missing an image file.\nCould not find {f}." ) else: - raise OSError(f"Could not find '{f}'") + msg = f"Could not find {f}" + raise OSError(msg) adata.uns["spatial"][library_id]["images"] = dict() for res in ["hires", "lowres"]: @@ -481,7 +492,8 @@ def read_visium( str(files[f"{res}_image"]) ) except Exception: - raise OSError(f"Could not find '{res}_image'") + msg = f"Could not find '{res}_image'" + raise OSError(msg) # read json scalefactors adata.uns["spatial"][library_id]["scalefactors"] = json.loads( @@ -623,7 +635,8 @@ def _read_10x_mtx( adata.var_names = genes[0].values adata.var["gene_symbols"] = genes[1].values else: - raise ValueError("`var_names` needs to be 'gene_symbols' or 'gene_ids'") + msg = "`var_names` needs to be 'gene_symbols' or 'gene_ids'" + raise ValueError(msg) if not is_legacy: adata.var["feature_types"] = genes[2].values barcodes = pd.read_csv(path / f"{prefix}barcodes.tsv{suffix}", header=None) @@ -667,11 +680,12 @@ def write( if ext is None: ext = ext_ elif ext != ext_: - raise ValueError( + msg = ( "It suffices to provide the file type by " "providing a proper extension to the filename." 'One of "txt", "csv", "h5" or "npz".' ) + raise ValueError(msg) else: key = filename ext = settings.file_format_data if ext is None else ext @@ -767,9 +781,8 @@ def _read( **kwargs, ): if ext is not None and ext not in avail_exts: - raise ValueError( - "Please provide one of the available extensions.\n" f"{avail_exts}" - ) + msg = f"Please provide one of the available extensions.\n{avail_exts}" + raise ValueError(msg) else: ext = is_valid_filename(filename, return_ext=True) is_present = _check_datafile_present_and_download(filename, backup_url=backup_url) @@ -793,7 +806,8 @@ def _read( return read_h5ad(path_cache) if not is_present: - raise FileNotFoundError(f"Did not find file {filename}.") + msg = f"Did not find file {filename}." + raise FileNotFoundError(msg) logg.debug(f"reading {filename}") if not cache and not suppress_cache_warning: logg.hint( @@ -803,7 +817,8 @@ def _read( # do the actual reading if ext == "xlsx" or ext == "xls": if sheet is None: - raise ValueError("Provide `sheet` parameter when reading '.xlsx' files.") + msg = "Provide `sheet` parameter when reading '.xlsx' files." + raise ValueError(msg) else: adata = read_excel(filename, sheet) elif ext in {"mtx", "mtx.gz"}: @@ -817,7 +832,7 @@ def _read( elif ext in {"txt", "tab", "data", "tsv"}: if ext == "data": logg.hint( - "... assuming '.data' means tab or white-space " "separated text file", + "... assuming '.data' means tab or white-space separated text file" ) logg.hint("change this by passing `ext` to sc.read") adata = read_text(filename, delimiter, first_column_names) @@ -826,7 +841,8 @@ def _read( elif ext == "loom": adata = read_loom(filename=filename, **kwargs) else: - raise ValueError(f"Unknown extension {ext}.") + msg = f"Unknown extension {ext}." + raise ValueError(msg) if cache: logg.info( f"... writing an {settings.file_format_data} " @@ -1091,11 +1107,10 @@ def is_valid_filename(filename: Path, *, return_ext: bool = False): return "mtx.gz" if return_ext else True elif not return_ext: return False - raise ValueError( - f"""\ + msg = f"""\ {filename!r} does not end on a valid extension. Please, provide one of the available extensions. {avail_exts} Text files with .gz and .bz2 extensions are also supported.\ """ - ) + raise ValueError(msg) diff --git a/src/scanpy/tools/_dendrogram.py b/src/scanpy/tools/_dendrogram.py index f60f0ae2e9..b31e792f31 100644 --- a/src/scanpy/tools/_dendrogram.py +++ b/src/scanpy/tools/_dendrogram.py @@ -124,15 +124,17 @@ def dendrogram( groupby = [groupby] for group in groupby: if group not in adata.obs_keys(): - raise ValueError( + msg = ( "groupby has to be a valid observation. " f"Given value: {group}, valid observations: {adata.obs_keys()}" ) + raise ValueError(msg) if not isinstance(adata.obs[group].dtype, CategoricalDtype): - raise ValueError( + msg = ( "groupby has to be a categorical observation. " f"Given value: {group}, Column type: {adata.obs[group].dtype}" ) + raise ValueError(msg) if var_names is None: rep_df = pd.DataFrame( @@ -188,7 +190,7 @@ def dendrogram( if inplace: if key_added is None: - key_added = f'dendrogram_{"_".join(groupby)}' + key_added = f"dendrogram_{'_'.join(groupby)}" logg.info(f"Storing dendrogram info using `.uns[{key_added!r}]`") adata.uns[key_added] = dat else: diff --git a/src/scanpy/tools/_diffmap.py b/src/scanpy/tools/_diffmap.py index d2bdcc647b..8554552252 100644 --- a/src/scanpy/tools/_diffmap.py +++ b/src/scanpy/tools/_diffmap.py @@ -77,11 +77,11 @@ def diffmap( neighbors_key = "neighbors" if neighbors_key not in adata.uns: - raise ValueError( - "You need to run `pp.neighbors` first to compute a neighborhood graph." - ) + msg = "You need to run `pp.neighbors` first to compute a neighborhood graph." + raise ValueError(msg) if n_comps <= 2: - raise ValueError("Provide any value greater than 2 for `n_comps`. ") + msg = "Provide any value greater than 2 for `n_comps`. " + raise ValueError(msg) adata = adata.copy() if copy else adata _diffmap( adata, n_comps=n_comps, neighbors_key=neighbors_key, random_state=random_state diff --git a/src/scanpy/tools/_dpt.py b/src/scanpy/tools/_dpt.py index c0fa59262f..e92fc726c6 100644 --- a/src/scanpy/tools/_dpt.py +++ b/src/scanpy/tools/_dpt.py @@ -18,7 +18,7 @@ def _diffmap(adata, n_comps=15, neighbors_key=None, random_state=0): - start = logg.info(f"computing Diffusion Maps using n_comps={n_comps}(=n_dcs)") + start = logg.info(f"computing Diffusion Maps using {n_comps=}(=n_dcs)") dpt = DPT(adata, neighbors_key=neighbors_key) dpt.compute_transitions() dpt.compute_eigen(n_comps=n_comps, random_state=random_state) @@ -129,7 +129,8 @@ def dpt( if neighbors_key is None: neighbors_key = "neighbors" if neighbors_key not in adata.uns: - raise ValueError("You need to run `pp.neighbors` and `tl.diffmap` first.") + msg = "You need to run `pp.neighbors` and `tl.diffmap` first." + raise ValueError(msg) if "iroot" not in adata.uns and "xroot" not in adata.var: logg.warning( "No root cell found. To compute pseudotime, pass the index or " @@ -152,7 +153,7 @@ def dpt( allow_kendall_tau_shift=allow_kendall_tau_shift, neighbors_key=neighbors_key, ) - start = logg.info(f"computing Diffusion Pseudotime using n_dcs={n_dcs}") + start = logg.info(f"computing Diffusion Pseudotime using {n_dcs=}") if n_branchings > 1: logg.info(" this uses a hierarchical implementation") if dpt.iroot is not None: @@ -262,7 +263,7 @@ def detect_branchings(self): """ logg.debug( f" detect {self.n_branchings} " - f'branching{"" if self.n_branchings == 1 else "s"}', + f"branching{'' if self.n_branchings == 1 else 's'}", ) # a segment is a subset of points of the data set (defined by the # indices of the points in the segment) @@ -799,9 +800,8 @@ def _detect_branching( elif self.flavor == "wolf17_bi" or self.flavor == "wolf17_bi_un": ssegs = self._detect_branching_single_wolf17_bi(Dseg, tips) else: - raise ValueError( - '`flavor` needs to be in {"haghverdi16", "wolf17_tri", "wolf17_bi"}.' - ) + msg = '`flavor` needs to be in {"haghverdi16", "wolf17_tri", "wolf17_bi"}.' + raise ValueError(msg) # make sure that each data point has a unique association with a segment masks = np.zeros((len(ssegs), Dseg.shape[0]), dtype=bool) for iseg, seg in enumerate(ssegs): @@ -1039,9 +1039,11 @@ def kendall_tau_split(self, a: np.ndarray, b: np.ndarray) -> int: Splitting index according to above description. """ if a.size != b.size: - raise ValueError("a and b need to have the same size") + msg = "a and b need to have the same size" + raise ValueError(msg) if a.ndim != b.ndim != 1: - raise ValueError("a and b need to be one-dimensional arrays") + msg = "a and b need to be one-dimensional arrays" + raise ValueError(msg) import scipy as sp min_length = 5 diff --git a/src/scanpy/tools/_draw_graph.py b/src/scanpy/tools/_draw_graph.py index aedd41f3d3..d0a70b3f4f 100644 --- a/src/scanpy/tools/_draw_graph.py +++ b/src/scanpy/tools/_draw_graph.py @@ -124,7 +124,8 @@ def draw_graph( """ start = logg.info(f"drawing single-cell graph using layout {layout!r}") if layout not in (layouts := get_literal_vals(_Layout)): - raise ValueError(f"Provide a valid layout, one of {layouts}.") + msg = f"Provide a valid layout, one of {layouts}." + raise ValueError(msg) adata = adata.copy() if copy else adata if adjacency is None: adjacency = _choose_graph(adata, obsp, neighbors_key) diff --git a/src/scanpy/tools/_embedding_density.py b/src/scanpy/tools/_embedding_density.py index 5ae69361dc..d539848b98 100644 --- a/src/scanpy/tools/_embedding_density.py +++ b/src/scanpy/tools/_embedding_density.py @@ -130,10 +130,11 @@ def embedding_density( basis = "draw_graph_fa" if f"X_{basis}" not in adata.obsm_keys(): - raise ValueError( + msg = ( "Cannot find the embedded representation " f"`adata.obsm['X_{basis}']`. Compute the embedding first." ) + raise ValueError(msg) if components is None: components = "1,2" @@ -142,17 +143,20 @@ def embedding_density( components = np.array(components).astype(int) - 1 if len(components) != 2: - raise ValueError("Please specify exactly 2 components, or `None`.") + msg = "Please specify exactly 2 components, or `None`." + raise ValueError(msg) if basis == "diffmap": components += 1 if groupby is not None: if groupby not in adata.obs: - raise ValueError(f"Could not find {groupby!r} `.obs` column.") + msg = f"Could not find {groupby!r} `.obs` column." + raise ValueError(msg) if adata.obs[groupby].dtype.name != "category": - raise ValueError(f"{groupby!r} column does not contain categorical data") + msg = f"{groupby!r} column does not contain categorical data" + raise ValueError(msg) # Define new covariate name if key_added is not None: diff --git a/src/scanpy/tools/_ingest.py b/src/scanpy/tools/_ingest.py index 3698067035..2a47e095a0 100644 --- a/src/scanpy/tools/_ingest.py +++ b/src/scanpy/tools/_ingest.py @@ -123,11 +123,12 @@ def ingest( # anndata version check anndata_version = pkg_version("anndata") if anndata_version < ANNDATA_MIN_VERSION: - raise ValueError( + msg = ( f"ingest only works correctly with anndata>={ANNDATA_MIN_VERSION} " f"(you have {anndata_version}) as prior to {ANNDATA_MIN_VERSION}, " "`AnnData.concatenate` did not concatenate `.obsm`." ) + raise ValueError(msg) start = logg.info("running ingest") obs = [obs] if isinstance(obs, str) else obs @@ -187,12 +188,13 @@ def __init__(self, dim, axis=0, vals=None): def __setitem__(self, key, value): if value.shape[self._axis] != self._dim: - raise ValueError( - f"Value passed for key '{key}' is of incorrect shape. " + msg = ( + f"Value passed for key {key!r} is of incorrect shape. " f"Value has shape {value.shape[self._axis]} " f"for dimension {self._axis} while " f"it should have {self._dim}." ) + raise ValueError(msg) self._data[key] = value def __getitem__(self, key): @@ -340,10 +342,11 @@ def __init__(self, adata: AnnData, neighbors_key: str | None = None): if neighbors_key in adata.uns: self._init_neighbors(adata, neighbors_key) else: - raise ValueError( + msg = ( f'There is no neighbors data in `adata.uns["{neighbors_key}"]`.\n' "Please run pp.neighbors." ) + raise ValueError(msg) if "X_umap" in adata.obsm: self._init_umap(adata) @@ -393,10 +396,11 @@ def fit(self, adata_new): new_var_names = adata_new.var_names.str.upper() if not ref_var_names.equals(new_var_names): - raise ValueError( + msg = ( "Variables in the new adata are different " "from variables in the reference adata" ) + raise ValueError(msg) self._obs = pd.DataFrame(index=adata_new.obs.index) self._obsm = _DimDict(adata_new.n_obs, axis=0) @@ -440,9 +444,8 @@ def map_embedding(self, method): elif method == "pca": self._obsm["X_pca"] = self._pca() else: - raise NotImplementedError( - "Ingest supports only umap and pca embeddings for now." - ) + msg = "Ingest supports only umap and pca embeddings for now." + raise NotImplementedError(msg) def _knn_classify(self, labels): # ensure it's categorical @@ -461,7 +464,8 @@ def map_labels(self, labels, method): if method == "knn": self._obs[labels] = self._knn_classify(labels) else: - raise NotImplementedError("Ingest supports knn labeling for now.") + msg = "Ingest supports knn labeling for now." + raise NotImplementedError(msg) @old_positionals("inplace") def to_adata(self, *, inplace: bool = False) -> AnnData | None: diff --git a/src/scanpy/tools/_leiden.py b/src/scanpy/tools/_leiden.py index f73ec1fd7d..9f1fbf23ef 100644 --- a/src/scanpy/tools/_leiden.py +++ b/src/scanpy/tools/_leiden.py @@ -120,19 +120,18 @@ def leiden( and `n_iterations`. """ if flavor not in {"igraph", "leidenalg"}: - raise ValueError( - f"flavor must be either 'igraph' or 'leidenalg', but '{flavor}' was passed" + msg = ( + f"flavor must be either 'igraph' or 'leidenalg', but {flavor!r} was passed" ) + raise ValueError(msg) _utils.ensure_igraph() if flavor == "igraph": if directed: - raise ValueError( - "Cannot use igraph’s leiden implementation with a directed graph." - ) + msg = "Cannot use igraph’s leiden implementation with a directed graph." + raise ValueError(msg) if partition_type is not None: - raise ValueError( - "Do not pass in partition_type argument when using igraph." - ) + msg = "Do not pass in partition_type argument when using igraph." + raise ValueError(msg) else: try: import leidenalg @@ -140,9 +139,8 @@ def leiden( msg = 'In the future, the default backend for leiden will be igraph instead of leidenalg.\n\n To achieve the future defaults please pass: flavor="igraph" and n_iterations=2. directed must also be False to work with igraph\'s implementation.' _utils.warn_once(msg, FutureWarning, stacklevel=3) except ImportError: - raise ImportError( - "Please install the leiden algorithm: `conda install -c conda-forge leidenalg` or `pip3 install leidenalg`." - ) + msg = "Please install the leiden algorithm: `conda install -c conda-forge leidenalg` or `pip3 install leidenalg`." + raise ImportError(msg) clustering_args = dict(clustering_args) start = logg.info("running Leiden clustering") diff --git a/src/scanpy/tools/_louvain.py b/src/scanpy/tools/_louvain.py index 470858ff38..50181229ab 100644 --- a/src/scanpy/tools/_louvain.py +++ b/src/scanpy/tools/_louvain.py @@ -143,9 +143,8 @@ def louvain( partition_kwargs = dict(partition_kwargs) start = logg.info("running Louvain clustering") if (flavor != "vtraag") and (partition_type is not None): - raise ValueError( - "`partition_type` is only a valid argument " 'when `flavour` is "vtraag"' - ) + msg = '`partition_type` is only a valid argument when `flavour` is "vtraag"' + raise ValueError(msg) adata = adata.copy() if copy else adata if adjacency is None: adjacency = _choose_graph(adata, obsp, neighbors_key) @@ -239,7 +238,8 @@ def louvain( for k, v in partition.items(): groups[k] = v else: - raise ValueError('`flavor` needs to be "vtraag" or "igraph" or "taynaud".') + msg = '`flavor` needs to be "vtraag" or "igraph" or "taynaud".' + raise ValueError(msg) if restrict_to is not None: if key_added == "louvain": key_added += "_R" diff --git a/src/scanpy/tools/_marker_gene_overlap.py b/src/scanpy/tools/_marker_gene_overlap.py index eb07b84885..1860fd73df 100644 --- a/src/scanpy/tools/_marker_gene_overlap.py +++ b/src/scanpy/tools/_marker_gene_overlap.py @@ -162,30 +162,35 @@ def marker_gene_overlap( """ # Test user inputs if inplace: - raise NotImplementedError( + msg = ( "Writing Pandas dataframes to h5ad is currently under development." "\nPlease use `inplace=False`." ) + raise NotImplementedError(msg) if key not in adata.uns: - raise ValueError( + msg = ( "Could not find marker gene data. " "Please run `sc.tl.rank_genes_groups()` first." ) + raise ValueError(msg) avail_methods = {"overlap_count", "overlap_coef", "jaccard", "enrich"} if method not in avail_methods: - raise ValueError(f"Method must be one of {avail_methods}.") + msg = f"Method must be one of {avail_methods}." + raise ValueError(msg) if normalize == "None": normalize = None avail_norm = {"reference", "data", None} if normalize not in avail_norm: - raise ValueError(f"Normalize must be one of {avail_norm}.") + msg = f"Normalize must be one of {avail_norm}." + raise ValueError(msg) if normalize is not None and method != "overlap_count": - raise ValueError("Can only normalize with method=`overlap_count`.") + msg = "Can only normalize with method=`overlap_count`." + raise ValueError(msg) if not all(isinstance(val, AbstractSet) for val in reference_markers.values()): try: @@ -193,18 +198,20 @@ def marker_gene_overlap( key: set(val) for key, val in reference_markers.items() } except Exception: - raise ValueError( + msg = ( "Please ensure that `reference_markers` contains " "sets or lists of markers as values." ) + raise ValueError(msg) if adj_pval_threshold is not None: if "pvals_adj" not in adata.uns[key]: - raise ValueError( + msg = ( "Could not find adjusted p-value data. " "Please run `sc.tl.rank_genes_groups()` with a " "method that outputs adjusted p-values." ) + raise ValueError(msg) if adj_pval_threshold < 0: logg.warning( diff --git a/src/scanpy/tools/_paga.py b/src/scanpy/tools/_paga.py index 98146b83e2..b7f1e86e5d 100644 --- a/src/scanpy/tools/_paga.py +++ b/src/scanpy/tools/_paga.py @@ -107,21 +107,22 @@ def paga( """ check_neighbors = "neighbors" if neighbors_key is None else neighbors_key if check_neighbors not in adata.uns: - raise ValueError( - "You need to run `pp.neighbors` first to compute a neighborhood graph." - ) + msg = "You need to run `pp.neighbors` first to compute a neighborhood graph." + raise ValueError(msg) if groups is None: for k in ("leiden", "louvain"): if k in adata.obs.columns: groups = k break if groups is None: - raise ValueError( + msg = ( "You need to run `tl.leiden` or `tl.louvain` to compute " "community labels, or specify `groups='an_existing_key'`" ) + raise ValueError(msg) elif groups not in adata.obs.columns: - raise KeyError(f"`groups` key {groups!r} not found in `adata.obs`.") + msg = f"`groups` key {groups!r} not found in `adata.obs`." + raise KeyError(msg) adata = adata.copy() if copy else adata _utils.sanitize_anndata(adata) @@ -170,9 +171,8 @@ def compute_connectivities(self): elif self._model == "v1.0": return self._compute_connectivities_v1_0() else: - raise ValueError( - f"`model` {self._model} needs to be one of {_AVAIL_MODELS}." - ) + msg = f"`model` {self._model} needs to be one of {_AVAIL_MODELS}." + raise ValueError(msg) def _compute_connectivities_v1_2(self): import igraph @@ -273,15 +273,17 @@ def compute_transitions(self): "The key 'velocyto_transitions' has been changed to 'velocity_graph'." ) else: - raise ValueError( + msg = ( "The passed AnnData needs to have an `uns` annotation " "with key 'velocity_graph' - a sparse matrix from RNA velocity." ) + raise ValueError(msg) if self._adata.uns[vkey].shape != (self._adata.n_obs, self._adata.n_obs): - raise ValueError( + msg = ( f"The passed 'velocity_graph' have shape {self._adata.uns[vkey].shape} " f"but shoud have shape {(self._adata.n_obs, self._adata.n_obs)}" ) + raise ValueError(msg) # restore this at some point # if 'expected_n_edges_random' not in self._adata.uns['paga']: # raise ValueError( diff --git a/src/scanpy/tools/_rank_genes_groups.py b/src/scanpy/tools/_rank_genes_groups.py index cafb78c6f1..05e5738d99 100644 --- a/src/scanpy/tools/_rank_genes_groups.py +++ b/src/scanpy/tools/_rank_genes_groups.py @@ -132,7 +132,8 @@ def __init__( adata_comp = adata if layer is not None: if use_raw: - raise ValueError("Cannot specify `layer` and have `use_raw=True`.") + msg = "Cannot specify `layer` and have `use_raw=True`." + raise ValueError(msg) X = adata_comp.layers[layer] else: if use_raw and adata.raw is not None: @@ -253,7 +254,8 @@ def t_test( # hack for overestimating the variance for small groups ns_rest = ns_group else: - raise ValueError("Method does not exist.") + msg = "Method does not exist." + raise ValueError(msg) # TODO: Come up with better solution. Mask unexpressed genes? # See https://github.com/scipy/scipy/issues/10269 @@ -369,7 +371,8 @@ def logreg( X = self.X[self.grouping_mask.values, :] if len(self.groups_order) == 1: - raise ValueError("Cannot perform logistic regression on a single cluster.") + msg = "Cannot perform logistic regression on a single cluster." + raise ValueError(msg) clf = LogisticRegression(**kwds) clf.fit(X, self.grouping.cat.codes) @@ -598,7 +601,8 @@ def rank_genes_groups( if use_raw is None: use_raw = adata.raw is not None elif use_raw is True and adata.raw is None: - raise ValueError("Received `use_raw=True`, but `adata.raw` is empty.") + msg = "Received `use_raw=True`, but `adata.raw` is empty." + raise ValueError(msg) if method is None: method = "t-test" @@ -608,11 +612,13 @@ def rank_genes_groups( start = logg.info("ranking genes") if method not in (avail_methods := get_literal_vals(_Method)): - raise ValueError(f"Method must be one of {avail_methods}.") + msg = f"Method must be one of {avail_methods}." + raise ValueError(msg) avail_corr = {"benjamini-hochberg", "bonferroni"} if corr_method not in avail_corr: - raise ValueError(f"Correction method must be one of {avail_corr}.") + msg = f"Correction method must be one of {avail_corr}." + raise ValueError(msg) adata = adata.copy() if copy else adata _utils.sanitize_anndata(adata) @@ -620,7 +626,8 @@ def rank_genes_groups( if groups == "all": groups_order = "all" elif isinstance(groups, str | int): - raise ValueError("Specify a sequence of groups") + msg = "Specify a sequence of groups" + raise ValueError(msg) else: groups_order = list(groups) if isinstance(groups_order[0], int): @@ -629,9 +636,8 @@ def rank_genes_groups( groups_order += [reference] if reference != "rest" and reference not in adata.obs[groupby].cat.categories: cats = adata.obs[groupby].cat.categories.tolist() - raise ValueError( - f"reference = {reference} needs to be one of groupby = {cats}." - ) + msg = f"reference = {reference} needs to be one of groupby = {cats}." + raise ValueError(msg) if key_added is None: key_added = "rank_genes_groups" diff --git a/src/scanpy/tools/_score_genes.py b/src/scanpy/tools/_score_genes.py index a40d9f3288..d0a33fdb97 100644 --- a/src/scanpy/tools/_score_genes.py +++ b/src/scanpy/tools/_score_genes.py @@ -38,7 +38,8 @@ def _sparse_nanmean( np.nanmean equivalent for sparse matrices """ if not issparse(X): - raise TypeError("X must be a sparse matrix") + msg = "X must be a sparse matrix" + raise TypeError(msg) # count the number of nan elements per row/column (dep. on axis) Z = X.copy() @@ -130,9 +131,8 @@ def score_genes( adata = adata.copy() if copy else adata use_raw = _check_use_raw(adata, use_raw, layer=layer) if is_backed_type(adata.X) and not use_raw: - raise NotImplementedError( - f"score_genes is not implemented for matrices of type {type(adata.X)}" - ) + msg = f"score_genes is not implemented for matrices of type {type(adata.X)}" + raise NotImplementedError(msg) if random_state is not None: np.random.seed(random_state) @@ -204,14 +204,16 @@ def _check_score_genes_args( if len(genes_to_ignore) > 0: logg.warning(f"genes are not in var_names and ignored: {genes_to_ignore}") if len(gene_list) == 0: - raise ValueError("No valid genes were passed for scoring.") + msg = "No valid genes were passed for scoring." + raise ValueError(msg) if gene_pool is None: gene_pool = var_names.astype("string") else: gene_pool = pd.Index(gene_pool, dtype="string").intersection(var_names) if len(gene_pool) == 0: - raise ValueError("No valid genes were passed for reference set.") + msg = "No valid genes were passed for reference set." + raise ValueError(msg) def get_subset(genes: pd.Index[str]): x = _get_obs_rep(adata, use_raw=use_raw, layer=layer) diff --git a/src/scanpy/tools/_sim.py b/src/scanpy/tools/_sim.py index 7410442952..a53575fa29 100644 --- a/src/scanpy/tools/_sim.py +++ b/src/scanpy/tools/_sim.py @@ -120,7 +120,7 @@ def add_args(p): "default": "", "metavar": "f", "type": str, - "help": "Specify a parameter file " '(default: "sim/${exkey}_params.txt")', + "help": 'Specify a parameter file (default: "sim/${exkey}_params.txt")', } } p = _utils.add_args(p, dadd_args) @@ -216,7 +216,7 @@ def sample_dynamic_data(**params): break logg.debug( f"mean nr of offdiagonal edges {nrOffEdges_list.mean()} " - f"compared to total nr {grnsim.dim * (grnsim.dim - 1) / 2.}" + f"compared to total nr {grnsim.dim * (grnsim.dim - 1) / 2.0}" ) # more complex models @@ -358,15 +358,13 @@ def write_data( for g in range(dim): if np.abs(Coupl[gp, g]) > 1e-10: f.write( - f"{names[gp]:10} " - f"{names[g]:10} " - f"{Coupl[gp, g]:10.3} \n" + f"{names[gp]:10} {names[g]:10} {Coupl[gp, g]:10.3} \n" ) # write simulated data # the binary mode option in the following line is a fix for python 3 # variable names if varNames: - header += f'{"it":>2} ' + header += f"{'it':>2} " for v in varNames: header += f"{v:>7} " with (dir / f"sim_{id}.txt").open("ab" if append else "wb") as f: @@ -429,7 +427,8 @@ def __init__( self.verbosity = verbosity # checks if initType not in ["branch", "random"]: - raise RuntimeError("initType must be either: branch, random") + msg = "initType must be either: branch, random" + raise RuntimeError(msg) if model not in self.availModels: message = "model not among predefined models \n" # noqa: F841 # TODO FIX # read from file @@ -437,7 +436,8 @@ def __init__( model = Path(sim_models.__file__).parent / f"{model}.txt" if not model.is_file(): - raise RuntimeError(f"Model file {model} does not exist") + msg = f"Model file {model} does not exist" + raise RuntimeError(msg) self.model = model # set the coupling matrix, and with that the adjacency matrix self.set_coupl(Coupl=Coupl) @@ -461,7 +461,8 @@ def sim_model(self, tmax, X0, noiseDyn=0, restart=0): elif self.modelType == "var": Xdiff = self.Xdiff_var(X[t - 1]) else: - raise ValueError(f"Unknown modelType {self.modelType!r}") + msg = f"Unknown modelType {self.modelType!r}" + raise ValueError(msg) X[t] = X[t - 1] + Xdiff # add dynamic noise X[t] += noiseDyn * np.random.randn(self.dim) @@ -501,7 +502,7 @@ def Xdiff_hill(self, Xt): ) if verbosity > 0: Xdiff_syn_tuple_str += ( - f'{"a" if v else "i"}' + f"{'a' if v else 'i'}" f"({self.pas[child][iv]}, {threshold:.2})" ) Xdiff_syn += Xdiff_syn_tuple @@ -853,12 +854,12 @@ def build_boolCoeff(self): for g in range(self.dim): if g in pasIndices: if np.abs(self.Coupl[self.varNames[key], g]) < 1e-10: - raise ValueError(f"specify coupling value for {key} <- {g}") + msg = f"specify coupling value for {key} <- {g}" + raise ValueError(msg) else: if np.abs(self.Coupl[self.varNames[key], g]) > 1e-10: - raise ValueError( - "there should be no coupling value for " f"{key} <- {g}" - ) + msg = f"there should be no coupling value for {key} <- {g}" + raise ValueError(msg) if self.verbosity > 1: settings.m(0, "..." + key) settings.m(0, rule) @@ -957,7 +958,7 @@ def _check_branching( check = False if check: Xsamples.append(X) - logg.debug(f'realization {restart}: {"" if check else "no"} new branch') + logg.debug(f"realization {restart}: {'' if check else 'no'} new branch") return check, Xsamples @@ -1047,9 +1048,8 @@ def sample_coupling_matrix( check = True break if not check: - raise ValueError( - "did not find graph without cycles after" f"{max_trial} trials" - ) + msg = f"did not find graph without cycles after {max_trial} trials" + raise ValueError(msg) return Coupl, Adj, Adj_signed, n_edges diff --git a/src/scanpy/tools/_umap.py b/src/scanpy/tools/_umap.py index 902171d58c..926e6d3d4f 100644 --- a/src/scanpy/tools/_umap.py +++ b/src/scanpy/tools/_umap.py @@ -164,9 +164,8 @@ def umap( if neighbors_key is None: # backwards compat neighbors_key = "neighbors" if neighbors_key not in adata.uns: - raise ValueError( - f"Did not find .uns[{neighbors_key!r}]. Run `sc.pp.neighbors` first." - ) + msg = f"Did not find .uns[{neighbors_key!r}]. Run `sc.pp.neighbors` first." + raise ValueError(msg) start = logg.info("computing UMAP") @@ -241,10 +240,11 @@ def umap( warnings.warn(msg, FutureWarning) metric = neigh_params.get("metric", "euclidean") if metric != "euclidean": - raise ValueError( + msg = ( f"`sc.pp.neighbors` was called with `metric` {metric!r}, " "but umap `method` 'rapids' only supports the 'euclidean' metric." ) + raise ValueError(msg) from cuml import UMAP n_neighbors = neighbors["params"]["n_neighbors"] diff --git a/src/scanpy/tools/_utils.py b/src/scanpy/tools/_utils.py index 97e2de0df1..4d24b5e276 100644 --- a/src/scanpy/tools/_utils.py +++ b/src/scanpy/tools/_utils.py @@ -32,9 +32,8 @@ def _choose_representation( if adata.n_vars > settings.N_PCS: if "X_pca" in adata.obsm: if n_pcs is not None and n_pcs > adata.obsm["X_pca"].shape[1]: - raise ValueError( - "`X_pca` does not have enough PCs. Rerun `sc.pp.pca` with adjusted `n_comps`." - ) + msg = "`X_pca` does not have enough PCs. Rerun `sc.pp.pca` with adjusted `n_comps`." + raise ValueError(msg) X = adata.obsm["X_pca"][:, :n_pcs] logg.info(f" using 'X_pca' with n_pcs = {X.shape[1]}") else: @@ -52,21 +51,23 @@ def _choose_representation( else: if use_rep in adata.obsm and n_pcs is not None: if n_pcs > adata.obsm[use_rep].shape[1]: - raise ValueError( + msg = ( f"{use_rep} does not have enough Dimensions. Provide a " "Representation with equal or more dimensions than" "`n_pcs` or lower `n_pcs` " ) + raise ValueError(msg) X = adata.obsm[use_rep][:, :n_pcs] elif use_rep in adata.obsm and n_pcs is None: X = adata.obsm[use_rep] elif use_rep == "X": X = adata.X else: - raise ValueError( + msg = ( f"Did not find {use_rep} in `.obsm.keys()`. " "You need to compute it first." ) + raise ValueError(msg) settings.verbosity = verbosity # resetting verbosity return X @@ -86,7 +87,7 @@ def preprocess_with_pca(adata, n_pcs: int | None = None, random_state=0): logg.info(" using data matrix X directly (no PCA)") return adata.X elif n_pcs is None and "X_pca" in adata.obsm_keys(): - logg.info(f' using \'X_pca\' with n_pcs = {adata.obsm["X_pca"].shape[1]}') + logg.info(f" using 'X_pca' with n_pcs = {adata.obsm['X_pca'].shape[1]}") return adata.obsm["X_pca"] elif "X_pca" in adata.obsm_keys() and adata.obsm["X_pca"].shape[1] >= n_pcs: logg.info(f" using 'X_pca' with n_pcs = {n_pcs}") @@ -128,5 +129,6 @@ def get_init_pos_from_paga( else: init_pos[subset] = group_pos else: - raise ValueError("Plot PAGA first, so that adata.uns['paga']" "with key 'pos'.") + msg = "Plot PAGA first, so that adata.uns['paga'] with key 'pos'." + raise ValueError(msg) return init_pos diff --git a/src/scanpy/tools/_utils_clustering.py b/src/scanpy/tools/_utils_clustering.py index 47f652fbdf..3c771e5d74 100644 --- a/src/scanpy/tools/_utils_clustering.py +++ b/src/scanpy/tools/_utils_clustering.py @@ -37,12 +37,12 @@ def restrict_adjacency( adjacency: spmatrix, ) -> tuple[spmatrix, NDArray[np.bool_]]: if not isinstance(restrict_categories[0], str): - raise ValueError( - "You need to use strings to label categories, " "e.g. '1' instead of 1." - ) + msg = "You need to use strings to label categories, e.g. '1' instead of 1." + raise ValueError(msg) for c in restrict_categories: if c not in adata.obs[restrict_key].cat.categories: - raise ValueError(f"'{c}' is not a valid category for '{restrict_key}'") + msg = f"{c!r} is not a valid category for {restrict_key!r}" + raise ValueError(msg) restrict_indices = adata.obs[restrict_key].isin(restrict_categories).values adjacency = adjacency[restrict_indices, :] adjacency = adjacency[:, restrict_indices] diff --git a/src/testing/scanpy/_pytest/__init__.py b/src/testing/scanpy/_pytest/__init__.py index 318baac1aa..e365a90495 100644 --- a/src/testing/scanpy/_pytest/__init__.py +++ b/src/testing/scanpy/_pytest/__init__.py @@ -75,8 +75,7 @@ def pytest_addoption(parser: pytest.Parser) -> None: action="store_true", default=False, help=( - "Run tests that retrieve stuff from the internet. " - "This increases test time." + "Run tests that retrieve stuff from the internet. This increases test time." ), ) @@ -131,6 +130,6 @@ def pytest_itemcollected(item: pytest.Item) -> None: ) -assert ( - "scanpy" not in sys.modules -), "scanpy is already imported, this will mess up test coverage" +assert "scanpy" not in sys.modules, ( + "scanpy is already imported, this will mess up test coverage" +) diff --git a/tests/conftest.py b/tests/conftest.py index 4cbe5ff53e..2d7f8e7aad 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -133,7 +133,8 @@ def save_and_compare(*path_parts: Path | os.PathLike, tol: int): plt.savefig(actual_pth, dpi=40) plt.close() if not expected_pth.is_file(): - raise OSError(f"No expected output found at {expected_pth}.") + msg = f"No expected output found at {expected_pth}." + raise OSError(msg) check_same_image(expected_pth, actual_pth, tol=tol) return save_and_compare diff --git a/tests/external/test_wishbone.py b/tests/external/test_wishbone.py index 7fadef63c6..db649a5b9d 100644 --- a/tests/external/test_wishbone.py +++ b/tests/external/test_wishbone.py @@ -22,6 +22,6 @@ def test_run_wishbone(): components=[2, 3], num_waypoints=150, ) - assert all( - [k in adata.obs for k in ["trajectory_wishbone", "branch_wishbone"]] - ), "Run Wishbone Error!" + assert all([k in adata.obs for k in ["trajectory_wishbone", "branch_wishbone"]]), ( + "Run Wishbone Error!" + ) diff --git a/tests/test_dendrogram.py b/tests/test_dendrogram.py index 18b952eff2..44a08fcf67 100644 --- a/tests/test_dendrogram.py +++ b/tests/test_dendrogram.py @@ -18,7 +18,7 @@ def test_dendrogram_key_added(groupby, key_added): adata = pbmc68k_reduced() sc.tl.dendrogram(adata, groupby=groupby, key_added=key_added, use_rep="X_pca") if isinstance(groupby, list): - dendrogram_key = f'dendrogram_{"_".join(groupby)}' + dendrogram_key = f"dendrogram_{'_'.join(groupby)}" else: dendrogram_key = f"dendrogram_{groupby}" diff --git a/tests/test_get.py b/tests/test_get.py index 673b26787d..05cb1b6a9d 100644 --- a/tests/test_get.py +++ b/tests/test_get.py @@ -24,7 +24,7 @@ def transpose_adata(adata: AnnData, *, expect_duplicates: bool = False) -> AnnDa TRANSPOSE_PARAMS = pytest.mark.parametrize( - "dim,transform,func", + ("dim", "transform", "func"), [ ("obs", lambda x, expect_duplicates=False: x, sc.get.obs_df), ("var", transpose_adata, sc.get.var_df), diff --git a/tests/test_highly_variable_genes.py b/tests/test_highly_variable_genes.py index 7d9fdac9fa..528a86ea99 100644 --- a/tests/test_highly_variable_genes.py +++ b/tests/test_highly_variable_genes.py @@ -629,7 +629,8 @@ def test_subset_inplace_consistency(flavor, array_type, batch_key): pass else: - raise ValueError(f"Unknown flavor {flavor}") + msg = f"Unknown flavor {flavor}" + raise ValueError(msg) n_genes = adata.shape[1] diff --git a/tests/test_normalization.py b/tests/test_normalization.py index 3acefe1bb1..9cf20c0b52 100644 --- a/tests/test_normalization.py +++ b/tests/test_normalization.py @@ -198,12 +198,12 @@ def _check_pearson_pca_fields(ad, n_cells, n_comps): "Missing `.uns` keys. Expected `['pearson_residuals_normalization', 'pca']`, " f"but only {list(ad.uns.keys())} were found" ) - assert ( - "X_pca" in ad.obsm - ), f"Missing `obsm` key `'X_pca'`, only {list(ad.obsm.keys())} were found" - assert ( - "PCs" in ad.varm - ), f"Missing `varm` key `'PCs'`, only {list(ad.varm.keys())} were found" + assert "X_pca" in ad.obsm, ( + f"Missing `obsm` key `'X_pca'`, only {list(ad.obsm.keys())} were found" + ) + assert "PCs" in ad.varm, ( + f"Missing `varm` key `'PCs'`, only {list(ad.varm.keys())} were found" + ) assert ad.obsm["X_pca"].shape == ( n_cells, n_comps, diff --git a/tests/test_rank_genes_groups.py b/tests/test_rank_genes_groups.py index 788c7e705d..b938fd2ca3 100644 --- a/tests/test_rank_genes_groups.py +++ b/tests/test_rank_genes_groups.py @@ -59,14 +59,12 @@ def get_example_data(array_type: Callable[[np.ndarray], Any]) -> AnnData: return adata -def get_true_scores() -> ( - tuple[ - NDArray[np.object_], - NDArray[np.object_], - NDArray[np.floating], - NDArray[np.floating], - ] -): +def get_true_scores() -> tuple[ + NDArray[np.object_], + NDArray[np.object_], + NDArray[np.floating], + NDArray[np.floating], +]: with (DATA_PATH / "objs_t_test.pkl").open("rb") as f: true_scores_t_test, true_names_t_test = pickle.load(f) with (DATA_PATH / "objs_wilcoxon.pkl").open("rb") as f: From fbb0692bee427d3b69e6ef7f3e6e54cfcdd79dee Mon Sep 17 00:00:00 2001 From: Zach McKenzie <92116279+zm711@users.noreply.github.com> Date: Wed, 15 Jan 2025 06:14:04 -0500 Subject: [PATCH 116/118] Grammar fixes in `sc.tl` docstrings (#3438) * typo and grammar fixes in docstrings only * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * revert dendogram docstring --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- src/scanpy/tools/_dendrogram.py | 10 +++++----- src/scanpy/tools/_diffmap.py | 18 +++++++++--------- src/scanpy/tools/_dpt.py | 20 ++++++++++---------- src/scanpy/tools/_draw_graph.py | 8 ++++---- src/scanpy/tools/_embedding_density.py | 2 +- src/scanpy/tools/_ingest.py | 4 ++-- src/scanpy/tools/_leiden.py | 8 ++++---- src/scanpy/tools/_louvain.py | 4 ++-- src/scanpy/tools/_marker_gene_overlap.py | 2 +- src/scanpy/tools/_score_genes.py | 4 ++-- src/scanpy/tools/_sim.py | 2 +- src/scanpy/tools/_top_genes.py | 4 ++-- src/scanpy/tools/_tsne.py | 2 +- 13 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/scanpy/tools/_dendrogram.py b/src/scanpy/tools/_dendrogram.py index b31e792f31..f33aca1ff7 100644 --- a/src/scanpy/tools/_dendrogram.py +++ b/src/scanpy/tools/_dendrogram.py @@ -60,8 +60,8 @@ def dendrogram( to compute a correlation matrix. The hierarchical clustering can be visualized using - :func:`scanpy.pl.dendrogram` or multiple other visualizations that can - include a dendrogram: :func:`~scanpy.pl.matrixplot`, + :func:`scanpy.pl.dendrogram` or multiple other visualizations + that can include a dendrogram: :func:`~scanpy.pl.matrixplot`, :func:`~scanpy.pl.heatmap`, :func:`~scanpy.pl.dotplot`, and :func:`~scanpy.pl.stacked_violin`. @@ -78,15 +78,15 @@ def dendrogram( {use_rep} var_names List of var_names to use for computing the hierarchical clustering. - If `var_names` is given, then `use_rep` and `n_pcs` is ignored. + If `var_names` is given, then `use_rep` and `n_pcs` are ignored. use_raw Only when `var_names` is not None. Use `raw` attribute of `adata` if present. cor_method - correlation method to use. + Correlation method to use. Options are 'pearson', 'kendall', and 'spearman' linkage_method - linkage method to use. See :func:`scipy.cluster.hierarchy.linkage` + Linkage method to use. See :func:`scipy.cluster.hierarchy.linkage` for more information. optimal_ordering Same as the optimal_ordering argument of :func:`scipy.cluster.hierarchy.linkage` diff --git a/src/scanpy/tools/_diffmap.py b/src/scanpy/tools/_diffmap.py index 8554552252..b69c2ef18f 100644 --- a/src/scanpy/tools/_diffmap.py +++ b/src/scanpy/tools/_diffmap.py @@ -23,9 +23,9 @@ def diffmap( """\ Diffusion Maps :cite:p:`Coifman2005,Haghverdi2015,Wolf2018`. - Diffusion maps :cite:p:`Coifman2005` has been proposed for visualizing single-cell - data by :cite:t:`Haghverdi2015`. The tool uses the adapted Gaussian kernel suggested - by :cite:t:`Haghverdi2016` in the implementation of :cite:t:`Wolf2018`. + Diffusion maps :cite:p:`Coifman2005` have been proposed for visualizing single-cell + data by :cite:t:`Haghverdi2015`. This tool uses the adapted Gaussian kernel suggested + by :cite:t:`Haghverdi2016` with the implementation of :cite:t:`Wolf2018`. The width ("sigma") of the connectivity kernel is implicitly determined by the number of neighbors used to compute the single-cell graph in @@ -42,12 +42,12 @@ def diffmap( n_comps The number of dimensions of the representation. neighbors_key - If not specified, diffmap looks .uns['neighbors'] for neighbors settings - and .obsp['connectivities'], .obsp['distances'] for connectivities and - distances respectively (default storage places for pp.neighbors). - If specified, diffmap looks .uns[neighbors_key] for neighbors settings and - .obsp[.uns[neighbors_key]['connectivities_key']], - .obsp[.uns[neighbors_key]['distances_key']] for connectivities and distances + If not specified, diffmap looks in .uns['neighbors'] for neighbors settings + and .obsp['connectivities'] and .obsp['distances'] for connectivities and + distances, respectively (default storage places for pp.neighbors). + If specified, diffmap looks in .uns[neighbors_key] for neighbors settings and + .obsp[.uns[neighbors_key]['connectivities_key']] and + .obsp[.uns[neighbors_key]['distances_key']] for connectivities and distances, respectively. random_state A numpy random seed diff --git a/src/scanpy/tools/_dpt.py b/src/scanpy/tools/_dpt.py index e92fc726c6..a9adc2a112 100644 --- a/src/scanpy/tools/_dpt.py +++ b/src/scanpy/tools/_dpt.py @@ -53,7 +53,7 @@ def dpt( :cite:p:`Haghverdi2016,Wolf2019`. Reconstruct the progression of a biological process from snapshot - data. `Diffusion Pseudotime` has been introduced by :cite:t:`Haghverdi2016` and + data. `Diffusion Pseudotime` was introduced by :cite:t:`Haghverdi2016` and implemented within Scanpy :cite:p:`Wolf2018`. Here, we use a further developed version, which is able to deal with disconnected graphs :cite:p:`Wolf2019` and can be run in a `hierarchical` mode by setting the parameter @@ -64,9 +64,9 @@ def dpt( adata.uns['iroot'] = np.flatnonzero(adata.obs['cell_types'] == 'Stem')[0] - This requires to run :func:`~scanpy.pp.neighbors`, first. In order to - reproduce the original implementation of DPT, use `method=='gauss'` in - this. Using the default `method=='umap'` only leads to minor quantitative + This requires running :func:`~scanpy.pp.neighbors`, first. In order to + reproduce the original implementation of DPT, use `method=='gauss'`. + Using the default `method=='umap'` only leads to minor quantitative differences, though. .. versionadded:: 1.1 @@ -96,12 +96,12 @@ def dpt( maximum correlation in Kendall tau criterion of :cite:t:`Haghverdi2016` to stabilize the splitting. neighbors_key - If not specified, dpt looks .uns['neighbors'] for neighbors settings - and .obsp['connectivities'], .obsp['distances'] for connectivities and - distances respectively (default storage places for pp.neighbors). - If specified, dpt looks .uns[neighbors_key] for neighbors settings and - .obsp[.uns[neighbors_key]['connectivities_key']], - .obsp[.uns[neighbors_key]['distances_key']] for connectivities and distances + If not specified, dpt looks in .uns['neighbors'] for neighbors settings + and .obsp['connectivities'] and .obsp['distances'] for connectivities and + distances, respectively (default storage places for pp.neighbors). + If specified, dpt looks in .uns[neighbors_key] for neighbors settings and + .obsp[.uns[neighbors_key]['connectivities_key']] and + .obsp[.uns[neighbors_key]['distances_key']] for connectivities and distances, respectively. copy Copy instance before computation and return a copy. diff --git a/src/scanpy/tools/_draw_graph.py b/src/scanpy/tools/_draw_graph.py index d0a70b3f4f..0727715671 100644 --- a/src/scanpy/tools/_draw_graph.py +++ b/src/scanpy/tools/_draw_graph.py @@ -56,14 +56,14 @@ def draw_graph( Force-directed graph drawing :cite:p:`Islam2011,Jacomy2014,Chippada2018`. An alternative to tSNE that often preserves the topology of the data - better. This requires to run :func:`~scanpy.pp.neighbors`, first. + better. This requires running :func:`~scanpy.pp.neighbors`, first. The default layout ('fa', `ForceAtlas2`, :cite:t:`Jacomy2014`) uses the package |fa2-modified|_ :cite:p:`Chippada2018`, which can be installed via `pip install fa2-modified`. `Force-directed graph drawing`_ describes a class of long-established algorithms for visualizing graphs. - It has been suggested for visualizing single-cell data by :cite:t:`Islam2011`. + It was suggested for visualizing single-cell data by :cite:t:`Islam2011`. Many other layouts as implemented in igraph :cite:p:`Csardi2006` are available. Similar approaches have been used by :cite:t:`Zunder2015` or :cite:t:`Weinreb2017`. @@ -98,9 +98,9 @@ def draw_graph( Use precomputed coordinates for initialization. If `False`/`None` (the default), initialize randomly. neighbors_key - If not specified, draw_graph looks .obsp['connectivities'] for connectivities + If not specified, draw_graph looks at .obsp['connectivities'] for connectivities (default storage place for pp.neighbors). - If specified, draw_graph looks + If specified, draw_graph looks at .obsp[.uns[neighbors_key]['connectivities_key']] for connectivities. obsp Use .obsp[obsp] as adjacency. You can't specify both diff --git a/src/scanpy/tools/_embedding_density.py b/src/scanpy/tools/_embedding_density.py index d539848b98..b930cc0aeb 100644 --- a/src/scanpy/tools/_embedding_density.py +++ b/src/scanpy/tools/_embedding_density.py @@ -70,7 +70,7 @@ def embedding_density( The annotated data matrix. basis The embedding over which the density will be calculated. This embedded - representation should be found in `adata.obsm['X_[basis]']``. + representation is found in `adata.obsm['X_[basis]']``. groupby Key for categorical observation/cell annotation for which densities are calculated per category. diff --git a/src/scanpy/tools/_ingest.py b/src/scanpy/tools/_ingest.py index 2a47e095a0..256e1a97c6 100644 --- a/src/scanpy/tools/_ingest.py +++ b/src/scanpy/tools/_ingest.py @@ -91,10 +91,10 @@ def ingest( The method to map labels in `adata_ref.obs` to `adata.obs`. The only supported value is 'knn'. neighbors_key - If not specified, ingest looks adata_ref.uns['neighbors'] + If not specified, ingest looks at adata_ref.uns['neighbors'] for neighbors settings and adata_ref.obsp['distances'] for distances (default storage places for pp.neighbors). - If specified, ingest looks adata_ref.uns[neighbors_key] for + If specified, ingest looks at adata_ref.uns[neighbors_key] for neighbors settings and adata_ref.obsp[adata_ref.uns[neighbors_key]['distances_key']] for distances. inplace diff --git a/src/scanpy/tools/_leiden.py b/src/scanpy/tools/_leiden.py index 9f1fbf23ef..cccd7f96ce 100644 --- a/src/scanpy/tools/_leiden.py +++ b/src/scanpy/tools/_leiden.py @@ -52,9 +52,9 @@ def leiden( Cluster cells using the Leiden algorithm :cite:p:`Traag2019`, an improved version of the Louvain algorithm :cite:p:`Blondel2008`. - It has been proposed for single-cell analysis by :cite:t:`Levine2015`. + It was proposed for single-cell analysis by :cite:t:`Levine2015`. - This requires having ran :func:`~scanpy.pp.neighbors` or + This requires having run :func:`~scanpy.pp.neighbors` or :func:`~scanpy.external.pp.bbknn` first. Parameters @@ -92,9 +92,9 @@ def leiden( :func:`~leidenalg.find_partition`. neighbors_key Use neighbors connectivities as adjacency. - If not specified, leiden looks .obsp['connectivities'] for connectivities + If not specified, leiden looks at .obsp['connectivities'] for connectivities (default storage place for pp.neighbors). - If specified, leiden looks + If specified, leiden looks at .obsp[.uns[neighbors_key]['connectivities_key']] for connectivities. obsp Use .obsp[obsp] as adjacency. You can't specify both diff --git a/src/scanpy/tools/_louvain.py b/src/scanpy/tools/_louvain.py index 50181229ab..1800dbe08e 100644 --- a/src/scanpy/tools/_louvain.py +++ b/src/scanpy/tools/_louvain.py @@ -69,10 +69,10 @@ def louvain( Cluster cells into subgroups :cite:p:`Blondel2008,Levine2015,Traag2017`. Cluster cells using the Louvain algorithm :cite:p:`Blondel2008` in the implementation - of :cite:t:`Traag2017`. The Louvain algorithm has been proposed for single-cell + of :cite:t:`Traag2017`. The Louvain algorithm was proposed for single-cell analysis by :cite:t:`Levine2015`. - This requires having ran :func:`~scanpy.pp.neighbors` or + This requires having run :func:`~scanpy.pp.neighbors` or :func:`~scanpy.external.pp.bbknn` first, or explicitly passing a ``adjacency`` matrix. diff --git a/src/scanpy/tools/_marker_gene_overlap.py b/src/scanpy/tools/_marker_gene_overlap.py index 1860fd73df..43408ff2c3 100644 --- a/src/scanpy/tools/_marker_gene_overlap.py +++ b/src/scanpy/tools/_marker_gene_overlap.py @@ -88,7 +88,7 @@ def marker_gene_overlap( inplace: bool = False, ): """\ - Calculate an overlap score between data-deriven marker genes and + Calculate an overlap score between data-derived marker genes and provided markers Marker gene overlap scores can be quoted as overlap counts, overlap diff --git a/src/scanpy/tools/_score_genes.py b/src/scanpy/tools/_score_genes.py index d0a33fdb97..7dff1a300c 100644 --- a/src/scanpy/tools/_score_genes.py +++ b/src/scanpy/tools/_score_genes.py @@ -79,8 +79,8 @@ def score_genes( """\ Score a set of genes :cite:p:`Satija2015`. - The score is the average expression of a set of genes subtracted with the - average expression of a reference set of genes. The reference set is + The score is the average expression of a set of genes after subtraction by + the average expression of a reference set of genes. The reference set is randomly sampled from the `gene_pool` for each binned expression value. This reproduces the approach in Seurat :cite:p:`Satija2015` and has been implemented diff --git a/src/scanpy/tools/_sim.py b/src/scanpy/tools/_sim.py index a53575fa29..f6ea2fede8 100644 --- a/src/scanpy/tools/_sim.py +++ b/src/scanpy/tools/_sim.py @@ -62,7 +62,7 @@ def sim( Sample from a stochastic differential equation model built from literature-curated boolean gene regulatory networks, as suggested by - :cite:t:`Wittmann2009`. The Scanpy implementation is due to :cite:t:`Wolf2018`. + :cite:t:`Wittmann2009`. The Scanpy implementation can be found in :cite:t:`Wolf2018`. Parameters ---------- diff --git a/src/scanpy/tools/_top_genes.py b/src/scanpy/tools/_top_genes.py index d66e9232f0..3b4e709b5f 100644 --- a/src/scanpy/tools/_top_genes.py +++ b/src/scanpy/tools/_top_genes.py @@ -38,7 +38,7 @@ def correlation_matrix( """\ Calculate correlation matrix. - Calculate a correlation matrix for genes strored in sample annotation + Calculate a correlation matrix for genes stored in sample annotation using :func:`~scanpy.tl.rank_genes_groups`. Parameters @@ -73,7 +73,7 @@ def correlation_matrix( spearman Spearman rank correlation annotation_key - Allows to define the name of the anndata entry where results are stored. + Allows defining the name of the anndata entry where results are stored. """ # TODO: At the moment, only works for int identifiers diff --git a/src/scanpy/tools/_tsne.py b/src/scanpy/tools/_tsne.py index 18e4a47f8e..62fa8b9d57 100644 --- a/src/scanpy/tools/_tsne.py +++ b/src/scanpy/tools/_tsne.py @@ -47,7 +47,7 @@ def tsne( """\ t-SNE :cite:p:`vanDerMaaten2008,Amir2013,Pedregosa2011`. - t-distributed stochastic neighborhood embedding (tSNE, :cite:t:`vanDerMaaten2008`) has been + t-distributed stochastic neighborhood embedding (tSNE, :cite:t:`vanDerMaaten2008`) was proposed for visualizating single-cell data by :cite:t:`Amir2013`. Here, by default, we use the implementation of *scikit-learn* :cite:p:`Pedregosa2011`. You can achieve a huge speedup and better convergence if you install Multicore-tSNE_ From 84a2c3939a956d2f9413c5a5298510dc1a9092b3 Mon Sep 17 00:00:00 2001 From: kaushal Date: Fri, 25 Oct 2024 08:53:13 +0530 Subject: [PATCH 117/118] updated for filter_cell --- src/scanpy/preprocessing/_simple.py | 70 +++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/src/scanpy/preprocessing/_simple.py b/src/scanpy/preprocessing/_simple.py index bbe20f13c9..25a20c5fa0 100644 --- a/src/scanpy/preprocessing/_simple.py +++ b/src/scanpy/preprocessing/_simple.py @@ -84,6 +84,36 @@ def get_cols_to_keep(indices, data, colcount, nthr, Flag): return counts # , keep_cols +# @numba.jit(cache=True,parallel=True) +def get_rows_to_keep_1(indptr, data): + lens = np.zeros(len(indptr) - 1, dtype=type(data[0])) + for i in range(len(lens)): + lens[i] = np.sum(data[indptr[i] : indptr[i + 1]]) + return lens + + +def get_rows_to_keep(indptr, dtype): + lens = indptr[1:] - indptr[:-1] + # lens.astype(dtype) + return lens + + +@numba.njit(cache=True, parallel=True) +def get_cols_to_keep(indices, data, colcount, nthr, Flag): + counts = np.zeros((nthr, colcount), dtype=type(data[0])) + for i in numba.prange(nthr): + start = i * indices.shape[0] // nthr + end = (i + 1) * indices.shape[0] // nthr + for j in range(start, end): + if data[j] != 0: # and indices[j]0,axis=1) + # number_per_cell = get_rows_to_keep(X.indptr,type(X.data[0])) elif isinstance(X, sp.sparse._csc.csc_matrix): nclos = X.shape[0] nthr = numba.get_num_threads() @@ -224,6 +258,8 @@ def filter_cells( X if min_genes is None and max_genes is None else X > 0, axis=1 ) + print("Number_per_Cell", time.time() - t0) + if issparse(X): number_per_cell = number_per_cell if min_number is not None: @@ -346,27 +382,52 @@ def filter_genes( if isinstance(X, sp.sparse._csr.csr_matrix): ncols = X.shape[1] nthr = numba.get_num_threads() + print( + "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH", + X.shape, + nthr, + X.indices.shape, + X.data.shape, + ) + # number_per_gene = get_cols_to_keep(X.indices, X.data, ncols, nthr) if min_cells is None and max_cells is None: number_per_gene = get_cols_to_keep(X.indices, X.data, ncols, nthr, False) else: number_per_gene = get_cols_to_keep(X.indices, X.data, ncols, nthr, True) elif isinstance(X, sp.sparse._csc.csc_matrix): + # ncols = X.shape[1] + # nthr = numba.get_num_threads() + print( + "HHHHHHHHHHHHHHHHHHcscHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH" + ) # X.shape,nthr,X.indices.shape,X.data.shape) + # number_per_gene = get_cols_to_keep(X.indices, X.data, ncols, nthr) if min_cells is None and max_cells is None: number_per_gene = get_rows_to_keep_1( X.indptr, X.data - ) + ) # get_cols_to_keep(X.indices, X.data, ncols, nthr,False) else: number_per_gene = get_rows_to_keep(X.indptr, type(X.data[0])) + # if isinstance(number_per_gene,np.matrix): + # number_per_gene=number_per_gene.A1 + # print("I am here") + + print("Cols to keep,", time.time() - t0) + # print(number_per_gene,type(number_per_gene),number_per_gene.shape,ncols) + # number_per_gene = axis_sum( + # X if min_cells is None and max_cells is None else X > 0, axis=0 + # ) + # print(number_per_gene.A1) else: + print("inside print") number_per_gene = axis_sum( X if min_cells is None and max_cells is None else X > 0, axis=0 ) if issparse(X): if isinstance(X, sp.sparse._csr.csr_matrix) or isinstance( X, sp.sparse._csc.csc_matrix - ): - number_per_gene = number_per_gene + ): # isinstance(X, sp.sparse._csr.csr_matrix): + number_per_gene = number_per_gene # cols_to_keep#number_per_gene else: number_per_gene = number_per_gene if min_number is not None: @@ -690,6 +751,7 @@ def normalize_per_cell( msg = "Can only be run with copy=True" raise ValueError(msg) cell_subset, counts_per_cell = filter_cells(X, min_counts=min_counts) + print(type(cell_subset), type(counts_per_cell)) X = X[cell_subset] counts_per_cell = counts_per_cell[cell_subset] if counts_per_cell_after is None: @@ -697,6 +759,8 @@ def normalize_per_cell( with warnings.catch_warnings(): warnings.simplefilter("ignore") counts_per_cell += counts_per_cell == 0 + print("!!!!!!!!!!!", type(counts_per_cell[0]), type(counts_per_cell_after)) + # counts_per_cell.astype(type(counts_per_cell_after)) counts_per_cell /= counts_per_cell_after if not issparse(X): X /= counts_per_cell[:, np.newaxis] From 49015423738b748987ffae847fbb5f36f2c8b1cb Mon Sep 17 00:00:00 2001 From: kaushal Date: Fri, 15 Nov 2024 13:43:33 +0530 Subject: [PATCH 118/118] print statment removal --- src/scanpy/preprocessing/_simple.py | 47 ++++------------------------- 1 file changed, 6 insertions(+), 41 deletions(-) diff --git a/src/scanpy/preprocessing/_simple.py b/src/scanpy/preprocessing/_simple.py index 25a20c5fa0..68a140d584 100644 --- a/src/scanpy/preprocessing/_simple.py +++ b/src/scanpy/preprocessing/_simple.py @@ -68,7 +68,7 @@ def get_rows_to_keep(indptr, dtype): return lens -@numba.njit(cache=True, parallel=True) +@njit() def get_cols_to_keep(indices, data, colcount, nthr, Flag): counts = np.zeros((nthr, colcount), dtype=type(data[0])) for i in numba.prange(nthr): @@ -94,11 +94,10 @@ def get_rows_to_keep_1(indptr, data): def get_rows_to_keep(indptr, dtype): lens = indptr[1:] - indptr[:-1] - # lens.astype(dtype) return lens -@numba.njit(cache=True, parallel=True) +@njit() def get_cols_to_keep(indices, data, colcount, nthr, Flag): counts = np.zeros((nthr, colcount), dtype=type(data[0])) for i in numba.prange(nthr): @@ -232,7 +231,6 @@ def filter_cells( X = data # proceed with processing the data matrix min_number = min_counts if min_genes is None else min_genes max_number = max_counts if max_genes is None else max_genes - print(type(X)) import time t0 = time.time() @@ -242,9 +240,6 @@ def filter_cells( else: number_per_cell = get_rows_to_keep(X.indptr, type(X.data[0])) - # and ( min_genes is not None or max_genes is not None) : - # #number_per_cell=np.sum(X>0,axis=1) - # number_per_cell = get_rows_to_keep(X.indptr,type(X.data[0])) elif isinstance(X, sp.sparse._csc.csc_matrix): nclos = X.shape[0] nthr = numba.get_num_threads() @@ -258,8 +253,6 @@ def filter_cells( X if min_genes is None and max_genes is None else X > 0, axis=1 ) - print("Number_per_Cell", time.time() - t0) - if issparse(X): number_per_cell = number_per_cell if min_number is not None: @@ -382,52 +375,27 @@ def filter_genes( if isinstance(X, sp.sparse._csr.csr_matrix): ncols = X.shape[1] nthr = numba.get_num_threads() - print( - "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH", - X.shape, - nthr, - X.indices.shape, - X.data.shape, - ) - # number_per_gene = get_cols_to_keep(X.indices, X.data, ncols, nthr) if min_cells is None and max_cells is None: number_per_gene = get_cols_to_keep(X.indices, X.data, ncols, nthr, False) else: number_per_gene = get_cols_to_keep(X.indices, X.data, ncols, nthr, True) elif isinstance(X, sp.sparse._csc.csc_matrix): - # ncols = X.shape[1] - # nthr = numba.get_num_threads() - print( - "HHHHHHHHHHHHHHHHHHcscHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH" - ) # X.shape,nthr,X.indices.shape,X.data.shape) - # number_per_gene = get_cols_to_keep(X.indices, X.data, ncols, nthr) if min_cells is None and max_cells is None: number_per_gene = get_rows_to_keep_1( X.indptr, X.data - ) # get_cols_to_keep(X.indices, X.data, ncols, nthr,False) + ) else: number_per_gene = get_rows_to_keep(X.indptr, type(X.data[0])) - # if isinstance(number_per_gene,np.matrix): - # number_per_gene=number_per_gene.A1 - # print("I am here") - - print("Cols to keep,", time.time() - t0) - # print(number_per_gene,type(number_per_gene),number_per_gene.shape,ncols) - # number_per_gene = axis_sum( - # X if min_cells is None and max_cells is None else X > 0, axis=0 - # ) - # print(number_per_gene.A1) else: - print("inside print") number_per_gene = axis_sum( X if min_cells is None and max_cells is None else X > 0, axis=0 ) if issparse(X): if isinstance(X, sp.sparse._csr.csr_matrix) or isinstance( X, sp.sparse._csc.csc_matrix - ): # isinstance(X, sp.sparse._csr.csr_matrix): - number_per_gene = number_per_gene # cols_to_keep#number_per_gene + ): + number_per_gene = number_per_gene else: number_per_gene = number_per_gene if min_number is not None: @@ -751,7 +719,6 @@ def normalize_per_cell( msg = "Can only be run with copy=True" raise ValueError(msg) cell_subset, counts_per_cell = filter_cells(X, min_counts=min_counts) - print(type(cell_subset), type(counts_per_cell)) X = X[cell_subset] counts_per_cell = counts_per_cell[cell_subset] if counts_per_cell_after is None: @@ -759,8 +726,6 @@ def normalize_per_cell( with warnings.catch_warnings(): warnings.simplefilter("ignore") counts_per_cell += counts_per_cell == 0 - print("!!!!!!!!!!!", type(counts_per_cell[0]), type(counts_per_cell_after)) - # counts_per_cell.astype(type(counts_per_cell_after)) counts_per_cell /= counts_per_cell_after if not issparse(X): X /= counts_per_cell[:, np.newaxis] @@ -1248,7 +1213,7 @@ def _downsample_total_counts(X, total_counts, random_state, replace): # TODO: can/should this be parallelized? -@numba.njit(cache=True) # noqa: TID251 +@njit() # noqa: TID251 def _downsample_array( col: np.ndarray, target: int,

!QJ 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 rrP8IfzZ;C_1PWD _LegendLoc | None: return request.param @@ -155,7 +160,7 @@ def vbounds(request): def test_missing_values_categorical( *, - fixture_request, + fixture_request: pytest.FixtureRequest, image_comparer, adata, plotfunc, @@ -182,7 +187,13 @@ def test_missing_values_categorical( def test_missing_values_continuous( - *, fixture_request, image_comparer, adata, plotfunc, na_color, legend_loc, vbounds + *, + fixture_request: pytest.FixtureRequest, + image_comparer, + adata, + plotfunc, + na_color, + vbounds, ): save_and_compare_images = partial(image_comparer, MISSING_VALUES_ROOT, tol=15) @@ -191,7 +202,6 @@ def test_missing_values_continuous( # Passing through a dict so it's easier to use default values kwargs = {} kwargs.update(vbounds) - kwargs["legend_loc"] = legend_loc if na_color is not None: kwargs["na_color"] = na_color From 3aff03a47a9752a20482718c0e4c975ad54f4c72 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 25 Jul 2024 13:27:46 +0200 Subject: [PATCH 014/118] Fix tests for dask PCA (#3162) --- src/testing/scanpy/_helpers/__init__.py | 8 +++- tests/test_highly_variable_genes.py | 4 +- tests/test_pca.py | 59 +++++++++++++++++-------- tests/test_preprocessing_distributed.py | 4 +- 4 files changed, 51 insertions(+), 24 deletions(-) diff --git a/src/testing/scanpy/_helpers/__init__.py b/src/testing/scanpy/_helpers/__init__.py index b85faec3f3..449eef9c57 100644 --- a/src/testing/scanpy/_helpers/__init__.py +++ b/src/testing/scanpy/_helpers/__init__.py @@ -6,12 +6,16 @@ import warnings from itertools import permutations +from typing import TYPE_CHECKING import numpy as np from anndata.tests.helpers import asarray, assert_equal import scanpy as sc +if TYPE_CHECKING: + from scanpy._compat import DaskArray + # TODO: Report more context on the fields being compared on error # TODO: Allow specifying paths to ignore on comparison @@ -124,13 +128,13 @@ def _check_check_values_warnings(function, adata, expected_warning, kwargs={}): # Delayed imports for case where we aren't using dask -def as_dense_dask_array(*args, **kwargs): +def as_dense_dask_array(*args, **kwargs) -> DaskArray: from anndata.tests.helpers import as_dense_dask_array return as_dense_dask_array(*args, **kwargs) -def as_sparse_dask_array(*args, **kwargs): +def as_sparse_dask_array(*args, **kwargs) -> DaskArray: from anndata.tests.helpers import as_sparse_dask_array return as_sparse_dask_array(*args, **kwargs) diff --git a/tests/test_highly_variable_genes.py b/tests/test_highly_variable_genes.py index a002a0ceb7..ab3996ff46 100644 --- a/tests/test_highly_variable_genes.py +++ b/tests/test_highly_variable_genes.py @@ -352,8 +352,8 @@ def test_compare_to_upstream( # noqa: PLR0917 array_type: Callable, ): if func == "fgd" and flavor == "cell_ranger": - msg = "The deprecated filter_genes_dispersion behaves differently with cell_ranger" - request.node.add_marker(pytest.mark.xfail(reason=msg)) + reason = "The deprecated filter_genes_dispersion behaves differently with cell_ranger" + request.applymarker(pytest.mark.xfail(reason=reason)) hvg_info = pd.read_csv(ref_path) pbmc = pbmc68k_reduced() diff --git a/tests/test_pca.py b/tests/test_pca.py index 90ec4648b4..961271a306 100644 --- a/tests/test_pca.py +++ b/tests/test_pca.py @@ -1,6 +1,7 @@ from __future__ import annotations import warnings +from functools import wraps from typing import TYPE_CHECKING import anndata as ad @@ -16,7 +17,7 @@ from scipy.sparse import issparse import scanpy as sc -from testing.scanpy._helpers import as_dense_dask_array, as_sparse_dask_array +from testing.scanpy import _helpers from testing.scanpy._helpers.data import pbmc3k_normalized from testing.scanpy._pytest.marks import needs from testing.scanpy._pytest.params import ( @@ -26,8 +27,11 @@ ) if TYPE_CHECKING: + from collections.abc import Callable from typing import Literal + from scanpy._compat import DaskArray + A_list = np.array( [ [0, 0, 7, 0, 0], @@ -62,7 +66,23 @@ ) -# If one uses dask for PCA it will always require dask-ml +def _chunked_1d( + f: Callable[[np.ndarray], DaskArray], +) -> Callable[[np.ndarray], DaskArray]: + @wraps(f) + def wrapper(a: np.ndarray) -> DaskArray: + da = f(a) + return da.rechunk((da.chunksize[0], -1)) + + return wrapper + + +DASK_CONVERTERS = { + f: _chunked_1d(f) + for f in (_helpers.as_dense_dask_array, _helpers.as_sparse_dask_array) +} + + @pytest.fixture( params=[ param_with(at, marks=[needs.dask_ml]) if "dask" in at.id else at @@ -70,6 +90,13 @@ ] ) def array_type(request: pytest.FixtureRequest): + # If one uses dask for PCA it will always require dask-ml. + # dask-ml can’t do 2D-chunked arrays, so rechunk them. + if as_dask_array := DASK_CONVERTERS.get(request.param): + return as_dask_array + + # When not using dask, just return the array type + assert "dask" not in request.param.__name__, "add more branches or refactor" return request.param @@ -92,8 +119,7 @@ def pca_params( expected_warning = None svd_solver = None if svd_solver_type is not None: - # TODO: are these right for sparse? - if array_type in {as_dense_dask_array, as_sparse_dask_array}: + if array_type in DASK_CONVERTERS.values(): svd_solver = ( {"auto", "full", "tsqr", "randomized"} if zero_center @@ -350,19 +376,19 @@ def test_mask_var_argument_equivalence(float_dtype, array_type): ) -def test_mask(array_type, request): - if array_type is as_dense_dask_array: - pytest.xfail("TODO: Dask arrays are not supported") +def test_mask(request: pytest.FixtureRequest, array_type): + if array_type in DASK_CONVERTERS.values(): + reason = "TODO: Dask arrays are not supported" + request.applymarker(pytest.mark.xfail(reason=reason)) adata = sc.datasets.blobs(n_variables=10, n_centers=3, n_observations=100) adata.X = array_type(adata.X) if isinstance(adata.X, np.ndarray) and Version(ad.__version__) < Version("0.9"): - request.node.add_marker( - pytest.mark.xfail( - reason="TODO: Previous version of anndata would return an F ordered array for one" - " case here, which suprisingly considerably changes the results of PCA. " - ) + reason = ( + "TODO: Previous version of anndata would return an F ordered array for one" + " case here, which surprisingly considerably changes the results of PCA." ) + request.applymarker(pytest.mark.xfail(reason=reason)) mask_var = np.random.choice([True, False], adata.shape[1]) adata_masked = adata[:, mask_var].copy() @@ -379,13 +405,10 @@ def test_mask(array_type, request): ) -def test_mask_order_warning(request): +def test_mask_order_warning(request: pytest.FixtureRequest): if Version(ad.__version__) >= Version("0.9"): - request.node.add_marker( - pytest.mark.xfail( - reason="Not expected to warn in later versions of anndata" - ) - ) + reason = "Not expected to warn in later versions of anndata" + request.applymarker(pytest.mark.xfail(reason=reason)) adata = ad.AnnData(X=np.random.randn(50, 5)) mask = np.array([True, False, True, False, True]) diff --git a/tests/test_preprocessing_distributed.py b/tests/test_preprocessing_distributed.py index 374c6c4b31..fcbe41c465 100644 --- a/tests/test_preprocessing_distributed.py +++ b/tests/test_preprocessing_distributed.py @@ -79,8 +79,8 @@ def test_normalize_per_cell( request: pytest.FixtureRequest, adata: AnnData, adata_dist: AnnData ): if isinstance(adata_dist.X, DaskArray): - msg = "normalize_per_cell deprecated and broken for Dask" - request.node.add_marker(pytest.mark.xfail(reason=msg)) + reason = "normalize_per_cell deprecated and broken for Dask" + request.applymarker(pytest.mark.xfail(reason=reason)) normalize_per_cell(adata_dist) assert isinstance(adata_dist.X, DIST_TYPES) result = materialize_as_ndarray(adata_dist.X) From b5ec2c56c3311090d60f6d3b11168e5991910f67 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 25 Jul 2024 13:50:06 +0200 Subject: [PATCH 015/118] Run benchmarks for off axis (#3147) --- benchmarks/README.md | 11 ++ benchmarks/asv.conf.json | 1 + benchmarks/benchmarks/_utils.py | 138 ++++++++++++++---- benchmarks/benchmarks/preprocessing_counts.py | 77 ++++++---- benchmarks/benchmarks/preprocessing_log.py | 31 ++-- 5 files changed, 189 insertions(+), 69 deletions(-) diff --git a/benchmarks/README.md b/benchmarks/README.md index f186cfa876..3546e79eaf 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -8,3 +8,14 @@ Benchmarks are run using the [benchmark bot][]. [asv]: https://asv.readthedocs.io/ [`benchmark.yml`]: ../.github/workflows/benchmark.yml [benchmark bot]: https://github.com/apps/scverse-benchmark + +## Data processing in benchmarks + +Each dataset is processed so it has + +- `.layers['counts']` (containing data in C/row-major format) and `.layers['counts-off-axis']` (containing data in FORTRAN/column-major format) +- `.X` and `.layers['off-axis']` with log-transformed data (formats like above) +- a `.var['mt']` boolean column indicating mitochondrial genes + +The benchmarks are set up so the `layer` parameter indicates the layer that will be moved into `.X` before the benchmark. +That way, we don’t need to add `layer=layer` everywhere. diff --git a/benchmarks/asv.conf.json b/benchmarks/asv.conf.json index b4fc26a9de..26591b490d 100644 --- a/benchmarks/asv.conf.json +++ b/benchmarks/asv.conf.json @@ -85,6 +85,7 @@ // "psutil": [""] "pooch": [""], "scikit-image": [""], + // "scikit-misc": [""], }, // Combinations of libraries/python versions can be excluded/included diff --git a/benchmarks/benchmarks/_utils.py b/benchmarks/benchmarks/_utils.py index 23404ce910..810ace74fd 100644 --- a/benchmarks/benchmarks/_utils.py +++ b/benchmarks/benchmarks/_utils.py @@ -1,5 +1,6 @@ from __future__ import annotations +import itertools import warnings from functools import cache from typing import TYPE_CHECKING @@ -7,23 +8,38 @@ import numpy as np import pooch from anndata import concat +from asv_runner.benchmarks.mark import skip_for_params +from scipy import sparse import scanpy as sc if TYPE_CHECKING: - from typing import Literal + from collections.abc import Callable, Sequence, Set + from typing import Literal, Protocol, TypeVar from anndata import AnnData + C = TypeVar("C", bound=Callable) + + class ParamSkipper(Protocol): + def __call__(self, **skipped: Set) -> Callable[[C], C]: ... + Dataset = Literal["pbmc68k_reduced", "pbmc3k", "bmmc", "lung93k"] + KeyX = Literal[None, "off-axis"] + KeyCount = Literal["counts", "counts-off-axis"] @cache def _pbmc68k_reduced() -> AnnData: + """A small datasets with a dense `.X`""" adata = sc.datasets.pbmc68k_reduced() + assert isinstance(adata.X, np.ndarray) + assert not np.isfortran(adata.X) + # raw has the same number of genes, so we can use it for counts # it doesn’t actually contain counts for some reason, but close enough - adata.layers["counts"] = adata.raw.X.copy() + assert isinstance(adata.raw.X, sparse.csr_matrix) + adata.layers["counts"] = adata.raw.X.toarray(order="C") mapper = dict( percent_mito="pct_counts_mt", n_counts="total_counts", @@ -39,10 +55,7 @@ def pbmc68k_reduced() -> AnnData: @cache def _pbmc3k() -> AnnData: adata = sc.datasets.pbmc3k() - adata.var["mt"] = adata.var_names.str.startswith("MT-") - sc.pp.calculate_qc_metrics( - adata, qc_vars=["mt"], percent_top=None, log1p=False, inplace=True - ) + assert isinstance(adata.X, sparse.csr_matrix) adata.layers["counts"] = adata.X.astype(np.int32, copy=True) sc.pp.log1p(adata) return adata @@ -76,12 +89,10 @@ def _bmmc(n_obs: int = 4000) -> AnnData: adata = concat(adatas, label="sample") adata.obs_names_make_unique() - adata.var["mt"] = adata.var_names.str.startswith("MT-") - sc.pp.calculate_qc_metrics( - adata, qc_vars=["mt"], percent_top=None, log1p=False, inplace=True - ) - adata.obs["n_counts"] = adata.X.sum(axis=1).A1 - + assert isinstance(adata.X, sparse.csr_matrix) + adata.layers["counts"] = adata.X.astype(np.int32, copy=True) + sc.pp.log1p(adata) + adata.obs["n_counts"] = adata.layers["counts"].sum(axis=1).A1 return adata @@ -95,33 +106,104 @@ def _lung93k() -> AnnData: url="https://figshare.com/ndownloader/files/45788454", known_hash="md5:4f28af5ff226052443e7e0b39f3f9212", ) - return sc.read_h5ad(path) + adata = sc.read_h5ad(path) + assert isinstance(adata.X, sparse.csr_matrix) + adata.layers["counts"] = adata.X.astype(np.int32, copy=True) + sc.pp.log1p(adata) + return adata def lung93k() -> AnnData: return _lung93k().copy() -def get_dataset(dataset: Dataset) -> tuple[AnnData, str | None]: - if dataset == "pbmc68k_reduced": - return pbmc68k_reduced(), None - if dataset == "pbmc3k": - return pbmc3k(), None # can’t use this with batches - if dataset == "bmmc": - # TODO: allow specifying bigger variant - return bmmc(400), "sample" - if dataset == "lung93k": - return lung93k(), "PatientNumber" +def to_off_axis(x: np.ndarray | sparse.csr_matrix) -> np.ndarray | sparse.csc_matrix: + if isinstance(x, sparse.csr_matrix): + return x.tocsc() + if isinstance(x, np.ndarray): + assert not np.isfortran(x) + return x.copy(order="F") + msg = f"Unexpected type {type(x)}" + raise TypeError(msg) + + +def _get_dataset_raw(dataset: Dataset) -> tuple[AnnData, str | None]: + match dataset: + case "pbmc68k_reduced": + adata, batch_key = pbmc68k_reduced(), None + case "pbmc3k": + adata, batch_key = pbmc3k(), None # can’t use this with batches + case "bmmc": + # TODO: allow specifying bigger variant + adata, batch_key = bmmc(400), "sample" + case "lung93k": + adata, batch_key = lung93k(), "PatientNumber" + case _: + msg = f"Unknown dataset {dataset}" + raise AssertionError(msg) + + # add off-axis layers + adata.layers["off-axis"] = to_off_axis(adata.X) + adata.layers["counts-off-axis"] = to_off_axis(adata.layers["counts"]) + + # add mitochondrial gene and pre-compute qc metrics + adata.var["mt"] = adata.var_names.str.startswith("MT-") + assert adata.var["mt"].sum() > 0, "no MT genes in dataset" + sc.pp.calculate_qc_metrics( + adata, qc_vars=["mt"], percent_top=None, log1p=False, inplace=True + ) - msg = f"Unknown dataset {dataset}" - raise AssertionError(msg) + return adata, batch_key + + +def get_dataset(dataset: Dataset, *, layer: KeyX = None) -> tuple[AnnData, str | None]: + adata, batch_key = _get_dataset_raw(dataset) + if layer is not None: + adata.X = adata.layers.pop(layer) + return adata, batch_key -def get_count_dataset(dataset: Dataset) -> tuple[AnnData, str | None]: - adata, batch_key = get_dataset(dataset) +def get_count_dataset( + dataset: Dataset, *, layer: KeyCount = "counts" +) -> tuple[AnnData, str | None]: + adata, batch_key = _get_dataset_raw(dataset) - adata.X = adata.layers.pop("counts") + adata.X = adata.layers.pop(layer) # remove indicators that X was transformed adata.uns.pop("log1p", None) return adata, batch_key + + +def param_skipper( + param_names: Sequence[str], params: tuple[Sequence[object], ...] +) -> ParamSkipper: + """Creates a decorator that will skip all combinations that contain any of the given parameters. + + Examples + -------- + + >>> param_names = ["letters", "numbers"] + >>> params = [["a", "b"], [3, 4, 5]] + >>> skip_when = param_skipper(param_names, params) + + >>> @skip_when(letters={"a"}, numbers={3}) + ... def func(a, b): + ... print(a, b) + >>> run_as_asv_benchmark(func) + b 4 + b 5 + """ + + def skip(**skipped: Set) -> Callable[[C], C]: + skipped_combs = [ + tuple(record.values()) + for record in ( + dict(zip(param_names, vals)) for vals in itertools.product(*params) + ) + if any(v in skipped.get(n, set()) for n, v in record.items()) + ] + # print(skipped_combs, file=sys.stderr) + return skip_for_params(skipped_combs) + + return skip diff --git a/benchmarks/benchmarks/preprocessing_counts.py b/benchmarks/benchmarks/preprocessing_counts.py index 28ed67934e..587b441e1c 100644 --- a/benchmarks/benchmarks/preprocessing_counts.py +++ b/benchmarks/benchmarks/preprocessing_counts.py @@ -14,7 +14,7 @@ if TYPE_CHECKING: from anndata import AnnData - from ._utils import Dataset + from ._utils import Dataset, KeyCount # setup variables @@ -22,31 +22,20 @@ batch_key: str | None -def setup(dataset: Dataset, *_): +def setup(dataset: Dataset, layer: KeyCount, *_): """Setup global variables before each benchmark.""" global adata, batch_key - adata, batch_key = get_count_dataset(dataset) + adata, batch_key = get_count_dataset(dataset, layer=layer) assert "log1p" not in adata.uns # ASV suite -params: list[Dataset] = ["pbmc68k_reduced", "pbmc3k"] -param_names = ["dataset"] - - -def time_calculate_qc_metrics(*_): - adata.var["mt"] = adata.var_names.str.startswith("MT-") - sc.pp.calculate_qc_metrics( - adata, qc_vars=["mt"], percent_top=None, log1p=False, inplace=True - ) - - -def peakmem_calculate_qc_metrics(*_): - adata.var["mt"] = adata.var_names.str.startswith("MT-") - sc.pp.calculate_qc_metrics( - adata, qc_vars=["mt"], percent_top=None, log1p=False, inplace=True - ) +params: tuple[list[Dataset], list[KeyCount]] = ( + ["pbmc68k_reduced", "pbmc3k"], + ["counts", "counts-off-axis"], +) +param_names = ["dataset", "layer"] def time_filter_cells(*_): @@ -73,19 +62,49 @@ def peakmem_scrublet(*_): sc.pp.scrublet(adata, batch_key=batch_key) -def time_normalize_total(*_): - sc.pp.normalize_total(adata, target_sum=1e4) +# Can’t do seurat v3 yet: https://github.com/conda-forge/scikit-misc-feedstock/issues/17 +""" +def time_hvg_seurat_v3(*_): + # seurat v3 runs on counts + sc.pp.highly_variable_genes(adata, flavor="seurat_v3_paper") + + +def peakmem_hvg_seurat_v3(*_): + sc.pp.highly_variable_genes(adata, flavor="seurat_v3_paper") +""" + + +class FastSuite: + """Suite for fast preprocessing operations.""" + + params: tuple[list[Dataset], list[KeyCount]] = ( + ["pbmc3k", "pbmc68k_reduced", "bmmc", "lung93k"], + ["counts", "counts-off-axis"], + ) + param_names = ["dataset", "layer"] + def time_calculate_qc_metrics(self, *_): + sc.pp.calculate_qc_metrics( + adata, qc_vars=["mt"], percent_top=None, log1p=False, inplace=True + ) -def peakmem_normalize_total(*_): - sc.pp.normalize_total(adata, target_sum=1e4) + def peakmem_calculate_qc_metrics(self, *_): + sc.pp.calculate_qc_metrics( + adata, qc_vars=["mt"], percent_top=None, log1p=False, inplace=True + ) + def time_normalize_total(self, *_): + sc.pp.normalize_total(adata, target_sum=1e4) -def time_log1p(*_): - # TODO: This would fail: assert "log1p" not in adata.uns, "ASV bug?" - # https://github.com/scverse/scanpy/issues/3052 - sc.pp.log1p(adata) + def peakmem_normalize_total(self, *_): + sc.pp.normalize_total(adata, target_sum=1e4) + def time_log1p(self, *_): + # TODO: This would fail: assert "log1p" not in adata.uns, "ASV bug?" + # https://github.com/scverse/scanpy/issues/3052 + adata.uns.pop("log1p", None) + sc.pp.log1p(adata) -def peakmem_log1p(*_): - sc.pp.log1p(adata) + def peakmem_log1p(self, *_): + adata.uns.pop("log1p", None) + sc.pp.log1p(adata) diff --git a/benchmarks/benchmarks/preprocessing_log.py b/benchmarks/benchmarks/preprocessing_log.py index 3819c17f62..6a04d4c7c6 100644 --- a/benchmarks/benchmarks/preprocessing_log.py +++ b/benchmarks/benchmarks/preprocessing_log.py @@ -7,17 +7,15 @@ from typing import TYPE_CHECKING -from asv_runner.benchmarks.mark import skip_for_params - import scanpy as sc from scanpy.preprocessing._utils import _get_mean_var -from ._utils import get_dataset +from ._utils import get_dataset, param_skipper if TYPE_CHECKING: from anndata import AnnData - from ._utils import Dataset + from ._utils import Dataset, KeyX # setup variables @@ -26,16 +24,21 @@ batch_key: str | None -def setup(dataset: Dataset, *_): +def setup(dataset: Dataset, layer: KeyX, *_): """Setup global variables before each benchmark.""" global adata, batch_key - adata, batch_key = get_dataset(dataset) + adata, batch_key = get_dataset(dataset, layer=layer) # ASV suite -params: list[Dataset] = ["pbmc68k_reduced", "pbmc3k"] -param_names = ["dataset"] +params: tuple[list[Dataset], list[KeyX]] = ( + ["pbmc68k_reduced", "pbmc3k"], + [None, "off-axis"], +) +param_names = ["dataset", "layer"] + +skip_when = param_skipper(param_names, params) def time_pca(*_): @@ -47,6 +50,7 @@ def peakmem_pca(*_): def time_highly_variable_genes(*_): + # the default flavor runs on log-transformed data sc.pp.highly_variable_genes(adata, min_mean=0.0125, max_mean=3, min_disp=0.5) @@ -55,12 +59,12 @@ def peakmem_highly_variable_genes(*_): # regress_out is very slow for this dataset -@skip_for_params([("pbmc3k",)]) +@skip_when(dataset={"pbmc3k"}) def time_regress_out(*_): sc.pp.regress_out(adata, ["total_counts", "pct_counts_mt"]) -@skip_for_params([("pbmc3k",)]) +@skip_when(dataset={"pbmc3k"}) def peakmem_regress_out(*_): sc.pp.regress_out(adata, ["total_counts", "pct_counts_mt"]) @@ -76,8 +80,11 @@ def peakmem_scale(*_): class FastSuite: """Suite for fast preprocessing operations.""" - params: list[Dataset] = ["pbmc3k", "pbmc68k_reduced", "bmmc", "lung93k"] - param_names = ["dataset"] + params: tuple[list[Dataset], list[KeyX]] = ( + ["pbmc3k", "pbmc68k_reduced", "bmmc", "lung93k"], + [None, "off-axis"], + ) + param_names = ["dataset", "layer"] def time_mean_var(self, *_): _get_mean_var(adata.X) From af38813a4f66bb5b0c8e9a8d50da46418e70b716 Mon Sep 17 00:00:00 2001 From: Severin Dicks <37635888+Intron7@users.noreply.github.com> Date: Thu, 25 Jul 2024 14:21:52 +0200 Subject: [PATCH 016/118] Fix `layers` parameter in `score_genes` with `.raw` (#3155) --- docs/release-notes/1.11.0.md | 1 + src/scanpy/_utils/__init__.py | 6 +++++- src/scanpy/plotting/_anndata.py | 4 +--- src/scanpy/tools/_score_genes.py | 2 +- tests/test_score_genes.py | 1 + 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/release-notes/1.11.0.md b/docs/release-notes/1.11.0.md index 8189632632..6baccacc16 100644 --- a/docs/release-notes/1.11.0.md +++ b/docs/release-notes/1.11.0.md @@ -4,6 +4,7 @@ ``` * Add layer argument to {func}`scanpy.tl.score_genes` and {func}`scanpy.tl.score_genes_cell_cycle` {pr}`2921` {smaller}`L Zappia` +* Prevent `raw` conflict with `layer` in {func}`~scanpy.tl.score_genes` {pr}`3155` {smaller}`S Dicks` ```{rubric} Docs ``` diff --git a/src/scanpy/_utils/__init__.py b/src/scanpy/_utils/__init__.py index 0cb0be0e11..9221f88ab5 100644 --- a/src/scanpy/_utils/__init__.py +++ b/src/scanpy/_utils/__init__.py @@ -247,7 +247,9 @@ def _check_array_function_arguments(**kwargs): ) -def _check_use_raw(adata: AnnData, use_raw: None | bool) -> bool: +def _check_use_raw( + adata: AnnData, use_raw: None | bool, *, layer: str | None = None +) -> bool: """ Normalize checking `use_raw`. @@ -255,6 +257,8 @@ def _check_use_raw(adata: AnnData, use_raw: None | bool) -> bool: """ if use_raw is not None: return use_raw + if layer is not None: + return False return adata.raw is not None diff --git a/src/scanpy/plotting/_anndata.py b/src/scanpy/plotting/_anndata.py index 9a80f2b65e..2ef36c88e3 100755 --- a/src/scanpy/plotting/_anndata.py +++ b/src/scanpy/plotting/_anndata.py @@ -2020,9 +2020,7 @@ def _prepare_dataframe( """ sanitize_anndata(adata) - use_raw = _check_use_raw(adata, use_raw) - if layer is not None: - use_raw = False + use_raw = _check_use_raw(adata, use_raw, layer=layer) if isinstance(var_names, str): var_names = [var_names] diff --git a/src/scanpy/tools/_score_genes.py b/src/scanpy/tools/_score_genes.py index d4f03686aa..20b66f3e60 100644 --- a/src/scanpy/tools/_score_genes.py +++ b/src/scanpy/tools/_score_genes.py @@ -122,7 +122,7 @@ def score_genes( """ start = logg.info(f"computing score {score_name!r}") adata = adata.copy() if copy else adata - use_raw = _check_use_raw(adata, use_raw) + use_raw = _check_use_raw(adata, use_raw, layer=layer) if is_backed_type(adata.X) and not use_raw: raise NotImplementedError( f"score_genes is not implemented for matrices of type {type(adata.X)}" diff --git a/tests/test_score_genes.py b/tests/test_score_genes.py index 60c49c2a5b..46f77701a5 100644 --- a/tests/test_score_genes.py +++ b/tests/test_score_genes.py @@ -251,6 +251,7 @@ def test_layer(): sc.tl.score_genes(adata, gene_set, score_name="X_score") # score layer (`del` makes sure it actually uses the layer) adata.layers["test"] = adata.X.copy() + adata.raw = adata del adata.X sc.tl.score_genes(adata, gene_set, score_name="test_score", layer="test") From cf7c2b89ce0798e6f29909ed81266d8bfff0ff45 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 26 Jul 2024 12:49:20 +0200 Subject: [PATCH 017/118] Refactor score_genes (#3170) --- src/scanpy/tools/_score_genes.py | 114 ++++++++++++++++++++++--------- tests/test_score_genes.py | 7 +- 2 files changed, 85 insertions(+), 36 deletions(-) diff --git a/src/scanpy/tools/_score_genes.py b/src/scanpy/tools/_score_genes.py index 20b66f3e60..a3909b7a28 100644 --- a/src/scanpy/tools/_score_genes.py +++ b/src/scanpy/tools/_score_genes.py @@ -15,7 +15,7 @@ from ..get import _get_obs_rep if TYPE_CHECKING: - from collections.abc import Sequence + from collections.abc import Callable, Generator, Sequence from typing import Literal from anndata import AnnData @@ -24,6 +24,12 @@ from .._utils import AnyRandom + try: + _StrIdx = pd.Index[str] + except TypeError: # Sphinx + _StrIdx = pd.Index + _GetSubset = Callable[[_StrIdx], np.ndarray | csr_matrix | csc_matrix] + def _sparse_nanmean( X: csr_matrix | csc_matrix, axis: Literal[0, 1] @@ -131,6 +137,66 @@ def score_genes( if random_state is not None: np.random.seed(random_state) + gene_list, gene_pool, get_subset = _check_score_genes_args( + adata, gene_list, gene_pool, use_raw=use_raw, layer=layer + ) + del use_raw, layer, random_state + + # Trying here to match the Seurat approach in scoring cells. + # Basically we need to compare genes against random genes in a matched + # interval of expression. + + control_genes = pd.Index([], dtype="string") + for r_genes in _score_genes_bins( + gene_list, + gene_pool, + ctrl_as_ref=ctrl_as_ref, + ctrl_size=ctrl_size, + n_bins=n_bins, + get_subset=get_subset, + ): + control_genes = control_genes.union(r_genes) + + if len(control_genes) == 0: + msg = "No control genes found in any cut." + if ctrl_as_ref: + msg += " Try setting `ctrl_as_ref=False`." + raise RuntimeError(msg) + + means_list, means_control = ( + _nan_means(get_subset(genes), axis=1, dtype="float64") + for genes in (gene_list, control_genes) + ) + score = means_list - means_control + + adata.obs[score_name] = pd.Series( + np.array(score).ravel(), index=adata.obs_names, dtype="float64" + ) + + logg.info( + " finished", + time=start, + deep=( + "added\n" + f" {score_name!r}, score of gene set (adata.obs).\n" + f" {len(control_genes)} total control genes are used." + ), + ) + return adata if copy else None + + +def _check_score_genes_args( + adata: AnnData, + gene_list: pd.Index[str] | Sequence[str], + gene_pool: pd.Index[str] | Sequence[str] | None, + *, + layer: str | None, + use_raw: bool, +) -> tuple[pd.Index[str], pd.Index[str], _GetSubset]: + """Restrict `gene_list` and `gene_pool` to present genes in `adata`. + + Also returns a function to get subset of `adata.X` based on a set of genes passed. + """ var_names = adata.raw.var_names if use_raw else adata.var_names gene_list = pd.Index([gene_list] if isinstance(gene_list, str) else gene_list) genes_to_ignore = gene_list.difference(var_names, sort=False) # first get missing @@ -147,10 +213,6 @@ def score_genes( if len(gene_pool) == 0: raise ValueError("No valid genes were passed for reference set.") - # Trying here to match the Seurat approach in scoring cells. - # Basically we need to compare genes against random genes in a matched - # interval of expression. - def get_subset(genes: pd.Index[str]): x = _get_obs_rep(adata, use_raw=use_raw, layer=layer) if len(genes) == len(var_names): @@ -158,6 +220,18 @@ def get_subset(genes: pd.Index[str]): idx = var_names.get_indexer(genes) return x[:, idx] + return gene_list, gene_pool, get_subset + + +def _score_genes_bins( + gene_list: pd.Index[str], + gene_pool: pd.Index[str], + *, + ctrl_as_ref: bool, + ctrl_size: int, + n_bins: int, + get_subset: _GetSubset, +) -> Generator[pd.Index[str], None, None]: # average expression of genes obs_avg = pd.Series(_nan_means(get_subset(gene_pool), axis=0), index=gene_pool) # Sometimes (and I don’t know how) missing data may be there, with NaNs for missing entries @@ -168,7 +242,6 @@ def get_subset(genes: pd.Index[str]): keep_ctrl_in_obs_cut = False if ctrl_as_ref else obs_cut.index.isin(gene_list) # now pick `ctrl_size` genes from every cut - control_genes = pd.Index([], dtype="string") for cut in np.unique(obs_cut.loc[gene_list]): r_genes: pd.Index[str] = obs_cut[(obs_cut == cut) & ~keep_ctrl_in_obs_cut].index if len(r_genes) == 0: @@ -181,34 +254,7 @@ def get_subset(genes: pd.Index[str]): r_genes = r_genes.to_series().sample(ctrl_size).index if ctrl_as_ref: # otherwise `r_genes` is already filtered r_genes = r_genes.difference(gene_list) - control_genes = control_genes.union(r_genes) - - if len(control_genes) == 0: - msg = "No control genes found in any cut." - if ctrl_as_ref: - msg += " Try setting `ctrl_as_ref=False`." - raise RuntimeError(msg) - - means_list, means_control = ( - _nan_means(get_subset(genes), axis=1, dtype="float64") - for genes in (gene_list, control_genes) - ) - score = means_list - means_control - - adata.obs[score_name] = pd.Series( - np.array(score).ravel(), index=adata.obs_names, dtype="float64" - ) - - logg.info( - " finished", - time=start, - deep=( - "added\n" - f" {score_name!r}, score of gene set (adata.obs).\n" - f" {len(control_genes)} total control genes are used." - ), - ) - return adata if copy else None + yield r_genes def _nan_means( diff --git a/tests/test_score_genes.py b/tests/test_score_genes.py index 46f77701a5..ddb4b1a3e4 100644 --- a/tests/test_score_genes.py +++ b/tests/test_score_genes.py @@ -274,15 +274,18 @@ def test_no_control_gene(): sc.tl.score_genes(adata, adata.var_names[:1], ctrl_size=1) -@pytest.mark.parametrize("ctrl_as_ref", [True, False]) +@pytest.mark.parametrize( + "ctrl_as_ref", [True, False], ids=["ctrl_as_ref", "no_ctrl_as_ref"] +) def test_gene_list_is_control(ctrl_as_ref: bool): np.random.seed(0) adata = sc.datasets.blobs(n_variables=10, n_observations=100, n_centers=20) + adata.var_names = "g" + adata.var_names with ( pytest.raises(RuntimeError, match=r"No control genes found in any cut") if ctrl_as_ref else nullcontext() ): sc.tl.score_genes( - adata, gene_list="3", ctrl_size=1, n_bins=5, ctrl_as_ref=ctrl_as_ref + adata, gene_list="g3", ctrl_size=1, n_bins=5, ctrl_as_ref=ctrl_as_ref ) From 2deca561105061efb3aed128098151d4953cd282 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 26 Jul 2024 14:42:58 +0200 Subject: [PATCH 018/118] Switch from using rubric in release notes (#3172) --- docs/conf.py | 14 +++++++++++++- docs/ecosystem.md | 8 -------- docs/index.md | 8 -------- docs/news.md | 6 ------ docs/release-notes/0.1.0.md | 1 + docs/release-notes/0.2.1.md | 1 + docs/release-notes/0.2.9.md | 4 ++-- docs/release-notes/0.3.0.md | 1 + docs/release-notes/0.3.2.md | 1 + docs/release-notes/0.4.0.md | 1 + docs/release-notes/0.4.2.md | 1 + docs/release-notes/0.4.3.md | 1 + docs/release-notes/0.4.4.md | 6 ++++++ docs/release-notes/1.0.0.md | 10 ++++------ docs/release-notes/1.1.0.md | 1 + docs/release-notes/1.10.0.md | 16 ++++++---------- docs/release-notes/1.10.1.md | 10 ++++------ docs/release-notes/1.10.2.md | 13 +++++-------- docs/release-notes/1.10.3.md | 13 +++++-------- docs/release-notes/1.11.0.md | 13 +++++-------- docs/release-notes/1.2.0.md | 1 + docs/release-notes/1.2.1.md | 4 ++-- docs/release-notes/1.3.1.md | 10 ++++------ docs/release-notes/1.3.3.md | 10 ++++------ docs/release-notes/1.3.4.md | 1 + docs/release-notes/1.3.5.md | 1 + docs/release-notes/1.3.6.md | 10 ++++------ docs/release-notes/1.3.7.md | 5 +++++ docs/release-notes/1.3.8.md | 5 +++++ docs/release-notes/1.4.1.md | 7 +++---- docs/release-notes/1.4.2.md | 10 ++++------ docs/release-notes/1.4.3.md | 7 +++---- docs/release-notes/1.4.4.md | 10 ++++------ docs/release-notes/1.4.5.md | 7 +++---- docs/release-notes/1.4.6.md | 10 ++++------ docs/release-notes/1.5.0.md | 19 +++++++------------ docs/release-notes/1.5.1.md | 4 ++-- docs/release-notes/1.6.0.md | 10 ++++------ docs/release-notes/1.7.0.md | 19 +++++++------------ docs/release-notes/1.7.1.md | 7 +++---- docs/release-notes/1.7.2.md | 7 +++---- docs/release-notes/1.8.0.md | 34 ++++++++++++++-------------------- docs/release-notes/1.8.1.md | 4 ++-- docs/release-notes/1.8.2.md | 10 ++++------ docs/release-notes/1.9.0.md | 16 ++++++---------- docs/release-notes/1.9.1.md | 5 ++--- docs/release-notes/1.9.2.md | 4 ++-- docs/release-notes/1.9.3.md | 4 ++-- docs/release-notes/1.9.4.md | 4 ++-- docs/release-notes/1.9.5.md | 4 ++-- docs/release-notes/1.9.6.md | 4 ++-- docs/release-notes/1.9.7.md | 4 ++-- docs/release-notes/1.9.8.md | 4 ++-- 53 files changed, 174 insertions(+), 216 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 30dde06a45..83e568ce5a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -2,10 +2,12 @@ import sys from datetime import datetime +from functools import partial from pathlib import Path from typing import TYPE_CHECKING import matplotlib # noqa +from docutils import nodes from packaging.version import Version # Don’t use tkinter agg when importing scanpy → … → matplotlib @@ -50,7 +52,14 @@ templates_path = ["_templates"] master_doc = "index" default_role = "literal" -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "**.ipynb_checkpoints"] +exclude_patterns = [ + "_build", + "Thumbs.db", + ".DS_Store", + "**.ipynb_checkpoints", + # exclude all 0.x.y.md files, but not index.md + "release-notes/[!i]*.md", +] extensions = [ "myst_nb", @@ -96,6 +105,7 @@ "html_admonition", ] myst_url_schemes = ("http", "https", "mailto", "ftp") +myst_heading_anchors = 3 nb_output_stderr = "remove" nb_execution_mode = "off" nb_merge_streams = True @@ -151,6 +161,8 @@ def setup(app: Sphinx): """App setup hook.""" + app.add_generic_role("small", partial(nodes.inline, classes=["small"])) + app.add_generic_role("smaller", partial(nodes.inline, classes=["smaller"])) app.add_config_value( "recommonmark_config", { diff --git a/docs/ecosystem.md b/docs/ecosystem.md index d78a5bd930..2c7aba9f9b 100644 --- a/docs/ecosystem.md +++ b/docs/ecosystem.md @@ -1,13 +1,5 @@ # Ecosystem -```{eval-rst} -.. role:: small -``` - -```{eval-rst} -.. role:: smaller -``` - ```{warning} We are no longer accepting new tools on this page. Instead, please submit your tool to the [scverse ecosystem package listing](https://scverse.org/packages/#ecosystem). diff --git a/docs/index.md b/docs/index.md index a8b49c72a4..4d648e8d39 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,14 +2,6 @@ :end-before: '## Citation' ``` -```{eval-rst} -.. role:: small -``` - -```{eval-rst} -.. role:: smaller -``` - ::::{grid} 1 2 3 3 :gutter: 2 diff --git a/docs/news.md b/docs/news.md index 5ff7f0b6d5..ac3bcd2856 100644 --- a/docs/news.md +++ b/docs/news.md @@ -1,12 +1,6 @@ (News)= - ## News -```{eval-rst} -.. role:: small - -``` - ### `rapids-singlecell` brings scanpy to the GPU! {small}`2024-03-18` diff --git a/docs/release-notes/0.1.0.md b/docs/release-notes/0.1.0.md index 181907de1a..c2b568ac69 100644 --- a/docs/release-notes/0.1.0.md +++ b/docs/release-notes/0.1.0.md @@ -1,3 +1,4 @@ +(v0.1.0)= ### 0.1.0 {small}`2017-05-17` Scanpy computationally outperforms and allows reproducing both the [Cell Ranger diff --git a/docs/release-notes/0.2.1.md b/docs/release-notes/0.2.1.md index 394a561398..c49fe1f264 100644 --- a/docs/release-notes/0.2.1.md +++ b/docs/release-notes/0.2.1.md @@ -1,3 +1,4 @@ +(v0.2.1)= ### 0.2.1 {small}`2017-07-24` Scanpy includes preprocessing, visualization, clustering, pseudotime and diff --git a/docs/release-notes/0.2.9.md b/docs/release-notes/0.2.9.md index 3d288c6a23..3ac14e9506 100644 --- a/docs/release-notes/0.2.9.md +++ b/docs/release-notes/0.2.9.md @@ -1,7 +1,7 @@ +(v0.2.9)= ### 0.2.9 {small}`2017-10-25` -```{rubric} Initial release of the new trajectory inference method [PAGA](https://github.com/theislab/paga) -``` +#### Initial release of the new trajectory inference method [PAGA](https://github.com/theislab/paga) - {func}`~scanpy.tl.paga` computes an abstracted, coarse-grained (PAGA) graph of the neighborhood graph {smaller}`A Wolf` - {func}`~scanpy.pl.paga_compare` plot this graph next an embedding {smaller}`A Wolf` diff --git a/docs/release-notes/0.3.0.md b/docs/release-notes/0.3.0.md index 9736c1bab0..7b3f48cc44 100644 --- a/docs/release-notes/0.3.0.md +++ b/docs/release-notes/0.3.0.md @@ -1,3 +1,4 @@ +(v0.3.0)= ### 0.3.0 {small}`2017-11-16` - {class}`~anndata.AnnData` gains method {meth}`~anndata.AnnData.concatenate` {smaller}`A Wolf` diff --git a/docs/release-notes/0.3.2.md b/docs/release-notes/0.3.2.md index bcdd791e22..deaa2c2d6f 100644 --- a/docs/release-notes/0.3.2.md +++ b/docs/release-notes/0.3.2.md @@ -1,3 +1,4 @@ +(v0.3.2)= ### 0.3.2 {small}`2017-11-29` - finding marker genes via {func}`~scanpy.pl.rank_genes_groups_violin` improved, diff --git a/docs/release-notes/0.4.0.md b/docs/release-notes/0.4.0.md index 4b5d789da8..870db9457e 100644 --- a/docs/release-notes/0.4.0.md +++ b/docs/release-notes/0.4.0.md @@ -1,3 +1,4 @@ +(v0.4.0)= ### 0.4.0 {small}`2017-12-23` - export to [SPRING] {cite:p}`Weinreb2017` for interactive visualization of data: diff --git a/docs/release-notes/0.4.2.md b/docs/release-notes/0.4.2.md index 2271f01bfb..7b832e6c9b 100644 --- a/docs/release-notes/0.4.2.md +++ b/docs/release-notes/0.4.2.md @@ -1,3 +1,4 @@ +(v0.4.2)= ### 0.4.2 {small}`2018-01-07` - amendments in [PAGA](https://github.com/theislab/paga) and its plotting functions {smaller}`A Wolf` diff --git a/docs/release-notes/0.4.3.md b/docs/release-notes/0.4.3.md index 2a5aedad78..1bff0701d1 100644 --- a/docs/release-notes/0.4.3.md +++ b/docs/release-notes/0.4.3.md @@ -1,3 +1,4 @@ +(v0.4.3)= ### 0.4.3 {small}`2018-02-09` - {func}`~scanpy.pl.clustermap`: heatmap from hierarchical clustering, diff --git a/docs/release-notes/0.4.4.md b/docs/release-notes/0.4.4.md index e69de29bb2..4ebe8392f6 100644 --- a/docs/release-notes/0.4.4.md +++ b/docs/release-notes/0.4.4.md @@ -0,0 +1,6 @@ +(v0.4.4)= +### 0.4.4 {small}`2018-02-26` + +- embed cells using {func}`~scanpy.tl.umap` {cite:p}`McInnes2018` {pr}`92` {smaller}`G Eraslan` +- score sets of genes, e.g. for cell cycle, using {func}`~scanpy.tl.score_genes` {cite:p}`Satija2015`: + [notebook](https://nbviewer.jupyter.org/github/theislab/scanpy_usage/blob/master/180209_cell_cycle/cell_cycle.ipynb) diff --git a/docs/release-notes/1.0.0.md b/docs/release-notes/1.0.0.md index 74ac0ea561..00fa8b43db 100644 --- a/docs/release-notes/1.0.0.md +++ b/docs/release-notes/1.0.0.md @@ -1,7 +1,7 @@ +(v1.0.0)= ### 1.0.0 {small}`2018-03-30` -```{rubric} Major updates -``` +#### Major updates - Scanpy is much faster and more memory efficient: preprocess, cluster and visualize 1.3M cells in [6h], 130K cells in [14min], and 68K cells in [3min] {smaller}`A Wolf` @@ -10,8 +10,7 @@ delegated {smaller}`A Wolf` ```{warning} -```{rubric} Upgrading to 1.0 isn’t fully backwards compatible in the following changes -``` +#### Upgrading to 1.0 isn’t fully backwards compatible in the following changes - the graph-based tools {func}`~scanpy.tl.louvain` {func}`~scanpy.tl.dpt` {func}`~scanpy.tl.draw_graph` @@ -35,8 +34,7 @@ some results might therefore look slightly different ``` -```{rubric} Further updates -``` +#### Further updates - UMAP {cite:p}`McInnes2018` can serve as a first visualization of the data just as tSNE, in contrast to tSNE, UMAP directly embeds the single-cell graph and is faster; diff --git a/docs/release-notes/1.1.0.md b/docs/release-notes/1.1.0.md index 85f22988c3..1d7cfb8a71 100644 --- a/docs/release-notes/1.1.0.md +++ b/docs/release-notes/1.1.0.md @@ -1,3 +1,4 @@ +(v1.1.0)= ### 1.1.0 {small}`2018-06-01` - {func}`~scanpy.set_figure_params` by default passes `vector_friendly=True` and allows you to produce reasonablly sized pdfs by rasterizing large scatter plots {smaller}`A Wolf` diff --git a/docs/release-notes/1.10.0.md b/docs/release-notes/1.10.0.md index a42d409f9f..0448d9fc5f 100644 --- a/docs/release-notes/1.10.0.md +++ b/docs/release-notes/1.10.0.md @@ -1,3 +1,4 @@ +(v1.10.0)= ### 1.10.0 {small}`2024-03-26` `scanpy` 1.10 brings a large amount of new features, performance improvements, and improved documentation. @@ -10,8 +11,7 @@ Some highlights: * Ability to `mask` observations or variables from a number of methods (see {doc}`/tutorials/plotting/advanced` for an example with plotting embeddings) * A new function {func}`~scanpy.get.aggregate` for computing aggregations of your data, very useful for pseudo bulking! -```{rubric} Features -``` +#### Features * {func}`~scanpy.pp.scrublet` and {func}`~scanpy.pp.scrublet_simulate_doublets` were moved from {mod}`scanpy.external.pp` to {mod}`scanpy.pp`. The `scrublet` implementation is now maintained as part of scanpy {pr}`2703` {smaller}`P Angerer` * {func}`scanpy.pp.pca`, {func}`scanpy.pp.scale`, {func}`scanpy.pl.embedding`, and {func}`scanpy.experimental.pp.normalize_pearson_residuals_pca` now support a `mask` parameter {pr}`2272` {smaller}`C Bright, T Marcella, & P Angerer` @@ -32,8 +32,7 @@ Some highlights: * {func}`scanpy.pp.scale` now clips `np.ndarray` also at `- max_value` for zero-centering {pr}`2913` {smaller}`S Dicks` * Support sparse chunks in dask {func}`~scanpy.pp.scale`, {func}`~scanpy.pp.normalize_total` and {func}`~scanpy.pp.highly_variable_genes` (`seurat` and `cell-ranger` tested) {pr}`2856` {smaller}`ilan-gold` -```{rubric} Docs -``` +#### Docs * Doc style overhaul {pr}`2220` {smaller}`A Gayoso` * Re-add search-as-you-type, this time via `readthedocs-sphinx-search` {pr}`2805` {smaller}`P Angerer` @@ -44,8 +43,7 @@ Some highlights: * Overhauled {doc}`/tutorials/index` page, and added new {doc}`/how-to/index` section to docs {pr}`2901` {smaller}`I Virshup` * Added a new tutorial on working with dask ({doc}`/tutorials/experimental/dask`) {pr}`2901` {smaller}`I Gold` {smaller}`I Virshup` -```{rubric} Bug fixes -``` +#### Bug fixes * Updated {func}`~scanpy.read_visium` such that it can read spaceranger 2.0 files {smaller}`L Lehner` * Fix {func}`~scanpy.pp.normalize_total` for dask {pr}`2466` {smaller}`P Angerer` @@ -61,14 +59,12 @@ Some highlights: * Fix pytest deprecation warning {pr}`2879` {smaller}`P Angerer` -```{rubric} Development -``` +#### Development * Scanpy is now tested against python 3.12 {pr}`2863` {smaller}`ivirshup` * Fix testing package build {pr}`2468` {smaller}`P Angerer` -```{rubric} Deprecations -``` +#### Deprecations * Dropped support for Python 3.8. [More details here](https://numpy.org/neps/nep-0029-deprecation_policy.html). {pr}`2695` {smaller}`P Angerer` * Deprecated specifying large numbers of function parameters by position as opposed to by name/keyword in all public APIs. diff --git a/docs/release-notes/1.10.1.md b/docs/release-notes/1.10.1.md index 6e9414c9bf..35f631bdc0 100644 --- a/docs/release-notes/1.10.1.md +++ b/docs/release-notes/1.10.1.md @@ -1,16 +1,14 @@ +(v1.10.1)= ### 1.10.1 {small}`2024-04-09` -```{rubric} Docs -``` +#### Docs * Added {doc}`how-to example ` on plotting with [Marsilea](https://marsilea.readthedocs.io) {pr}`2974` {smaller}`Y Zheng` -```{rubric} Bug fixes -``` +#### Bug fixes * Fix `aggregate` when aggregating by more than two groups {pr}`2965` {smaller}`I Virshup` -```{rubric} Performance -``` +#### Performance * {func}`~scanpy.pp.scale` now uses numba kernels for `sparse.csr_matrix` and `sparse.csc_matrix` when `zero_center==False` and `mask_obs` is provided. This greatly speed up execution {pr}`2942` {smaller}`S Dicks` diff --git a/docs/release-notes/1.10.2.md b/docs/release-notes/1.10.2.md index 586cde1d55..8e0342054b 100644 --- a/docs/release-notes/1.10.2.md +++ b/docs/release-notes/1.10.2.md @@ -1,12 +1,11 @@ +(v1.10.2)= ### 1.10.2 {small}`2024-06-25` -```{rubric} Development features -``` +#### Development features * Add performance benchmarking {pr}`2977` {smaller}`R Shrestha`, {smaller}`P Angerer` -```{rubric} Docs -``` +#### Docs * Document several missing parameters in docstring {pr}`2888` {smaller}`S Cheney` * Fixed incorrect instructions in "testing" dev docs {pr}`2994` {smaller}`I Virshup` @@ -14,8 +13,7 @@ * Fixed citations {pr}`3032` {smaller}`P Angerer` * Improve dataset documentation {pr}`3060` {smaller}`P Angerer` -```{rubric} Bug fixes -``` +#### Bug fixes * Compatibility with `matplotlib` 3.9 {pr}`2999` {smaller}`I Virshup` * Add clear errors where `backed` mode-like matrices (i.e., from `sparse_dataset`) are not supported {pr}`3048` {smaller}`I gold` @@ -24,8 +22,7 @@ * Fix zappy support {pr}`3089` {smaller}`P Angerer` * Fix dotplot group order with {mod}`pandas` 1.x {pr}`3101` {smaller}`P Angerer` -```{rubric} Performance -``` +#### Performance * `sparse_mean_variance_axis` now uses all cores for the calculations {pr}`3015` {smaller}`S Dicks` * `pp.highly_variable_genes` with `flavor=seurat_v3` now uses a numba kernel {pr}`3017` {smaller}`S Dicks` diff --git a/docs/release-notes/1.10.3.md b/docs/release-notes/1.10.3.md index 29ff234af5..bbb8edbc8c 100644 --- a/docs/release-notes/1.10.3.md +++ b/docs/release-notes/1.10.3.md @@ -1,18 +1,15 @@ +(v1.10.3)= ### 1.10.3 {small}`the future` -```{rubric} Development features -``` +#### Development features -```{rubric} Docs -``` +#### Docs -```{rubric} Bug fixes -``` +#### Bug fixes * Prevent empty control gene set in {func}`~scanpy.tl.score_genes` {pr}`2875` {smaller}`M Müller` * Fix `subset=True` of {func}`~scanpy.pp.highly_variable_genes` when `flavor` is `seurat` or `cell_ranger`, and `batch_key!=None` {pr}`3042` {smaller}`E Roellin` * Add compatibility with {mod}`numpy` 2.0 {pr}`3065` and {pr}`3115` {smaller}`P Angerer` * Fix `legend_loc` argument in {func}`scanpy.pl.embedding` not accepting matplotlib parameters {pr}`3163` {smaller}`P Angerer` -```{rubric} Performance -``` +#### Performance diff --git a/docs/release-notes/1.11.0.md b/docs/release-notes/1.11.0.md index 6baccacc16..fee2d0b1a9 100644 --- a/docs/release-notes/1.11.0.md +++ b/docs/release-notes/1.11.0.md @@ -1,16 +1,13 @@ +(v1.11.0)= ### 1.11.0 {small}`the future` -```{rubric} Features -``` +#### Features * Add layer argument to {func}`scanpy.tl.score_genes` and {func}`scanpy.tl.score_genes_cell_cycle` {pr}`2921` {smaller}`L Zappia` * Prevent `raw` conflict with `layer` in {func}`~scanpy.tl.score_genes` {pr}`3155` {smaller}`S Dicks` -```{rubric} Docs -``` +#### Docs -```{rubric} Bug fixes -``` +#### Bug fixes -```{rubric} Deprecations -``` +#### Deprecations diff --git a/docs/release-notes/1.2.0.md b/docs/release-notes/1.2.0.md index 5bd2ed451e..973b59775c 100644 --- a/docs/release-notes/1.2.0.md +++ b/docs/release-notes/1.2.0.md @@ -1,3 +1,4 @@ +(v1.2.0)= ### 1.2.0 {small}`2018-06-08` - {func}`~scanpy.tl.paga` improved, see [PAGA](https://github.com/theislab/paga); the default model changed, restore the previous default model by passing `model='v1.0'` diff --git a/docs/release-notes/1.2.1.md b/docs/release-notes/1.2.1.md index 3110537aa8..5979029098 100644 --- a/docs/release-notes/1.2.1.md +++ b/docs/release-notes/1.2.1.md @@ -1,6 +1,6 @@ +(v1.2.1)= ### 1.2.1 {small}`2018-06-08` -~~~{rubric} Plotting of {ref}`pl-generic` marker genes and quality control. -~~~ +#### Plotting of {ref}`pl-generic` marker genes and quality control. - {func}`~scanpy.pl.highest_expr_genes` for quality control; plot genes with highest mean fraction of cells, similar to `plotQC` of *Scater* {cite:p}`McCarthy2017` {pr}`169` {smaller}`F Ramirez` diff --git a/docs/release-notes/1.3.1.md b/docs/release-notes/1.3.1.md index 8492d6b9e6..829e56ec26 100644 --- a/docs/release-notes/1.3.1.md +++ b/docs/release-notes/1.3.1.md @@ -1,20 +1,18 @@ +(v1.3.1)= ### 1.3.1 {small}`2018-09-03` -```{rubric} RNA velocity in single cells {cite:p}`LaManno2018` -``` +#### RNA velocity in single cells {cite:p}`LaManno2018` - Scanpy and AnnData support loom’s layers so that computations for single-cell RNA velocity {cite:p}`LaManno2018` become feasible {smaller}`S Rybakov and V Bergen` - [scvelo] harmonizes with Scanpy and is able to process loom files with splicing information produced by Velocyto {cite:p}`LaManno2018`, it runs a lot faster than the count matrix analysis of Velocyto and provides several conceptual developments -~~~{rubric} Plotting ({ref}`pl-generic`) -~~~ +#### Plotting ({ref}`pl-generic`) - {func}`~scanpy.pl.dotplot` for visualizing genes across conditions and clusters, see [here](https://gist.github.com/fidelram/2289b7a8d6da055fb058ac9a79ed485c) {pr}`199` {smaller}`F Ramirez` - {func}`~scanpy.pl.heatmap` for pretty heatmaps {pr}`175` {smaller}`F Ramirez` - {func}`~scanpy.pl.violin` produces very compact overview figures with many panels {pr}`175` {smaller}`F Ramirez` -~~~{rubric} There now is a section on imputation in {doc}`external <../external/index>`: -~~~ +#### There now is a section on imputation in {doc}`external <../external/index>`: - {func}`~scanpy.external.pp.magic` for imputation using data diffusion {cite:p}`vanDijk2018` {pr}`187` {smaller}`S Gigante` - {func}`~scanpy.external.pp.dca` for imputation and latent space construction using an autoencoder {cite:p}`Eraslan2019` {pr}`186` {smaller}`G Eraslan` diff --git a/docs/release-notes/1.3.3.md b/docs/release-notes/1.3.3.md index f94e3c5dec..fd898ec4eb 100644 --- a/docs/release-notes/1.3.3.md +++ b/docs/release-notes/1.3.3.md @@ -1,18 +1,16 @@ +(v1.3.3)= ### 1.3.3 {small}`2018-11-05` -```{rubric} Major updates -``` +#### Major updates - a fully distributed preprocessing backend {smaller}`T White and the Laserson Lab` -```{rubric} Code design -``` +#### Code design - {func}`~scanpy.read_10x_h5` and {func}`~scanpy.read_10x_mtx` read Cell Ranger 3.0 outputs {pr}`334` {smaller}`Q Gong` ```{note} -```{rubric} Also see changes in anndata 0.6. -``` +#### Also see changes in anndata 0.6. - changed default compression to `None` in {meth}`~anndata.AnnData.write_h5ad` to speed up read and write, disk space use is usually less critical - performance gains in {meth}`~anndata.AnnData.write_h5ad` due to better handling of strings and categories {smaller}`S Rybakov` diff --git a/docs/release-notes/1.3.4.md b/docs/release-notes/1.3.4.md index ab4a9b599b..9381bc4647 100644 --- a/docs/release-notes/1.3.4.md +++ b/docs/release-notes/1.3.4.md @@ -1,3 +1,4 @@ +(v1.3.4)= ### 1.3.4 {small}`2018-11-24` - {func}`~scanpy.tl.leiden` wraps the recent graph clustering package by {cite:t}`Traag2019` {smaller}`K Polanski` diff --git a/docs/release-notes/1.3.5.md b/docs/release-notes/1.3.5.md index 198b5e9994..20706e9fca 100644 --- a/docs/release-notes/1.3.5.md +++ b/docs/release-notes/1.3.5.md @@ -1,3 +1,4 @@ +(v1.3.5)= ### 1.3.5 {small}`2018-12-09` - uncountable figure improvements {pr}`369` {smaller}`F Ramirez` diff --git a/docs/release-notes/1.3.6.md b/docs/release-notes/1.3.6.md index 75d5cbbbcc..a8bf3a94a1 100644 --- a/docs/release-notes/1.3.6.md +++ b/docs/release-notes/1.3.6.md @@ -1,19 +1,17 @@ +(v1.3.6)= ### 1.3.6 {small}`2018-12-11` -```{rubric} Major updates -``` +#### Major updates - a new plotting gallery for `visualizing-marker-genes` {smaller}`F Ramirez` - tutorials are integrated on ReadTheDocs, `pbmc3k` and `paga-paul15` {smaller}`A Wolf` -```{rubric} Interactive exploration of analysis results through *manifold viewers* -``` +#### Interactive exploration of analysis results through *manifold viewers* - CZI’s [cellxgene] directly reads `.h5ad` files {smaller}`the cellxgene developers` - the [UCSC Single Cell Browser] requires exporting via {func}`~scanpy.external.exporting.cellbrowser` {smaller}`M Haeussler` -```{rubric} Code design -``` +#### Code design - {func}`~scanpy.pp.highly_variable_genes` supersedes {func}`~scanpy.pp.filter_genes_dispersion`, it gives the same results but, by default, expects logarithmized data and doesn’t subset {smaller}`A Wolf` diff --git a/docs/release-notes/1.3.7.md b/docs/release-notes/1.3.7.md index e69de29bb2..19675fe0e3 100644 --- a/docs/release-notes/1.3.7.md +++ b/docs/release-notes/1.3.7.md @@ -0,0 +1,5 @@ +(v1.3.7)= +### 1.3.7 {small}`2019-01-02` + +- API changed from `import scanpy as sc` to `import scanpy.api as sc`. +- {func}`~scanpy.external.tl.phenograph` wraps the graph clustering package Phenograph {cite:p}`Levine2015` {smaller}`thanks to A Mousa` diff --git a/docs/release-notes/1.3.8.md b/docs/release-notes/1.3.8.md index e69de29bb2..f1f6e01282 100644 --- a/docs/release-notes/1.3.8.md +++ b/docs/release-notes/1.3.8.md @@ -0,0 +1,5 @@ +(v1.3.8)= +### 1.3.8 {small}`2019-02-05` + +- various documentation and dev process improvements +- Added {func}`~scanpy.pp.combat` function for batch effect correction {cite:p}`Johnson2006,Leek2012,Pedersen2012` {pr}`398` {smaller}`M Lange` diff --git a/docs/release-notes/1.4.1.md b/docs/release-notes/1.4.1.md index 18d689a190..ab503085a4 100644 --- a/docs/release-notes/1.4.1.md +++ b/docs/release-notes/1.4.1.md @@ -1,7 +1,7 @@ +(v1.4.1)= ### 1.4.1 {small}`2019-04-26` -```{rubric} New functionality -``` +#### New functionality - Scanpy has a command line interface again. Invoking it with `scanpy somecommand [args]` calls `scanpy-somecommand [args]`, except for builtin commands (currently `scanpy settings`) {pr}`604` {smaller}`P Angerer` - {func}`~scanpy.datasets.ebi_expression_atlas` allows convenient download of EBI expression atlas {smaller}`I Virshup` @@ -12,8 +12,7 @@ - {func}`~scanpy.tl.embedding_density` computes densities on embeddings {pr}`543` {smaller}`M Luecken` - {func}`~scanpy.external.tl.palantir` interfaces Palantir {cite:p}`Setty2019` {pr}`493` {smaller}`A Mousa` -```{rubric} Code design -``` +#### Code design - `.layers` support of scatter plots {smaller}`F Ramirez` - fix double-logarithmization in compute of log fold change in {func}`~scanpy.tl.rank_genes_groups` {smaller}`A Muñoz-Rojas` diff --git a/docs/release-notes/1.4.2.md b/docs/release-notes/1.4.2.md index f08e21de90..fa3ebf345c 100644 --- a/docs/release-notes/1.4.2.md +++ b/docs/release-notes/1.4.2.md @@ -1,19 +1,17 @@ +(v1.4.2)= ### 1.4.2 {small}`2019-05-06` -```{rubric} New functionality -``` +#### New functionality - {func}`~scanpy.pp.combat` supports additional covariates which may include adjustment variables or biological condition {pr}`618` {smaller}`G Eraslan` - {func}`~scanpy.pp.highly_variable_genes` has a `batch_key` option which performs HVG selection in each batch separately to avoid selecting genes that vary strongly across batches {pr}`622` {smaller}`G Eraslan` -```{rubric} Bug fixes -``` +#### Bug fixes - {func}`~scanpy.tl.rank_genes_groups` t-test implementation doesn't return NaN when variance is 0, also changed to scipy's implementation {pr}`621` {smaller}`I Virshup` - {func}`~scanpy.tl.umap` with `init_pos='paga'` detects correct `dtype` {smaller}`A Wolf` - {func}`~scanpy.tl.louvain` and {func}`~scanpy.tl.leiden` auto-generate `key_added=louvain_R` upon passing `restrict_to`, which was temporarily changed in `1.4.1` {smaller}`A Wolf` -```{rubric} Code design -``` +#### Code design - {func}`~scanpy.pp.neighbors` and {func}`~scanpy.tl.umap` got rid of UMAP legacy code and introduced UMAP as a dependency {pr}`576` {smaller}`S Rybakov` diff --git a/docs/release-notes/1.4.3.md b/docs/release-notes/1.4.3.md index d034230132..af60127ded 100644 --- a/docs/release-notes/1.4.3.md +++ b/docs/release-notes/1.4.3.md @@ -1,11 +1,10 @@ +(v1.4.3)= ### 1.4.3 {small}`2019-05-14` -```{rubric} Bug fixes -``` +#### Bug fixes - {func}`~scanpy.pp.neighbors` correctly infers `n_neighbors` again from `params`, which was temporarily broken in `v1.4.2` {smaller}`I Virshup` -```{rubric} Code design -``` +#### Code design - {func}`~scanpy.pp.calculate_qc_metrics` is single threaded by default for datasets under 300,000 cells -- allowing cached compilation {pr}`615` {smaller}`I Virshup` diff --git a/docs/release-notes/1.4.4.md b/docs/release-notes/1.4.4.md index b82bdaa362..b500c11b6d 100644 --- a/docs/release-notes/1.4.4.md +++ b/docs/release-notes/1.4.4.md @@ -1,16 +1,14 @@ +(v1.4.4)= ### 1.4.4 {small}`2019-07-20` -```{rubric} New functionality -``` +#### New functionality - {mod}`scanpy.get` adds helper functions for extracting data in convenient formats {pr}`619` {smaller}`I Virshup` -```{rubric} Bug fixes -``` +#### Bug fixes - Stopped deprecations warnings from AnnData `0.6.22` {smaller}`I Virshup` -```{rubric} Code design -``` +#### Code design - {func}`~scanpy.pp.normalize_total` gains param `exclude_highly_expressed`, and `fraction` is renamed to `max_fraction` with better docs {smaller}`A Wolf` diff --git a/docs/release-notes/1.4.5.md b/docs/release-notes/1.4.5.md index c56c1270da..44a475ad5d 100644 --- a/docs/release-notes/1.4.5.md +++ b/docs/release-notes/1.4.5.md @@ -1,16 +1,15 @@ +(v1.4.5)= ### 1.4.5 {small}`2019-12-30` Please install `scanpy==1.4.5.post3` instead of `scanpy==1.4.5`. -```{rubric} New functionality -``` +#### New functionality - {func}`~scanpy.tl.ingest` maps labels and embeddings of reference data to new data {doc}`/tutorials/basics/integrating-data-using-ingest` {pr}`651` {smaller}`S Rybakov, A Wolf` - {mod}`~scanpy.queries` recieved many updates including enrichment through [gprofiler] and more advanced biomart queries {pr}`467` {smaller}`I Virshup` - {func}`~scanpy.set_figure_params` allows setting `figsize` and accepts `facecolor='white'`, useful for working in dark mode {smaller}`A Wolf` -```{rubric} Code design -``` +#### Code design - {mod}`~scanpy.pp.downsample_counts` now always preserves the dtype of it's input, instead of converting floats to ints {pr}`865` {smaller}`I Virshup` - allow specifying a base for {func}`~scanpy.pp.log1p` {pr}`931` {smaller}`G Eraslan` diff --git a/docs/release-notes/1.4.6.md b/docs/release-notes/1.4.6.md index 51be1d4569..2ea16c184c 100644 --- a/docs/release-notes/1.4.6.md +++ b/docs/release-notes/1.4.6.md @@ -1,19 +1,17 @@ +(v1.4.6)= ### 1.4.6 {small}`2020-03-17` -~~~{rubric} Functionality in `external` -~~~ +#### Functionality in `external` - {func}`~scanpy.external.tl.sam` self-assembling manifolds {cite:p}`Tarashansky2019` {pr}`903` {smaller}`A Tarashansky` - {func}`~scanpy.external.tl.harmony_timeseries` for trajectory inference on discrete time points {pr}`994` {smaller}`A Mousa` - {func}`~scanpy.external.tl.wishbone` for trajectory inference (bifurcations) {pr}`1063` {smaller}`A Mousa` -```{rubric} Code design -``` +#### Code design - {mod}`~scanpy.pl.violin` now reads `.uns['colors_...']` {pr}`1029` {smaller}`michalk8` -```{rubric} Bug fixes -``` +#### Bug fixes - adapt {func}`~scanpy.tl.ingest` for UMAP 0.4 {pr}`1038` {pr}`1106` {smaller}`S Rybakov` - compat with matplotlib 3.1 and 3.2 {pr}`1090` {smaller}`I Virshup, P Angerer` diff --git a/docs/release-notes/1.5.0.md b/docs/release-notes/1.5.0.md index b1fff45e03..922e758723 100644 --- a/docs/release-notes/1.5.0.md +++ b/docs/release-notes/1.5.0.md @@ -1,29 +1,26 @@ +(v1.5.0)= ### 1.5.0 {small}`2020-05-15` The `1.5.0` release adds a lot of new functionality, much of which takes advantage of {mod}`anndata` updates `0.7.0 - 0.7.2`. Highlights of this release include support for spatial data, dedicated handling of graphs in AnnData, sparse PCA, an interface with scvi, and others. -```{rubric} Spatial data support -``` +#### Spatial data support - Basic analysis {doc}`/tutorials/spatial/basic-analysis` and integration with single cell data {doc}`/tutorials/spatial/integration-scanorama` {smaller}`G Palla` - {func}`~scanpy.read_visium` read 10x Visium data {pr}`1034` {smaller}`G Palla, P Angerer, I Virshup` - {func}`~scanpy.datasets.visium_sge` load Visium data directly from 10x Genomics {pr}`1013` {smaller}`M Mirkazemi, G Palla, P Angerer` - {func}`~scanpy.pl.spatial` plot spatial data {pr}`1012` {smaller}`G Palla, P Angerer` -```{rubric} New functionality -``` +#### New functionality - Many functions, like {func}`~scanpy.pp.neighbors` and {func}`~scanpy.tl.umap`, now store cell-by-cell graphs in {attr}`~anndata.AnnData.obsp` {pr}`1118` {smaller}`S Rybakov` - {func}`~scanpy.pp.scale` and {func}`~scanpy.pp.log1p` can be used on any element in {attr}`~anndata.AnnData.layers` or {attr}`~anndata.AnnData.obsm` {pr}`1173` {smaller}`I Virshup` -```{rubric} External tools -``` +#### External tools - `scanpy.external.pp.scvi` for preprocessing with scVI {pr}`1085` {smaller}`G Xing` - Guide for using `Scanpy in R` {pr}`1186` {smaller}`L Zappia` -```{rubric} Performance -``` +#### Performance - {func}`~scanpy.pp.pca` now uses efficient implicit centering for sparse matrices. This can lead to signifigantly improved performance for large datasets {pr}`1066` {smaller}`A Tarashansky` - {func}`~scanpy.tl.score_genes` now has an efficient implementation for sparse matrices with missing values {pr}`1196` {smaller}`redst4r`. @@ -32,16 +29,14 @@ The `1.5.0` release adds a lot of new functionality, much of which takes advanta The new {func}`~scanpy.pp.pca` implementation can result in slightly different results for sparse matrices. See the pr ({pr}`1066`) and documentation for more info. ``` -```{rubric} Code design -``` +#### Code design - {func}`~scanpy.pl.stacked_violin` can now be used as a subplot {pr}`1084` {smaller}`P Angerer` - {func}`~scanpy.tl.score_genes` has improved logging {pr}`1119` {smaller}`G Eraslan` - {func}`~scanpy.pp.scale` now saves mean and standard deviation in the {attr}`~anndata.AnnData.var` {pr}`1173` {smaller}`A Wolf` - {func}`~scanpy.external.tl.harmony_timeseries` {pr}`1091` {smaller}`A Mousa` -```{rubric} Bug fixes -``` +#### Bug fixes - {func}`~scanpy.pp.combat` now works when `obs_names` aren't unique. {pr}`1215` {smaller}`I Virshup` - {func}`~scanpy.pp.scale` can now be used on dense arrays without centering {pr}`1160` {smaller}`simonwm` diff --git a/docs/release-notes/1.5.1.md b/docs/release-notes/1.5.1.md index 215fe3b3cc..f7c18bb73f 100644 --- a/docs/release-notes/1.5.1.md +++ b/docs/release-notes/1.5.1.md @@ -1,7 +1,7 @@ +(v1.5.1)= ### 1.5.1 {small}`2020-05-21` -```{rubric} Bug fixes -``` +#### Bug fixes - Fixed a bug in {func}`~scanpy.pp.pca`, where `random_state` did not have an effect for sparse input {pr}`1240` {smaller}`I Virshup` - Fixed docstring in {func}`~scanpy.pp.pca` which included an unused argument {pr}`1240` {smaller}`I Virshup` diff --git a/docs/release-notes/1.6.0.md b/docs/release-notes/1.6.0.md index fe40597a81..19b227fc05 100644 --- a/docs/release-notes/1.6.0.md +++ b/docs/release-notes/1.6.0.md @@ -1,9 +1,9 @@ +(v1.6.0)= ### 1.6.0 {small}`2020-08-15` This release includes an overhaul of {func}`~scanpy.pl.dotplot`, {func}`~scanpy.pl.matrixplot`, and {func}`~scanpy.pl.stacked_violin` ({pr}`1210` {smaller}`F Ramirez`), and of the internals of {func}`~scanpy.tl.rank_genes_groups` ({pr}`1156` {smaller}`S Rybakov`). -~~~{rubric} Overhaul of {func}`~scanpy.pl.dotplot`, {func}`~scanpy.pl.matrixplot`, and {func}`~scanpy.pl.stacked_violin` {pr}`1210` {smaller}`F Ramirez` -~~~ +#### Overhaul of {func}`~scanpy.pl.dotplot`, {func}`~scanpy.pl.matrixplot`, and {func}`~scanpy.pl.stacked_violin` {pr}`1210` {smaller}`F Ramirez` - An overhauled tutorial {doc}`/tutorials/plotting/core`. @@ -38,8 +38,7 @@ This release includes an overhaul of {func}`~scanpy.pl.dotplot`, {func}`~scanpy. > - The linewidth of the violin plots is thinner. > - Removed the tics for the y-axis as they tend to overlap with each other. Using the style method they can be displayed if needed. -```{rubric} Additions -``` +#### Additions - {func}`~anndata.concat` is now exported from scanpy, see {doc}`anndata:concatenation` for more info. {pr}`1338` {smaller}`I Virshup` - Added highly variable gene selection strategy from Seurat v3 {pr}`1204` {smaller}`A Gayoso` @@ -49,8 +48,7 @@ This release includes an overhaul of {func}`~scanpy.pl.dotplot`, {func}`~scanpy. - Optional tie correction for the `'wilcoxon'` method in {func}`~scanpy.tl.rank_genes_groups` {pr}`1330` {smaller}`S Rybakov` - Use `sinfo` for {func}`~scanpy.logging.print_versions` and add {func}`~scanpy.logging.print_header` to do what it previously did. {pr}`1338` {smaller}`I Virshup` {pr}`1373` -```{rubric} Bug fixes -``` +#### Bug fixes - Avoid warning in {func}`~scanpy.tl.rank_genes_groups` if 't-test' is passed {pr}`1303` {smaller}`A Wolf` - Restrict sphinx version to \<3.1, >3.0 {pr}`1297` {smaller}`I Virshup` diff --git a/docs/release-notes/1.7.0.md b/docs/release-notes/1.7.0.md index 7ea8c8c0c5..0c3f77f4ce 100644 --- a/docs/release-notes/1.7.0.md +++ b/docs/release-notes/1.7.0.md @@ -1,7 +1,7 @@ +(v1.7.0)= ### 1.7.0 {small}`2021-02-03` -```{rubric} Features -``` +#### Features - Add new 10x Visium datasets to {func}`~scanpy.datasets.visium_sge` {pr}`1473` {smaller}`G Palla` - Enable download of source image for 10x visium datasets in {func}`~scanpy.datasets.visium_sge` {pr}`1506` {smaller}`H Spitzer` @@ -14,8 +14,7 @@ - Added `na_color` and `na_in_legend` keyword arguments to {func}`~scanpy.pl.embedding` plots. Allows specifying color for missing or filtered values in plots like {func}`~scanpy.pl.umap` or {func}`~scanpy.pl.spatial` {pr}`1356` {smaller}`I Virshup` - {func}`~scanpy.pl.embedding` plots now support passing `dict` of `{cluster_name: cluster_color, ...}` for palette argument {pr}`1392` {smaller}`I Virshup` -```{rubric} External tools (new) -``` +#### External tools (new) - Add [Scanorama](https://github.com/brianhie/scanorama) integration to scanpy external API ({func}`~scanpy.external.pp.scanorama_integrate`, {cite:t}`Hie2019`) {pr}`1332` {smaller}`B Hie` - Scrublet {cite:p}`Wolock2019` integration: {func}`~scanpy.pp.scrublet`, {func}`~scanpy.pp.scrublet_simulate_doublets`, and plotting method {func}`~scanpy.pl.scrublet_score_distribution` {pr}`1476` {smaller}`J Manning` @@ -23,8 +22,7 @@ - Added [scirpy](https://github.com/icbi-lab/scirpy) (sc-AIRR analysis) to ecosystem page {pr}`1453` {smaller}`G Sturm` - Added [scvi-tools](https://scvi-tools.org) to ecosystem page {pr}`1421` {smaller}`A Gayoso` -```{rubric} External tools (changes) -``` +#### External tools (changes) - Updates for {func}`~scanpy.external.tl.palantir` and {func}`~scanpy.external.tl.palantir_results` {pr}`1245` {smaller}`A Mousa` - Fixes to {func}`~scanpy.external.tl.harmony_timeseries` docs {pr}`1248` {smaller}`A Mousa` @@ -32,20 +30,17 @@ - Deprecate `scanpy.external.pp.scvi` {pr}`1554` {smaller}`G Xing` - Updated default params of {func}`~scanpy.external.tl.sam` to work with larger data {pr}`1540` {smaller}`A Tarashansky` -```{rubric} Documentation -``` +#### Documentation - {ref}`New contribution guide ` {pr}`1544` {smaller}`I Virshup` - `zsh` installation instructions {pr}`1444` {smaller}`P Angerer` -```{rubric} Performance -``` +#### Performance - Speed up {func}`~scanpy.read_10x_h5` {pr}`1402` {smaller}`P Weiler` - Speed ups for {func}`~scanpy.get.obs_df` {pr}`1499` {smaller}`F Ramirez` -```{rubric} Bugfixes -``` +#### Bugfixes - Consistent fold-change, fractions calculation for filter_rank_genes_groups {pr}`1391` {smaller}`S Rybakov` - Fixed bug where `score_genes` would error if one gene was passed {pr}`1398` {smaller}`I Virshup` diff --git a/docs/release-notes/1.7.1.md b/docs/release-notes/1.7.1.md index 0e536ca848..c4d28b0455 100644 --- a/docs/release-notes/1.7.1.md +++ b/docs/release-notes/1.7.1.md @@ -1,12 +1,11 @@ +(v1.7.1)= ### 1.7.1 {small}`2021-02-24` -```{rubric} Documentation -``` +#### Documentation - More twitter handles for core devs {pr}`1676` {smaller}`G Eraslan` -```{rubric} Bug fixes -``` +#### Bug fixes - {func}`~scanpy.tl.dendrogram` use `1 - correlation` as distance matrix to compute the dendrogram {pr}`1614` {smaller}`F Ramirez` - Fixed {func}`~scanpy.get.obs_df`/ {func}`~scanpy.get.var_df` erroring when `keys` not passed {pr}`1637` {smaller}`I Virshup` diff --git a/docs/release-notes/1.7.2.md b/docs/release-notes/1.7.2.md index 90e90c5cc7..816819b3d2 100644 --- a/docs/release-notes/1.7.2.md +++ b/docs/release-notes/1.7.2.md @@ -1,15 +1,14 @@ +(v1.7.2)= ### 1.7.2 {small}`2021-04-07` -```{rubric} Bug fixes -``` +#### Bug fixes - {func}`scanpy.logging.print_versions` now works when `python<3.8` {pr}`1691` {smaller}`I Virshup` - {func}`scanpy.pp.regress_out` now uses `joblib` as the parallel backend, and should stop oversubscribing threads {pr}`1694` {smaller}`I Virshup` - {func}`scanpy.pp.highly_variable_genes` with `flavor="seurat_v3"` now returns correct gene means and -variances when used with `batch_key` {pr}`1732` {smaller}`J Lause` - {func}`scanpy.pp.highly_variable_genes` now throws a warning instead of an error when non-integer values are passed for method `"seurat_v3"`. The check can be skipped by passing `check_values=False`. {pr}`1679` {smaller}`G Palla` -```{rubric} Ecosystem -``` +#### Ecosystem - Added `triku` a feature selection method to the ecosystem page {pr}`1722` {smaller}`AM Ascensión` - Added `dorothea` and `progeny` to the ecosystem page {pr}`1767` {smaller}`P Badia-i-Mompel` diff --git a/docs/release-notes/1.8.0.md b/docs/release-notes/1.8.0.md index 2ec0a03496..f2e06e8371 100644 --- a/docs/release-notes/1.8.0.md +++ b/docs/release-notes/1.8.0.md @@ -1,46 +1,42 @@ +(v1.8.0)= ### 1.8.0 {small}`2021-06-28` -```{rubric} Metrics module -``` +#### Metrics module - Added {mod}`scanpy.metrics` module! - > - Added {func}`scanpy.metrics.gearys_c` for spatial autocorrelation {pr}`915` {smaller}`I Virshup` - > - Added {func}`scanpy.metrics.morans_i` for global spatial autocorrelation {pr}`1740` {smaller}`I Virshup, G Palla` - > - Added {func}`scanpy.metrics.confusion_matrix` for comparing labellings {pr}`915` {smaller}`I Virshup` + - Added {func}`scanpy.metrics.gearys_c` for spatial autocorrelation {pr}`915` {smaller}`I Virshup` + - Added {func}`scanpy.metrics.morans_i` for global spatial autocorrelation {pr}`1740` {smaller}`I Virshup, G Palla` + - Added {func}`scanpy.metrics.confusion_matrix` for comparing labellings {pr}`915` {smaller}`I Virshup` -```{rubric} Features -``` +#### Features - Added `layer` and `copy` kwargs to {func}`~scanpy.pp.normalize_total` {pr}`1667` {smaller}`I Virshup` - Added `vcenter` and `norm` arguments to the plotting functions {pr}`1551` {smaller}`G Eraslan` - Standardized and expanded available arguments to the `sc.pl.rank_genes_groups*` family of functions. {pr}`1529` {smaller}`F Ramirez` {smaller}`I Virshup` - \- See examples sections of {func}`~scanpy.pl.rank_genes_groups_dotplot` and {func}`~scanpy.pl.rank_genes_groups_matrixplot` for demonstrations. + - See examples sections of {func}`~scanpy.pl.rank_genes_groups_dotplot` and {func}`~scanpy.pl.rank_genes_groups_matrixplot` for demonstrations. - {func}`scanpy.tl.tsne` now supports the metric argument and records the passed parameters {pr}`1854` {smaller}`I Virshup` - {func}`scanpy.pl.scrublet_score_distribution` now uses same API as other scanpy functions for saving/ showing plots {pr}`1741` {smaller}`J Manning` -```{rubric} Ecosystem -``` +#### Ecosystem - Added [Cubé](https://github.com/connerlambden/Cube) to ecosystem page {pr}`1878` {smaller}`C Lambden` - Added `triku` a feature selection method to the ecosystem page {pr}`1722` {smaller}`AM Ascensión` - Added `dorothea` and `progeny` to the ecosystem page {pr}`1767` {smaller}`P Badia-i-Mompel` -```{rubric} Documentation -``` +#### Documentation - Added {doc}`/community` page to docs {pr}`1856` {smaller}`I Virshup` - Added rendered examples to many plotting functions {issue}`1664` {smaller}`A Schaar` {smaller}`L Zappia` {smaller}`bio-la` {smaller}`L Hetzel` {smaller}`L Dony` {smaller}`M Buttner` {smaller}`K Hrovatin` {smaller}`F Ramirez` {smaller}`I Virshup` {smaller}`LouisK92` {smaller}`mayarali` - Integrated [DocSearch], a find-as-you-type documentation index search. {pr}`1754` {smaller}`P Angerer` -- - Reorganized reference docs {pr}`1753` {smaller}`I Virshup` +- Reorganized reference docs {pr}`1753` {smaller}`I Virshup` - Clarified docs issues for {func}`~scanpy.pp.neighbors`, {func}`~scanpy.tl.diffmap`, {func}`~scanpy.pp.calculate_qc_metrics` {pr}`1680` {smaller}`G Palla` - Fixed typos in grouped plot doc-strings {pr}`1877` {smaller}`C Rands` - Extended examples for differential expression plotting. {pr}`1529` {smaller}`F Ramirez` - \- See {func}`~scanpy.pl.rank_genes_groups_dotplot` or {func}`~scanpy.pl.rank_genes_groups_matrixplot` for examples. + - See {func}`~scanpy.pl.rank_genes_groups_dotplot` or {func}`~scanpy.pl.rank_genes_groups_matrixplot` for examples. -```{rubric} Bug fixes -``` +#### Bug fixes - Fix {func}`scanpy.pl.paga_path` `TypeError` with recent versions of anndata {pr}`1047` {smaller}`P Angerer` - Fix detection of whether IPython is running {pr}`1844` {smaller}`I Virshup` @@ -51,14 +47,12 @@ - {func}`scanpy.pl.rank_genes_groups_violin` now works for `raw=False` {pr}`1669` {smaller}`M van den Beek` - {func}`scanpy.pl.dotplot` now uses `smallest_dot` argument correctly {pr}`1771` {smaller}`S Flemming` -```{rubric} Development processes -``` +#### Development processes - Switched to [flit] for building and deploying the package, a simple tool with an easy to understand command line interface and metadata {pr}`1527` {smaller}`P Angerer` - Use [pre-commit](https://pre-commit.com) for style checks {pr}`1684` {pr}`1848` {smaller}`L Heumos` {smaller}`I Virshup` -```{rubric} Deprecations -``` +#### Deprecations - Dropped support for Python 3.6. [More details here](https://numpy.org/neps/nep-0029-deprecation_policy.html). {pr}`1897` {smaller}`I Virshup` - Deprecated `layers` and `layers_norm` kwargs to {func}`~scanpy.pp.normalize_total` {pr}`1667` {smaller}`I Virshup` diff --git a/docs/release-notes/1.8.1.md b/docs/release-notes/1.8.1.md index 6569748ab4..befef210e5 100644 --- a/docs/release-notes/1.8.1.md +++ b/docs/release-notes/1.8.1.md @@ -1,7 +1,7 @@ +(v1.8.1)= ### 1.8.1 {small}`2021-07-07` -```{rubric} Bug fixes -``` +#### Bug fixes - Fixed reproducibility of {func}`scanpy.tl.score_genes`. Calculation and output is now float64 type. {pr}`1890` {smaller}`I Kucinski` - Workarounds for some changes/ bugs in pandas 1.3 {pr}`1918` {smaller}`I Virshup` diff --git a/docs/release-notes/1.8.2.md b/docs/release-notes/1.8.2.md index 8cae543c03..418cae9944 100644 --- a/docs/release-notes/1.8.2.md +++ b/docs/release-notes/1.8.2.md @@ -1,12 +1,11 @@ +(v1.8.2)= ### 1.8.2 {small}`2021-11-3` -```{rubric} Docs -``` +#### Docs - Update conda installation instructions {pr}`1974` {smaller}`L Heumos` -```{rubric} Bug fixes -``` +#### Bug fixes - Fix plotting after {func}`scanpy.tl.filter_rank_genes_groups` {pr}`1942` {smaller}`S Rybakov` - Fix `use_raw=None` using {attr}`anndata.AnnData.var_names` if {attr}`anndata.AnnData.raw` @@ -14,7 +13,6 @@ - Fix compatibility with UMAP 0.5.2 {pr}`2028` {smaller}`L Mcinnes` - Fixed non-determinism in {func}`scanpy.pl.paga` node positions {pr}`1922` {smaller}`I Virshup` -```{rubric} Ecosystem -``` +#### Ecosystem - Added PASTE (a tool to align and integrate spatial transcriptomics data) to scanpy ecosystem. diff --git a/docs/release-notes/1.9.0.md b/docs/release-notes/1.9.0.md index 977489a34b..c89a1b704b 100644 --- a/docs/release-notes/1.9.0.md +++ b/docs/release-notes/1.9.0.md @@ -1,13 +1,12 @@ +(v1.9.0)= ### 1.9.0 {small}`2022-04-01` -```{rubric} Tutorials -``` +#### Tutorials - New tutorial on the usage of Pearson Residuals: {doc}`/tutorials/experimental/pearson_residuals` {smaller}`J Lause, G Palla` - [Materials](https://github.com/scverse/scanpy-tutorials/tree/master/scanpy_workshop) and [recordings](https://www.youtube.com/playlist?list=PL4rcQcNPLZxWQQH7LlRBMkAo5NWuHX1e3) for Scanpy workshops by Maren Büttner -```{rubric} Experimental module -``` +#### Experimental module - Added {mod}`scanpy.experimental` module! Currently contains functionality related to pearson residuals in {mod}`scanpy.experimental.pp` {pr}`1715` {smaller}`J Lause, G Palla, I Virshup`. This includes: @@ -16,8 +15,7 @@ - {func}`~scanpy.experimental.pp.normalize_pearson_residuals_pca` for Pearson Residuals normalization and dimensionality reduction with PCA - {func}`~scanpy.experimental.pp.recipe_pearson_residuals` for Pearson Residuals normalization, HVG selection and dimensionality reduction with PCA -```{rubric} Features -``` +#### Features - {func}`~scanpy.tl.filter_rank_genes_groups` now allows to filter with absolute values of log fold change {pr}`1649` {smaller}`S Rybakov` - `_choose_representation` now subsets the provided representation to n_pcs, regardless of the name of the provided representation (should affect mostly {func}`~scanpy.pp.neighbors`) {pr}`2179` {smaller}`I Virshup` {smaller}`PG Majev` @@ -29,8 +27,7 @@ - Embedding plots now have a `dimensions` argument, which lets users select which dimensions of their embedding to plot and uses the same broadcasting rules as other arguments {pr}`1538` {smaller}`I Virshup` - {func}`~scanpy.logging.print_versions` now uses `session_info` {pr}`2089` {smaller}`P Angerer` {smaller}`I Virshup` -```{rubric} Ecosystem -``` +#### Ecosystem Multiple packages have been added to our ecosystem page, including: @@ -38,8 +35,7 @@ Multiple packages have been added to our ecosystem page, including: - [dandelion](https://github.com/zktuong/dandelion) for B-cell receptor analysis {pr}`1953` {smaller}`Z Tuong` - [CIARA](https://github.com/ScialdoneLab/CIARA_python) a feature selection tools for identifying rare cell types {pr}`2175` {smaller}`M Stock` -```{rubric} Bug fixes -``` +#### Bug fixes - Fixed finding variables with `use_raw=True` and `basis=None` in {func}`scanpy.pl.scatter` {pr}`2027` {smaller}`E Rice` - Fixed {func}`scanpy.pp.scrublet` to address {issue}`1957` {smaller}`FlMai` and ensure raw counts are used for simulation diff --git a/docs/release-notes/1.9.1.md b/docs/release-notes/1.9.1.md index dcaa2a77cb..38bf8922cc 100644 --- a/docs/release-notes/1.9.1.md +++ b/docs/release-notes/1.9.1.md @@ -1,8 +1,7 @@ +(v1.9.1)= ### 1.9.1 {small}`2022-04-05` - -```{rubric} Bug fixes -``` +#### Bug fixes - {func}`~scanpy.pp.normalize_total` works when Dask is not installed {pr}`2209` {smaller}`R Cannoodt` - Fix embedding plots by bumping matplotlib dependency to version 3.4 {pr}`2212` {smaller}`I Virshup` diff --git a/docs/release-notes/1.9.2.md b/docs/release-notes/1.9.2.md index c2f5b647da..6b50147f43 100644 --- a/docs/release-notes/1.9.2.md +++ b/docs/release-notes/1.9.2.md @@ -1,7 +1,7 @@ +(v1.9.2)= ### 1.9.2 {small}`2023-02-16` -```{rubric} Bug fixes -``` +#### Bug fixes * {func}`~scanpy.pp.highly_variable_genes` `layer` argument now works in tandem with `batches` {pr}`2302` {smaller}`D Schaumont` * {func}`~scanpy.pp.highly_variable_genes` with `flavor='cell_ranger'` now handles the case in {issue}`2230` where the number of calculated dispersions is less than `n_top_genes` {pr}`2231` {smaller}`L Zappia` diff --git a/docs/release-notes/1.9.3.md b/docs/release-notes/1.9.3.md index 83dd8c8454..bec9964182 100644 --- a/docs/release-notes/1.9.3.md +++ b/docs/release-notes/1.9.3.md @@ -1,6 +1,6 @@ +(v1.9.3)= ### 1.9.3 {small}`2023-03-02` -```{rubric} Bug fixes -``` +#### Bug fixes * Variety of fixes against pandas 2.0.0rc0 {pr}`2434` {smaller}`I Virshup` diff --git a/docs/release-notes/1.9.4.md b/docs/release-notes/1.9.4.md index 51ca54257b..daf34fa968 100644 --- a/docs/release-notes/1.9.4.md +++ b/docs/release-notes/1.9.4.md @@ -1,7 +1,7 @@ +(v1.9.4)= ### 1.9.4 {small}`2023-08-24` -```{rubric} Bug fixes -``` +#### Bug fixes * Support scikit-learn 1.3 {pr}`2515` {smaller}`P Angerer` * Deal with `None` value vanishing from things like `.uns['log1p']` {pr}`2546` {smaller}`SP Shen` diff --git a/docs/release-notes/1.9.5.md b/docs/release-notes/1.9.5.md index c674da556d..cb96112005 100644 --- a/docs/release-notes/1.9.5.md +++ b/docs/release-notes/1.9.5.md @@ -1,6 +1,6 @@ +(v1.9.5)= ### 1.9.5 {small}`2023-09-08` -```{rubric} Bug fixes -``` +#### Bug fixes - Remove use of deprecated `dtype` argument to AnnData constructor {pr}`2658` {smaller}`Isaac Virshup` diff --git a/docs/release-notes/1.9.6.md b/docs/release-notes/1.9.6.md index ca8d43e498..4e26980a54 100644 --- a/docs/release-notes/1.9.6.md +++ b/docs/release-notes/1.9.6.md @@ -1,7 +1,7 @@ +(v1.9.6)= ### 1.9.6 {small}`2023-10-31` -```{rubric} Bug fixes -``` +#### Bug fixes - Allow {func}`scanpy.pl.scatter` to accept a {class}`str` palette name {pr}`2571` {smaller}`P Angerer` - Make {func}`scanpy.external.tl.palantir` compatible with palantir >=1.3 {pr}`2672` {smaller}`DJ Otto` diff --git a/docs/release-notes/1.9.7.md b/docs/release-notes/1.9.7.md index 927a57dcf7..0b98ac3d80 100644 --- a/docs/release-notes/1.9.7.md +++ b/docs/release-notes/1.9.7.md @@ -1,7 +1,7 @@ +(v1.9.7)= ### 1.9.7 {small}`2024-01-25` -```{rubric} Bug fixes -``` +#### Bug fixes - Fix handling of numpy array palettes (e.g. after write-read cycle) {pr}`2734` {smaller}`P Angerer` - Specify correct version of `matplotlib` dependency {pr}`2733` {smaller}`P Fisher` diff --git a/docs/release-notes/1.9.8.md b/docs/release-notes/1.9.8.md index c2289144a6..d7e65ec12a 100644 --- a/docs/release-notes/1.9.8.md +++ b/docs/release-notes/1.9.8.md @@ -1,6 +1,6 @@ +(v1.9.8)= ### 1.9.8 {small}`2024-01-26` -```{rubric} Bug fixes -``` +#### Bug fixes - Fix handling of numpy array palettes for old numpy versions {pr}`2832` {smaller}`P Angerer` From df0ac257526f47d1abc675c60e2d3e0510e54f08 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 11:45:17 +0200 Subject: [PATCH 019/118] [pre-commit.ci] pre-commit autoupdate (#3174) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 476797fd48..1c44692b47 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.5.4 + rev: v0.5.5 hooks: - id: ruff types_or: [python, pyi, jupyter] From e96cde290f8a58329f50b5bd17d4bf81d967487e Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Tue, 30 Jul 2024 14:26:42 +0200 Subject: [PATCH 020/118] Fix NaN dispersion (#3176) --- docs/release-notes/1.10.3.md | 1 + .../preprocessing/_highly_variable_genes.py | 2 +- tests/test_highly_variable_genes.py | 22 +++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/1.10.3.md b/docs/release-notes/1.10.3.md index bbb8edbc8c..6ed21a12d7 100644 --- a/docs/release-notes/1.10.3.md +++ b/docs/release-notes/1.10.3.md @@ -11,5 +11,6 @@ * Fix `subset=True` of {func}`~scanpy.pp.highly_variable_genes` when `flavor` is `seurat` or `cell_ranger`, and `batch_key!=None` {pr}`3042` {smaller}`E Roellin` * Add compatibility with {mod}`numpy` 2.0 {pr}`3065` and {pr}`3115` {smaller}`P Angerer` * Fix `legend_loc` argument in {func}`scanpy.pl.embedding` not accepting matplotlib parameters {pr}`3163` {smaller}`P Angerer` +* Fix dispersion cutoff in {func}`~scanpy.pp.highly_variable_genes` in presence of `NaN`s {pr}`3176` {smaller}`P Angerer` #### Performance diff --git a/src/scanpy/preprocessing/_highly_variable_genes.py b/src/scanpy/preprocessing/_highly_variable_genes.py index d75faa5af6..af71728d2c 100644 --- a/src/scanpy/preprocessing/_highly_variable_genes.py +++ b/src/scanpy/preprocessing/_highly_variable_genes.py @@ -402,7 +402,7 @@ def _subset_genes( f"the {n_top_genes} top genes correspond to a " f"normalized dispersion cutoff of {disp_cut_off}" ) - return np.nan_to_num(dispersion_norm) >= disp_cut_off + return np.nan_to_num(dispersion_norm, nan=-np.inf) >= disp_cut_off def _nth_highest(x: NDArray[np.float64] | DaskArray, n: int) -> float | DaskArray: diff --git a/tests/test_highly_variable_genes.py b/tests/test_highly_variable_genes.py index ab3996ff46..391a83ddf0 100644 --- a/tests/test_highly_variable_genes.py +++ b/tests/test_highly_variable_genes.py @@ -13,6 +13,7 @@ from scipy import sparse import scanpy as sc +from scanpy.preprocessing._utils import _get_mean_var from testing.scanpy._helpers import _check_check_values_warnings from testing.scanpy._helpers.data import pbmc3k, pbmc68k_reduced from testing.scanpy._pytest.marks import needs @@ -131,6 +132,27 @@ def test_keep_layer(base, flavor): assert np.allclose(X_orig.toarray(), adata.X.toarray()) +@pytest.mark.parametrize( + "flavor", + [ + "seurat", + pytest.param( + "cell_ranger", + marks=pytest.mark.xfail(reason="can’t deal with duplicate bin edges"), + ), + ], +) +def test_no_filter_genes(flavor): + """Test that even with columns containing all-zeros in the data, n_top_genes is respected.""" + adata = sc.datasets.pbmc3k() + means, _ = _get_mean_var(adata.X) + assert (means == 0).any() + sc.pp.normalize_total(adata, target_sum=10000) + sc.pp.log1p(adata) + sc.pp.highly_variable_genes(adata, flavor=flavor, n_top_genes=10000) + assert adata.var["highly_variable"].sum() == 10000 + + def _check_pearson_hvg_columns(output_df: pd.DataFrame, n_top_genes: int): assert pd.api.types.is_float_dtype(output_df["residual_variances"].dtype) From 6a421f76c2c5a1e7ad2811438f9728c3badb82b9 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Tue, 30 Jul 2024 14:41:36 +0200 Subject: [PATCH 021/118] Cache data for subsequent test runs (#3177) --- src/testing/scanpy/_pytest/__init__.py | 5 ++++- src/testing/scanpy/_pytest/fixtures/__init__.py | 3 --- tests/test_datasets.py | 9 +++++++++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/testing/scanpy/_pytest/__init__.py b/src/testing/scanpy/_pytest/__init__.py index ab5c3ab737..d989b4080c 100644 --- a/src/testing/scanpy/_pytest/__init__.py +++ b/src/testing/scanpy/_pytest/__init__.py @@ -19,6 +19,7 @@ @pytest.fixture(autouse=True) def _global_test_context( request: pytest.FixtureRequest, + cache: pytest.Cache, tmp_path_factory: pytest.TempPathFactory, ) -> Generator[None, None, None]: """Switch to agg backend, reset settings, and close all figures at teardown.""" @@ -33,7 +34,9 @@ def _global_test_context( sc.settings.logfile = sys.stderr sc.settings.verbosity = "hint" sc.settings.autoshow = True - sc.settings.datasetdir = tmp_path_factory.mktemp("scanpy_data") + # reuse data files between test runs (unless overwritten in the test) + sc.settings.datasetdir = cache.mkdir("scanpy-data") + # create new writedir for each test run sc.settings.writedir = tmp_path_factory.mktemp("scanpy_write") if isinstance(request.node, pytest.DoctestItem): diff --git a/src/testing/scanpy/_pytest/fixtures/__init__.py b/src/testing/scanpy/_pytest/fixtures/__init__.py index 16c3f8a4df..2a490ab6ab 100644 --- a/src/testing/scanpy/_pytest/fixtures/__init__.py +++ b/src/testing/scanpy/_pytest/fixtures/__init__.py @@ -39,7 +39,6 @@ def float_dtype(request): @pytest.fixture() def _doctest_env(cache: pytest.Cache, tmp_path: Path) -> Generator[None, None, None]: - from scanpy import settings from scanpy._compat import chdir showwarning_orig = warnings.showwarning @@ -61,8 +60,6 @@ def showwarning(message, category, filename, lineno, file=None, line=None): # n ] + [("ignore", None, Warning, None, 0)] warnings.showwarning = showwarning - old_dd, settings.datasetdir = settings.datasetdir, cache.mkdir("scanpy-data") with chdir(tmp_path): yield warnings.showwarning = showwarning_orig - settings.datasetdir = old_dd diff --git a/tests/test_datasets.py b/tests/test_datasets.py index 88f8fc9423..4bad3800d7 100644 --- a/tests/test_datasets.py +++ b/tests/test_datasets.py @@ -24,6 +24,15 @@ from anndata import AnnData +@pytest.fixture(autouse=True) +def _tmp_dataset_dir(tmp_path: Path) -> None: + """Make sure that datasets are downloaded during the test run. + + The default test environment stores them in a cached location. + """ + sc.settings.datasetdir = tmp_path / "scanpy_data" + + @pytest.mark.internet def test_burczynski06(): with pytest.warns(UserWarning, match=r"Variable names are not unique"): From 4861996454b4939fd1b4f6d7911a269b4f341eeb Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 1 Aug 2024 12:25:20 +0200 Subject: [PATCH 022/118] Some refactoring ahead of key_added (#3182) --- src/scanpy/_utils/__init__.py | 32 ++++++++++---- src/scanpy/neighbors/__init__.py | 19 ++++++-- src/scanpy/preprocessing/_pca.py | 74 ++++++++++++++------------------ src/scanpy/tools/_tsne.py | 28 ++++++------ src/scanpy/tools/_umap.py | 31 ++++++------- 5 files changed, 98 insertions(+), 86 deletions(-) diff --git a/src/scanpy/_utils/__init__.py b/src/scanpy/_utils/__init__.py index 9221f88ab5..95fbb5bccb 100644 --- a/src/scanpy/_utils/__init__.py +++ b/src/scanpy/_utils/__init__.py @@ -19,7 +19,7 @@ from operator import mul, truediv from textwrap import dedent from types import MethodType, ModuleType -from typing import TYPE_CHECKING, overload +from typing import TYPE_CHECKING, Union, overload from weakref import WeakSet import h5py @@ -44,14 +44,17 @@ if TYPE_CHECKING: from collections.abc import Mapping from pathlib import Path - from typing import Any, Callable, Literal, TypeVar, Union + from typing import Any, Callable, Literal, TypeVar from anndata import AnnData from numpy.typing import DTypeLike, NDArray - # e.g. https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html - # maybe in the future random.Generator - AnyRandom = Union[int, np.random.RandomState, None] + from ..neighbors import NeighborsParams, RPForestDict + + +# e.g. https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html +# maybe in the future random.Generator +AnyRandom = Union[int, np.random.RandomState, None] class Empty(Enum): @@ -1014,7 +1017,7 @@ class NeighborsView: 'params' in adata.uns[key] """ - def __init__(self, adata, key=None): + def __init__(self, adata: AnnData, key=None): self._connectivities = None self._distances = None @@ -1045,7 +1048,18 @@ def __init__(self, adata, key=None): self._dists_key, ) - def __getitem__(self, key): + @overload + def __getitem__( + self, key: Literal["distances", "connectivities"] + ) -> sparse.csr_matrix: ... + @overload + def __getitem__(self, key: Literal["params"]) -> NeighborsParams: ... + @overload + def __getitem__(self, key: Literal["rp_forest"]) -> RPForestDict: ... + @overload + def __getitem__(self, key: Literal["connectivities_key"]) -> str: ... + + def __getitem__(self, key: str): if key == "distances": if "distances" not in self: raise KeyError(f'No "{self._dists_key}" in .obsp') @@ -1054,10 +1068,12 @@ def __getitem__(self, key): if "connectivities" not in self: raise KeyError(f'No "{self._conns_key}" in .obsp') return self._connectivities + elif key == "connectivities_key": + return self._conns_key else: return self._neighbors_dict[key] - def __contains__(self, key): + def __contains__(self, key: str) -> bool: if key == "distances": return self._distances is not None elif key == "connectivities": diff --git a/src/scanpy/neighbors/__init__.py b/src/scanpy/neighbors/__init__.py index 62d8b81d86..f95e95050c 100644 --- a/src/scanpy/neighbors/__init__.py +++ b/src/scanpy/neighbors/__init__.py @@ -1,5 +1,6 @@ from __future__ import annotations +from collections.abc import Mapping from textwrap import indent from types import MappingProxyType from typing import TYPE_CHECKING, NamedTuple, TypedDict, get_args @@ -24,8 +25,8 @@ from ._types import _KnownTransformer, _Method if TYPE_CHECKING: - from collections.abc import Callable, Mapping, MutableMapping - from typing import Any, Literal + from collections.abc import Callable, MutableMapping + from typing import Any, Literal, NotRequired from anndata import AnnData from igraph import Graph @@ -34,8 +35,8 @@ from .._utils import AnyRandom from ._types import KnnTransformerLike, _Metric, _MetricFn - RPForestDict = Mapping[str, Mapping[str, np.ndarray]] +RPForestDict = Mapping[str, Mapping[str, np.ndarray]] N_DCS = 15 # default number of diffusion components # Backwards compat, constants should be defined in only one place. @@ -55,6 +56,16 @@ class KwdsForTransformer(TypedDict): random_state: AnyRandom +class NeighborsParams(TypedDict): + n_neighbors: int + method: _Method + random_state: AnyRandom + metric: _Metric | _MetricFn + metric_kwds: NotRequired[Mapping[str, Any]] + use_rep: NotRequired[str] + n_pcs: NotRequired[int] + + @_doc_params(n_pcs=doc_n_pcs, use_rep=doc_use_rep) def neighbors( adata: AnnData, @@ -203,7 +214,7 @@ def neighbors( neighbors_dict["connectivities_key"] = conns_key neighbors_dict["distances_key"] = dists_key - neighbors_dict["params"] = dict( + neighbors_dict["params"] = NeighborsParams( n_neighbors=neighbors.n_neighbors, method=method, random_state=random_state, diff --git a/src/scanpy/preprocessing/_pca.py b/src/scanpy/preprocessing/_pca.py index 6060bee6f6..28e1c6a01c 100644 --- a/src/scanpy/preprocessing/_pca.py +++ b/src/scanpy/preprocessing/_pca.py @@ -24,6 +24,7 @@ if TYPE_CHECKING: from numpy.typing import DTypeLike, NDArray from scipy.sparse import spmatrix + from sklearn.decomposition import PCA from .._utils import AnyRandom, Empty @@ -43,9 +44,9 @@ def pca( mask_var: NDArray[np.bool_] | str | None | Empty = _empty, use_highly_variable: bool | None = None, dtype: DTypeLike = "float32", - copy: bool = False, chunked: bool = False, chunk_size: int | None = None, + copy: bool = False, ) -> AnnData | np.ndarray | spmatrix | None: """\ Principal component analysis :cite:p:`Pedregosa2011`. @@ -126,9 +127,6 @@ def pca( Layer of `adata` to use as expression values. dtype Numpy data type string to which to convert the result. - copy - If an :class:`~anndata.AnnData` is passed, determines whether a copy - is returned. Is ignored otherwise. chunked If `True`, perform an incremental PCA on segments of `chunk_size`. The incremental PCA automatically zero centers and ignores settings of @@ -139,6 +137,9 @@ def pca( chunk_size Number of observations to include in each chunk. Required if `chunked=True` was passed. + copy + If an :class:`~anndata.AnnData` is passed, determines whether a copy + is returned. Is ignored otherwise. Returns ------- @@ -279,21 +280,11 @@ def pca( ) X_pca = pca_.fit_transform(X) elif issparse(X) and zero_center: - from sklearn.decomposition import PCA - svd_solver = _handle_sklearn_args(svd_solver, "PCA (with sparse input)") - output = _pca_with_sparse( + X_pca, pca_ = _pca_with_sparse( X, n_comps, solver=svd_solver, random_state=random_state ) - # this is just a wrapper for the results - X_pca = output["X_pca"] - pca_ = PCA( - n_components=n_comps, svd_solver=svd_solver, random_state=random_state - ) - pca_.components_ = output["components"] - pca_.explained_variance_ = output["variance"] - pca_.explained_variance_ratio_ = output["variance_ratio"] elif not zero_center: if is_dask: from dask_ml.decomposition import TruncatedSVD @@ -322,26 +313,27 @@ def pca( X_pca = X_pca.astype(dtype) if data_is_AnnData: - adata.obsm["X_pca"] = X_pca + key_obsm, key_varm, key_uns = ("X_pca", "PCs", "pca") + adata.obsm[key_obsm] = X_pca if mask_var is not None: - adata.varm["PCs"] = np.zeros(shape=(adata.n_vars, n_comps)) - adata.varm["PCs"][mask_var] = pca_.components_.T + adata.varm[key_varm] = np.zeros(shape=(adata.n_vars, n_comps)) + adata.varm[key_varm][mask_var] = pca_.components_.T else: - adata.varm["PCs"] = pca_.components_.T - - uns_entry = { - "params": { - "zero_center": zero_center, - "use_highly_variable": mask_var_param == "highly_variable", - "mask_var": mask_var_param, - }, - "variance": pca_.explained_variance_, - "variance_ratio": pca_.explained_variance_ratio_, - } + adata.varm[key_varm] = pca_.components_.T + + params = dict( + zero_center=zero_center, + use_highly_variable=mask_var_param == "highly_variable", + mask_var=mask_var_param, + ) if layer is not None: - uns_entry["params"]["layer"] = layer - adata.uns["pca"] = uns_entry + params["layer"] = layer + adata.uns[key_uns] = dict( + params=params, + variance=pca_.explained_variance_, + variance_ratio=pca_.explained_variance_ratio_, + ) logg.info(" finished", time=logg_start) logg.debug( @@ -408,7 +400,7 @@ def _pca_with_sparse( solver: str = "arpack", mu: NDArray[np.floating] | None = None, random_state: AnyRandom = None, -): +) -> tuple[NDArray[np.floating], PCA]: random_state = check_random_state(random_state) np.random.set_state(random_state.get_state()) random_init = np.random.rand(np.min(X.shape)) @@ -461,13 +453,13 @@ def rmatmat(x): total_var = _get_mean_var(X)[1].sum() ev_ratio = ev / total_var - output = { - "X_pca": X_pca, - "variance": ev, - "variance_ratio": ev_ratio, - "components": v, - } - return output + from sklearn.decomposition import PCA + + pca = PCA(n_components=n_pcs, svd_solver=solver, random_state=random_state) + pca.explained_variance_ = ev + pca.explained_variance_ratio_ = ev_ratio + pca.components_ = v + return X_pca, pca def _handle_dask_ml_args(svd_solver: str, method: str) -> str: @@ -485,7 +477,7 @@ def _handle_dask_ml_args(svd_solver: str, method: str) -> str: return _handle_x_args("dask_ml", svd_solver, method, method2args, method2default) -def _handle_sklearn_args(svd_solver: str, method: str) -> str: +def _handle_sklearn_args(svd_solver: str | None, method: str) -> str: method2args = { "PCA": {"auto", "full", "arpack", "randomized"}, "TruncatedSVD": {"arpack", "randomized"}, @@ -500,7 +492,7 @@ def _handle_sklearn_args(svd_solver: str, method: str) -> str: return _handle_x_args("sklearn", svd_solver, method, method2args, method2default) -def _handle_x_args(lib, svd_solver, method, method2args, method2default): +def _handle_x_args(lib, svd_solver: str | None, method, method2args, method2default): if svd_solver not in method2args[method]: if svd_solver is not None: warnings.warn( diff --git a/src/scanpy/tools/_tsne.py b/src/scanpy/tools/_tsne.py index 1e3ade92e6..cf4251adf1 100644 --- a/src/scanpy/tools/_tsne.py +++ b/src/scanpy/tools/_tsne.py @@ -35,13 +35,13 @@ def tsne( *, use_rep: str | None = None, perplexity: float | int = 30, + metric: str = "euclidean", early_exaggeration: float | int = 12, learning_rate: float | int = 1000, random_state: AnyRandom = 0, use_fast_tsne: bool = False, n_jobs: int | None = None, copy: bool = False, - metric: str = "euclidean", ) -> AnnData | None: """\ t-SNE :cite:p:`vanDerMaaten2008,Amir2013,Pedregosa2011`. @@ -165,21 +165,17 @@ def tsne( X_tsne = tsne.fit_transform(X) # update AnnData instance - adata.obsm["X_tsne"] = X_tsne # annotate samples with tSNE coordinates - adata.uns["tsne"] = { - "params": { - k: v - for k, v in { - "perplexity": perplexity, - "early_exaggeration": early_exaggeration, - "learning_rate": learning_rate, - "n_jobs": n_jobs, - "metric": metric, - "use_rep": use_rep, - }.items() - if v is not None - } - } + params = dict( + perplexity=perplexity, + early_exaggeration=early_exaggeration, + learning_rate=learning_rate, + n_jobs=n_jobs, + metric=metric, + use_rep=use_rep, + ) + key_uns, key_obsm = ("tsne", "X_tsne") + adata.obsm[key_obsm] = X_tsne # annotate samples with tSNE coordinates + adata.uns[key_uns] = dict(params={k: v for k, v in params.items() if v is not None}) logg.info( " finished", diff --git a/src/scanpy/tools/_umap.py b/src/scanpy/tools/_umap.py index 8f8c555ee5..ee69105d94 100644 --- a/src/scanpy/tools/_umap.py +++ b/src/scanpy/tools/_umap.py @@ -52,9 +52,9 @@ def umap( random_state: AnyRandom = 0, a: float | None = None, b: float | None = None, - copy: bool = False, method: Literal["umap", "rapids"] = "umap", - neighbors_key: str | None = None, + neighbors_key: str = "neighbors", + copy: bool = False, ) -> AnnData | None: """\ Embed the neighborhood graph using UMAP :cite:p:`McInnes2018`. @@ -122,8 +122,6 @@ def umap( More specific parameters controlling the embedding. If `None` these values are set automatically as determined by `min_dist` and `spread`. - copy - Return a copy instead of writing to adata. method Chosen implementation. @@ -135,11 +133,11 @@ def umap( .. deprecated:: 1.10.0 Use :func:`rapids_singlecell.tl.umap` instead. neighbors_key - If not specified, umap looks .uns['neighbors'] for neighbors settings - and .obsp['connectivities'] for connectivities - (default storage places for pp.neighbors). - If specified, umap looks .uns[neighbors_key] for neighbors settings and - .obsp[.uns[neighbors_key]['connectivities_key']] for connectivities. + Umap looks in + :attr:`~anndata.AnnData.uns`\\ ``[neighbors_key]`` for neighbors settings and + :attr:`~anndata.AnnData.obsp`\\ ``[.uns[neighbors_key]['connectivities_key']]`` for connectivities. + copy + Return a copy instead of writing to adata. Returns ------- @@ -153,13 +151,15 @@ def umap( """ adata = adata.copy() if copy else adata - if neighbors_key is None: - neighbors_key = "neighbors" + key_obsm, key_uns = ("X_umap", "umap") + if neighbors_key is None: # backwards compat + neighbors_key = "neighbors" if neighbors_key not in adata.uns: raise ValueError( f"Did not find .uns[{neighbors_key!r}]. Run `sc.pp.neighbors` first." ) + start = logg.info("computing UMAP") neighbors = NeighborsView(adata, neighbors_key) @@ -178,10 +178,7 @@ def umap( if a is None or b is None: a, b = find_ab_params(spread, min_dist) - else: - a = a - b = b - adata.uns["umap"] = {"params": {"a": a, "b": b}} + adata.uns[key_uns] = dict(params=dict(a=a, b=b)) if isinstance(init_pos, str) and init_pos in adata.obsm.keys(): init_coords = adata.obsm[init_pos] elif isinstance(init_pos, str) and init_pos == "paga": @@ -194,7 +191,7 @@ def umap( init_coords = check_array(init_coords, dtype=np.float32, accept_sparse=False) if random_state != 0: - adata.uns["umap"]["params"]["random_state"] = random_state + adata.uns[key_uns]["params"]["random_state"] = random_state random_state = check_random_state(random_state) neigh_params = neighbors["params"] @@ -262,7 +259,7 @@ def umap( random_state=random_state, ) X_umap = umap.fit_transform(X_contiguous) - adata.obsm["X_umap"] = X_umap # annotate samples with UMAP coordinates + adata.obsm[key_obsm] = X_umap # annotate samples with UMAP coordinates logg.info( " finished", time=start, From 352061e396e17f7248b75bd62360e27808726cb4 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 1 Aug 2024 13:31:49 +0200 Subject: [PATCH 023/118] Auto-metric and fix logs (#3186) --- src/scanpy/preprocessing/_pca.py | 8 ++++---- src/scanpy/tools/_tsne.py | 6 +++++- src/scanpy/tools/_umap.py | 6 +++++- tests/test_aggregated.py | 20 ++++++++++++++------ 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/scanpy/preprocessing/_pca.py b/src/scanpy/preprocessing/_pca.py index 28e1c6a01c..0e7d28a0ef 100644 --- a/src/scanpy/preprocessing/_pca.py +++ b/src/scanpy/preprocessing/_pca.py @@ -338,10 +338,10 @@ def pca( logg.info(" finished", time=logg_start) logg.debug( "and added\n" - " 'X_pca', the PCA coordinates (adata.obs)\n" - " 'PC1', 'PC2', ..., the loadings (adata.var)\n" - " 'pca_variance', the variance / eigenvalues (adata.uns)\n" - " 'pca_variance_ratio', the variance ratio (adata.uns)" + f" {key_obsm!r}, the PCA coordinates (adata.obs)\n" + f" {key_varm!r}, the loadings (adata.varm)\n" + f" 'pca_variance', the variance / eigenvalues (adata.uns[{key_uns!r}])\n" + f" 'pca_variance_ratio', the variance ratio (adata.uns[{key_uns!r}])" ) return adata if copy else None else: diff --git a/src/scanpy/tools/_tsne.py b/src/scanpy/tools/_tsne.py index cf4251adf1..e1b5fe7e7c 100644 --- a/src/scanpy/tools/_tsne.py +++ b/src/scanpy/tools/_tsne.py @@ -180,7 +180,11 @@ def tsne( logg.info( " finished", time=start, - deep="added\n 'X_tsne', tSNE coordinates (adata.obsm)", + deep=( + f"added\n" + f" {key_obsm!r}, tSNE coordinates (adata.obsm)\n" + f" {key_uns!r}, tSNE parameters (adata.uns)" + ), ) return adata if copy else None diff --git a/src/scanpy/tools/_umap.py b/src/scanpy/tools/_umap.py index ee69105d94..061315ca65 100644 --- a/src/scanpy/tools/_umap.py +++ b/src/scanpy/tools/_umap.py @@ -263,6 +263,10 @@ def umap( logg.info( " finished", time=start, - deep=("added\n" " 'X_umap', UMAP coordinates (adata.obsm)"), + deep=( + "added\n" + f" {key_obsm!r}, UMAP coordinates (adata.obsm)\n" + f" {key_uns!r}, UMAP parameters (adata.uns)" + ), ) return adata if copy else None diff --git a/tests/test_aggregated.py b/tests/test_aggregated.py index 0cc064e74e..ce680b8df5 100644 --- a/tests/test_aggregated.py +++ b/tests/test_aggregated.py @@ -1,5 +1,7 @@ from __future__ import annotations +from typing import get_args + import anndata as ad import numpy as np import pandas as pd @@ -9,11 +11,17 @@ import scanpy as sc from scanpy._utils import _resolve_axis +from scanpy.get._aggregated import AggType from testing.scanpy._helpers import assert_equal from testing.scanpy._helpers.data import pbmc3k_processed from testing.scanpy._pytest.params import ARRAY_TYPES_MEM +@pytest.fixture(params=get_args(AggType)) +def metric(request: pytest.FixtureRequest) -> AggType: + return request.param + + @pytest.fixture def df_base(): ax_base = ["A", "B"] @@ -88,7 +96,6 @@ def test_mask(axis): @pytest.mark.parametrize("array_type", ARRAY_TYPES_MEM) -@pytest.mark.parametrize("metric", ["sum", "mean", "var", "count_nonzero"]) def test_aggregate_vs_pandas(metric, array_type): adata = pbmc3k_processed().raw.to_adata() adata = adata[ @@ -135,7 +142,6 @@ def test_aggregate_vs_pandas(metric, array_type): @pytest.mark.parametrize("array_type", ARRAY_TYPES_MEM) -@pytest.mark.parametrize("metric", ["sum", "mean", "var", "count_nonzero"]) def test_aggregate_axis(array_type, metric): adata = pbmc3k_processed().raw.to_adata() adata = adata[ @@ -222,7 +228,8 @@ def test_aggregate_axis_specification(axis_name): { "a": ["a", "a", "b", "b"], "b": ["c", "d", "d", "d"], - } + }, + index=["a_c", "a_d", "b_d1", "b_d2"], ), ["a", "b"], ["count_nonzero"], # , "sum", "mean"], @@ -253,7 +260,8 @@ def test_aggregate_axis_specification(axis_name): { "a": ["a", "a", "b", "b"], "b": ["c", "d", "d", "d"], - } + }, + index=["a_c", "a_d", "b_d1", "b_d2"], ), ["a", "b"], ["sum", "mean", "count_nonzero"], @@ -284,7 +292,8 @@ def test_aggregate_axis_specification(axis_name): { "a": ["a", "a", "b", "b"], "b": ["c", "d", "d", "d"], - } + }, + index=["a_c", "a_d", "b_d1", "b_d2"], ), ["a", "b"], ["mean"], @@ -381,7 +390,6 @@ def test_combine_categories(label_cols, cols, expected): @pytest.mark.parametrize("array_type", ARRAY_TYPES_MEM) -@pytest.mark.parametrize("metric", ["sum", "mean", "var", "count_nonzero"]) def test_aggregate_arraytype(array_type, metric): adata = pbmc3k_processed().raw.to_adata() adata = adata[ From f4a8dc0b5b5adb0084b67fb095f35a18cbf83964 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 1 Aug 2024 17:12:56 +0200 Subject: [PATCH 024/118] Add Ruff FBT (#3189) --- docs/conf.py | 2 +- pyproject.toml | 1 + src/scanpy/_utils/__init__.py | 7 ++++--- src/scanpy/experimental/pp/_normalization.py | 2 +- src/scanpy/external/exporting.py | 4 ++-- src/scanpy/get/get.py | 1 + src/scanpy/neighbors/__init__.py | 4 +++- src/scanpy/neighbors/_types.py | 2 +- src/scanpy/plotting/_anndata.py | 14 +++++++------- src/scanpy/plotting/_baseplot_class.py | 16 +++++++++++----- src/scanpy/plotting/_dotplot.py | 6 +++--- src/scanpy/plotting/_matrixplot.py | 4 ++-- src/scanpy/plotting/_preprocessing.py | 3 +++ src/scanpy/plotting/_stacked_violin.py | 14 ++++++-------- src/scanpy/plotting/_tools/paga.py | 6 +++--- src/scanpy/plotting/_tools/scatterplots.py | 1 + src/scanpy/plotting/_utils.py | 2 +- .../preprocessing/_deprecated/__init__.py | 3 +++ .../_deprecated/highly_variable_genes.py | 16 +++++++++++++++- src/scanpy/preprocessing/_normalization.py | 2 +- src/scanpy/preprocessing/_qc.py | 8 ++++---- src/scanpy/preprocessing/_scale.py | 6 ++++-- src/scanpy/preprocessing/_scrublet/core.py | 5 +++-- src/scanpy/preprocessing/_simple.py | 18 ++++++++++++++++-- src/scanpy/readwrite.py | 8 +++++--- src/scanpy/tools/_ingest.py | 4 +++- src/scanpy/tools/_rank_genes_groups.py | 4 ++-- tests/test_neighbors_common.py | 1 + tests/test_normalization.py | 2 +- tests/test_rank_genes_groups.py | 2 +- tests/test_score_genes.py | 2 +- 31 files changed, 111 insertions(+), 59 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 83e568ce5a..2980ac58b2 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -172,7 +172,7 @@ def setup(app: Sphinx): "enable_inline_math": False, "enable_eval_rst": True, }, - True, + True, # noqa: FBT003 ) diff --git a/pyproject.toml b/pyproject.toml index 888a613ab7..ecde4651f4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -232,6 +232,7 @@ select = [ "ICN", # Follow import conventions "PTH", # Pathlib instead of os.path "PLR0917", # Ban APIs with too many positional parameters + "FBT", # No positional boolean parameters ] ignore = [ # line too long -> we accept long comment lines; black gets rid of long code lines diff --git a/src/scanpy/_utils/__init__.py b/src/scanpy/_utils/__init__.py index 95fbb5bccb..46d62bcde6 100644 --- a/src/scanpy/_utils/__init__.py +++ b/src/scanpy/_utils/__init__.py @@ -398,7 +398,7 @@ def get_associated_colors_of_groups(reference_colors, asso_matrix): ] -def identify_groups(ref_labels, pred_labels, return_overlaps=False): +def identify_groups(ref_labels, pred_labels, *, return_overlaps: bool = False): """Which predicted label explains which reference label? A predicted label explains the reference label which maximizes the minimum @@ -497,7 +497,8 @@ def get_random_state(seed: AnyRandom) -> np.random.RandomState: def update_params( old_params: Mapping[str, Any], new_params: Mapping[str, Any], - check=False, + *, + check: bool = False, ) -> dict[str, Any]: """\ Update old_params with new_params. @@ -653,7 +654,7 @@ def new_data_op(x): def make_axis_chunks( - X: DaskArray, axis: Literal[0, 1], pad=True + X: DaskArray, axis: Literal[0, 1] ) -> tuple[tuple[int], tuple[int]]: if axis == 0: return (X.chunks[axis], (1,)) diff --git a/src/scanpy/experimental/pp/_normalization.py b/src/scanpy/experimental/pp/_normalization.py index 7041caeb87..bc4dedbaf9 100644 --- a/src/scanpy/experimental/pp/_normalization.py +++ b/src/scanpy/experimental/pp/_normalization.py @@ -35,7 +35,7 @@ from ..._utils import Empty -def _pearson_residuals(X, theta, clip, check_values, copy: bool = False): +def _pearson_residuals(X, theta, clip, check_values, *, copy: bool = False): X = X.copy() if copy else X # check theta diff --git a/src/scanpy/external/exporting.py b/src/scanpy/external/exporting.py index 8655a7ce9d..c1d7fa93b4 100644 --- a/src/scanpy/external/exporting.py +++ b/src/scanpy/external/exporting.py @@ -316,8 +316,8 @@ def write_hdf5_cells(E, filename): hf.close() -def write_sparse_npz(E, filename, compressed=False): - '''SPRING standard: filename = main_spring_dir + "/counts_norm.npz"''' +def write_sparse_npz(E, filename, *, compressed: bool = False): + """SPRING standard: filename = f"{main_spring_dir}/counts_norm.npz".""" E = E.tocsc() scipy.sparse.save_npz(filename, E, compressed=compressed) diff --git a/src/scanpy/get/get.py b/src/scanpy/get/get.py index 936e5c3946..4d073baeb2 100644 --- a/src/scanpy/get/get.py +++ b/src/scanpy/get/get.py @@ -195,6 +195,7 @@ def _get_array_values( X, dim_names: pd.Index, keys: list[str], + *, axis: Literal[0, 1], backed: bool, ): diff --git a/src/scanpy/neighbors/__init__.py b/src/scanpy/neighbors/__init__.py index f95e95050c..0666a8b3ed 100644 --- a/src/scanpy/neighbors/__init__.py +++ b/src/scanpy/neighbors/__init__.py @@ -8,6 +8,7 @@ import numpy as np import scipy +from legacy_api_wrap import legacy_api from scipy.sparse import issparse from sklearn.utils import check_random_state @@ -713,7 +714,8 @@ def _handle_transformer( # else `transformer` is probably an instance return conn_method, transformer, shortcut - def compute_transitions(self, density_normalize: bool = True): + @legacy_api("density_normalize") + def compute_transitions(self, *, density_normalize: bool = True): """\ Compute transition matrix. diff --git a/src/scanpy/neighbors/_types.py b/src/scanpy/neighbors/_types.py index 473d7378fb..35e4c154cb 100644 --- a/src/scanpy/neighbors/_types.py +++ b/src/scanpy/neighbors/_types.py @@ -55,5 +55,5 @@ def transform(self, X) -> spmatrix: ... def fit_transform(self, X, y: None = None) -> spmatrix: ... # from BaseEstimator - def get_params(self, deep: bool = True) -> dict[str, Any]: ... + def get_params(self, *, deep: bool = True) -> dict[str, Any]: ... def set_params(self, **params: Any) -> Self: ... diff --git a/src/scanpy/plotting/_anndata.py b/src/scanpy/plotting/_anndata.py index 2ef36c88e3..b164f30c7c 100755 --- a/src/scanpy/plotting/_anndata.py +++ b/src/scanpy/plotting/_anndata.py @@ -395,7 +395,7 @@ def add_centroid(centroids, name, Y, mask): for ikey, palette in zip(categoricals, palettes): key = keys[ikey] _utils.add_colors_for_categorical_sample_annotation( - adata, key, palette, force_update_colors=not palette_was_none + adata, key, palette=palette, force_update_colors=not palette_was_none ) # actually plot the groups mask_remaining = np.ones(Y.shape[0], dtype=bool) @@ -1272,7 +1272,7 @@ def heatmap( heatmap_ax.set_xlim(-0.5, obs_tidy.shape[1] - 0.5) heatmap_ax.tick_params(axis="y", left=False, labelleft=False) heatmap_ax.set_ylabel("") - heatmap_ax.grid(False) + heatmap_ax.grid(visible=False) if show_gene_labels: heatmap_ax.tick_params(axis="x", labelsize="small") @@ -1376,7 +1376,7 @@ def heatmap( heatmap_ax.set_ylim(obs_tidy.shape[1] - 0.5, -0.5) heatmap_ax.tick_params(axis="x", bottom=False, labelbottom=False) heatmap_ax.set_xlabel("") - heatmap_ax.grid(False) + heatmap_ax.grid(visible=False) if show_gene_labels: heatmap_ax.tick_params(axis="y", labelsize="small", length=1) heatmap_ax.set_yticks(np.arange(len(var_names))) @@ -1653,7 +1653,7 @@ def tracksplot( ax.spines["left"].set_visible(False) ax.spines["top"].set_visible(False) ax.spines["bottom"].set_visible(False) - ax.grid(False) + ax.grid(visible=False) ymin, ymax = ax.get_ylim() ymax = int(ymax) ax.set_yticks([ymax]) @@ -2223,7 +2223,7 @@ def _plot_gene_groups_brackets( patch = patches.PathPatch(path, facecolor="none", lw=1.5) gene_groups_ax.add_patch(patch) - gene_groups_ax.grid(False) + gene_groups_ax.grid(visible=False) gene_groups_ax.axis("off") # remove y ticks gene_groups_ax.tick_params(axis="y", left=False, labelleft=False) @@ -2492,7 +2492,7 @@ def translate_pos(pos_list, new_ticks, old_ticks): labelbottom=False, labeltop=False, labelleft=False, labelright=False ) - dendro_ax.grid(False) + dendro_ax.grid(visible=False) dendro_ax.spines["right"].set_visible(False) dendro_ax.spines["top"].set_visible(False) @@ -2549,7 +2549,7 @@ def _plot_categories_as_colorblocks( value_sum += value label2code[label] = code - groupby_ax.grid(False) + groupby_ax.grid(visible=False) if orientation == "left": groupby_ax.imshow( diff --git a/src/scanpy/plotting/_baseplot_class.py b/src/scanpy/plotting/_baseplot_class.py index 45a95681cc..b3b6803c8c 100644 --- a/src/scanpy/plotting/_baseplot_class.py +++ b/src/scanpy/plotting/_baseplot_class.py @@ -7,6 +7,7 @@ from warnings import warn import numpy as np +from legacy_api_wrap import legacy_api from matplotlib import gridspec from matplotlib import pyplot as plt @@ -204,7 +205,8 @@ def __init__( self.ax_dict = None self.ax = ax - def swap_axes(self, swap_axes: bool | None = True) -> Self: + @legacy_api("swap_axes") + def swap_axes(self, *, swap_axes: bool | None = True) -> Self: """ Plots a transposed image. @@ -231,8 +233,10 @@ def swap_axes(self, swap_axes: bool | None = True) -> Self: self.are_axes_swapped = swap_axes return self + @legacy_api("show", "dendrogram_key", "size") def add_dendrogram( self, + *, show: bool | None = True, dendrogram_key: str | None = None, size: float | None = 0.8, @@ -316,8 +320,10 @@ def add_dendrogram( } return self + @legacy_api("show", "sort", "size", "color") def add_totals( self, + *, show: bool | None = True, sort: Literal["ascending", "descending"] | None = None, size: float | None = 0.8, @@ -545,7 +551,7 @@ def _plot_totals( ) total_barplot_ax.set_xlim(0, max_x * 1.4) - total_barplot_ax.grid(False) + total_barplot_ax.grid(visible=False) total_barplot_ax.axis("off") def _plot_colorbar(self, color_legend_ax: Axes, normalize) -> None: @@ -597,7 +603,7 @@ def _plot_legend(self, legend_ax, return_ax_dict, normalize): self._plot_colorbar(color_legend_ax, normalize) return_ax_dict["color_legend_ax"] = color_legend_ax - def _mainplot(self, ax): + def _mainplot(self, ax: Axes): y_labels = self.categories x_labels = self.var_names @@ -622,7 +628,7 @@ def _mainplot(self, ax): ax.set_xticklabels(x_labels, rotation=90, ha="center", minor=False) ax.tick_params(axis="both", labelsize="small") - ax.grid(False) + ax.grid(visible=False) # to be consistent with the heatmap plot, is better to # invert the order of the y-axis, such that the first group is on @@ -1075,7 +1081,7 @@ def _plot_var_groups_brackets( patch = patches.PathPatch(path, facecolor="none", lw=1.5) gene_groups_ax.add_patch(patch) - gene_groups_ax.grid(False) + gene_groups_ax.grid(visible=False) gene_groups_ax.axis("off") # remove y ticks gene_groups_ax.tick_params(axis="y", left=False, labelleft=False) diff --git a/src/scanpy/plotting/_dotplot.py b/src/scanpy/plotting/_dotplot.py index 4b6d29f0f5..2048cd0e8e 100644 --- a/src/scanpy/plotting/_dotplot.py +++ b/src/scanpy/plotting/_dotplot.py @@ -530,7 +530,7 @@ def _plot_size_legend(self, size_legend_ax: Axes): size_legend_ax.spines["top"].set_visible(False) size_legend_ax.spines["left"].set_visible(False) size_legend_ax.spines["bottom"].set_visible(False) - size_legend_ax.grid(False) + size_legend_ax.grid(visible=False) ymax = size_legend_ax.get_ylim()[1] size_legend_ax.set_ylim(-1.05 - self.largest_dot * 0.003, 4) @@ -823,7 +823,7 @@ def _dotplot( minor=False, ) dot_ax.tick_params(axis="both", labelsize="small") - dot_ax.grid(False) + dot_ax.grid(visible=False) dot_ax.set_ylabel(y_label) # to be consistent with the heatmap plot, is better to @@ -844,7 +844,7 @@ def _dotplot( dot_ax.set_xlim(-x_padding, dot_color.shape[1] + x_padding) if grid: - dot_ax.grid(True, color="gray", linewidth=0.1) + dot_ax.grid(visible=True, color="gray", linewidth=0.1) dot_ax.set_axisbelow(True) return normalize, dot_min, dot_max diff --git a/src/scanpy/plotting/_matrixplot.py b/src/scanpy/plotting/_matrixplot.py index 011955eb2b..f5fc18a72f 100644 --- a/src/scanpy/plotting/_matrixplot.py +++ b/src/scanpy/plotting/_matrixplot.py @@ -253,7 +253,7 @@ def style( return self - def _mainplot(self, ax): + def _mainplot(self, ax: Axes): # work on a copy of the dataframes. This is to avoid changes # on the original data frames after repetitive calls to the # MatrixPlot object, for example once with swap_axes and other without @@ -301,7 +301,7 @@ def _mainplot(self, ax): ax.set_xticklabels(x_labels, rotation=90, ha="center", minor=False) ax.tick_params(axis="both", labelsize="small") - ax.grid(False) + ax.grid(visible=False) # to be consistent with the heatmap plot, is better to # invert the order of the y-axis, such that the first group is on diff --git a/src/scanpy/plotting/_preprocessing.py b/src/scanpy/plotting/_preprocessing.py index 9dce5dca3f..f2fd1c6d66 100644 --- a/src/scanpy/plotting/_preprocessing.py +++ b/src/scanpy/plotting/_preprocessing.py @@ -3,6 +3,7 @@ import numpy as np import pandas as pd from anndata import AnnData +from legacy_api_wrap import legacy_api from matplotlib import pyplot as plt from matplotlib import rcParams @@ -103,8 +104,10 @@ def highly_variable_genes( # backwards compat +@legacy_api("log", "show", "save") def filter_genes_dispersion( result: np.recarray, + *, log: bool = False, show: bool | None = None, save: bool | str | None = None, diff --git a/src/scanpy/plotting/_stacked_violin.py b/src/scanpy/plotting/_stacked_violin.py index 8745452554..b78184004f 100644 --- a/src/scanpy/plotting/_stacked_violin.py +++ b/src/scanpy/plotting/_stacked_violin.py @@ -23,13 +23,11 @@ ) if TYPE_CHECKING: - from collections.abc import ( - Mapping, # Special - Sequence, # ABCs - ) + from collections.abc import Mapping, Sequence from typing import Literal, Self from anndata import AnnData + from matplotlib.axes import Axes from matplotlib.colors import Normalize from ._baseplot_class import _VarNames @@ -375,7 +373,7 @@ def style( return self - def _mainplot(self, ax): + def _mainplot(self, ax: Axes): # to make the stacked violin plots, the # `ax` is subdivided horizontally and in each horizontal sub ax # a seaborn violin plot is added. @@ -442,7 +440,7 @@ def _mainplot(self, ax): if max([len(x) for x in labels]) > 2: ax.tick_params(axis="x", labelrotation=90) ax.tick_params(axis="both", labelsize="small") - ax.grid(False) + ax.grid(visible=False) return normalize @@ -561,7 +559,7 @@ def _make_rows_of_violinplots( self._setup_violin_axes_ticks(row_ax, num_cols) - def _setup_violin_axes_ticks(self, row_ax, num_cols): + def _setup_violin_axes_ticks(self, row_ax: Axes, num_cols: int): """ Configures each of the violin plot axes ticks like remove or add labels etc. @@ -569,7 +567,7 @@ def _setup_violin_axes_ticks(self, row_ax, num_cols): # remove the default seaborn grids because in such a compact # plot are unnecessary - row_ax.grid(False) + row_ax.grid(visible=False) if self.ylim is not None: row_ax.set_ylim(self.ylim) if self.log: diff --git a/src/scanpy/plotting/_tools/paga.py b/src/scanpy/plotting/_tools/paga.py index 56feead5a6..49fe1c9d2c 100644 --- a/src/scanpy/plotting/_tools/paga.py +++ b/src/scanpy/plotting/_tools/paga.py @@ -1263,7 +1263,7 @@ def moving_average(a): ax.set_frame_on(False) ax.set_xticks([]) ax.tick_params(axis="both", which="both", length=0) - ax.grid(False) + ax.grid(visible=False) if show_colorbar: plt.colorbar(img, ax=ax) left_margin = 0.2 if left_margin is None else left_margin @@ -1327,7 +1327,7 @@ def moving_average(a): ), ) groups_axis.set_xticks([]) - groups_axis.grid(False) + groups_axis.grid(visible=False) groups_axis.tick_params(axis="both", which="both", length=0) # further annotations y_shift = ax_bounds[3] / len(keys) @@ -1364,7 +1364,7 @@ def moving_average(a): anno_axis.set_yticks([]) anno_axis.set_frame_on(False) anno_axis.set_xticks([]) - anno_axis.grid(False) + anno_axis.grid(visible=False) if title is not None: ax.set_title(title, fontsize=title_fontsize) if show is None and not ax_was_none: diff --git a/src/scanpy/plotting/_tools/scatterplots.py b/src/scanpy/plotting/_tools/scatterplots.py index 4bdb3a0080..611b698078 100644 --- a/src/scanpy/plotting/_tools/scatterplots.py +++ b/src/scanpy/plotting/_tools/scatterplots.py @@ -1357,6 +1357,7 @@ def _check_img( spatial_data: Mapping | None, img: np.ndarray | None, img_key: None | str | Empty, + *, bw: bool = False, ) -> tuple[np.ndarray | None, str | None]: """ diff --git a/src/scanpy/plotting/_utils.py b/src/scanpy/plotting/_utils.py index 57c4887681..c26cc121b1 100644 --- a/src/scanpy/plotting/_utils.py +++ b/src/scanpy/plotting/_utils.py @@ -535,7 +535,7 @@ def _set_default_colors_for_categorical_obs(adata, value_to_plot): def add_colors_for_categorical_sample_annotation( - adata, key, palette=None, force_update_colors=False + adata, key, *, palette=None, force_update_colors=False ): color_key = f"{key}_colors" colors_needed = len(adata.obs[key].cat.categories) diff --git a/src/scanpy/preprocessing/_deprecated/__init__.py b/src/scanpy/preprocessing/_deprecated/__init__.py index c2c363af01..bb944b874a 100644 --- a/src/scanpy/preprocessing/_deprecated/__init__.py +++ b/src/scanpy/preprocessing/_deprecated/__init__.py @@ -1,11 +1,14 @@ from __future__ import annotations import numpy as np +from legacy_api_wrap import legacy_api from scipy.sparse import csr_matrix, issparse +@legacy_api("max_fraction", "mult_with_mean") def normalize_per_cell_weinreb16_deprecated( X: np.ndarray, + *, max_fraction: float = 1, mult_with_mean: bool = False, ) -> np.ndarray: diff --git a/src/scanpy/preprocessing/_deprecated/highly_variable_genes.py b/src/scanpy/preprocessing/_deprecated/highly_variable_genes.py index ff29536ac8..ab75346127 100644 --- a/src/scanpy/preprocessing/_deprecated/highly_variable_genes.py +++ b/src/scanpy/preprocessing/_deprecated/highly_variable_genes.py @@ -6,6 +6,7 @@ import numpy as np import pandas as pd from anndata import AnnData +from legacy_api_wrap import legacy_api from scipy.sparse import issparse from ... import logging as logg @@ -18,8 +19,21 @@ from scipy.sparse import spmatrix -def filter_genes_dispersion( # noqa: PLR0917 +@legacy_api( + "flavor", + "min_disp", + "max_disp", + "min_mean", + "max_mean", + "n_bins", + "n_top_genes", + "log", + "subset", + "copy", +) +def filter_genes_dispersion( data: AnnData | spmatrix | np.ndarray, + *, flavor: Literal["seurat", "cell_ranger"] = "seurat", min_disp: float | None = None, max_disp: float | None = None, diff --git a/src/scanpy/preprocessing/_normalization.py b/src/scanpy/preprocessing/_normalization.py index de21a18631..c6fccfb70a 100644 --- a/src/scanpy/preprocessing/_normalization.py +++ b/src/scanpy/preprocessing/_normalization.py @@ -26,7 +26,7 @@ from anndata import AnnData -def _normalize_data(X, counts, after=None, copy: bool = False): +def _normalize_data(X, counts, after=None, *, copy: bool = False): X = X.copy() if copy else X if issubclass(X.dtype.type, (int, np.integer)): X = X.astype(np.float32) # TODO: Check if float64 should be used diff --git a/src/scanpy/preprocessing/_qc.py b/src/scanpy/preprocessing/_qc.py index f4e14054f9..508beb7861 100644 --- a/src/scanpy/preprocessing/_qc.py +++ b/src/scanpy/preprocessing/_qc.py @@ -26,7 +26,7 @@ from scipy.sparse import spmatrix -def _choose_mtx_rep(adata, use_raw: bool = False, layer: str | None = None): +def _choose_mtx_rep(adata, *, use_raw: bool = False, layer: str | None = None): is_layer = layer is not None if use_raw and is_layer: raise ValueError( @@ -98,7 +98,7 @@ def describe_obs( ) # Handle whether X is passed if X is None: - X = _choose_mtx_rep(adata, use_raw, layer) + X = _choose_mtx_rep(adata, use_raw=use_raw, layer=layer) if isspmatrix_coo(X): X = csr_matrix(X) # COO not subscriptable if issparse(X): @@ -185,7 +185,7 @@ def describe_var( """ # Handle whether X is passed if X is None: - X = _choose_mtx_rep(adata, use_raw, layer) + X = _choose_mtx_rep(adata, use_raw=use_raw, layer=layer) if isspmatrix_coo(X): X = csr_matrix(X) # COO not subscriptable if issparse(X): @@ -303,7 +303,7 @@ def calculate_qc_metrics( FutureWarning, ) # Pass X so I only have to do it once - X = _choose_mtx_rep(adata, use_raw, layer) + X = _choose_mtx_rep(adata, use_raw=use_raw, layer=layer) if isspmatrix_coo(X): X = csr_matrix(X) # COO not subscriptable if issparse(X): diff --git a/src/scanpy/preprocessing/_scale.py b/src/scanpy/preprocessing/_scale.py index f6f4b4e586..be452c356d 100644 --- a/src/scanpy/preprocessing/_scale.py +++ b/src/scanpy/preprocessing/_scale.py @@ -44,7 +44,7 @@ def _scale_sparse_numba(indptr, indices, data, *, std, mask_obs, clip): @numba.njit(parallel=True, cache=True) -def clip_array(X: np.ndarray, max_value: float | None = 10, zero_center: bool = True): +def clip_array(X: np.ndarray, *, max_value: float = 10, zero_center: bool = True): a_min, a_max = -max_value, max_value if X.ndim > 1: for r, c in numba.pndindex(X.shape): @@ -216,7 +216,9 @@ def clip_set(x): X = da.map_blocks(clip_set, X) else: if isinstance(X, DaskArray): - X = X.map_blocks(clip_array, max_value, zero_center) + X = X.map_blocks( + clip_array, max_value=max_value, zero_center=zero_center + ) elif issparse(X): X.data = clip_array(X.data, max_value=max_value, zero_center=False) else: diff --git a/src/scanpy/preprocessing/_scrublet/core.py b/src/scanpy/preprocessing/_scrublet/core.py index b608443de6..20d49eda04 100644 --- a/src/scanpy/preprocessing/_scrublet/core.py +++ b/src/scanpy/preprocessing/_scrublet/core.py @@ -34,7 +34,7 @@ kw_only = lambda _: {} # noqa: E731 -@dataclass(**kw_only(True)) +@dataclass(**kw_only(True)) # noqa: FBT003 class Scrublet: """\ Initialize Scrublet object with counts matrix and doublet prediction parameters @@ -73,7 +73,7 @@ class Scrublet: # init fields counts_obs: InitVar[sparse.csr_matrix | sparse.csc_matrix | NDArray[np.integer]] = ( - field(**kw_only(False)) + field(**kw_only(False)) # noqa: FBT003 ) total_counts_obs: InitVar[NDArray[np.integer] | None] = None sim_doublet_ratio: float = 2.0 @@ -278,6 +278,7 @@ def set_manifold( def calculate_doublet_scores( self, + *, use_approx_neighbors: bool | None = None, distance_metric: _Metric | _MetricFn = "euclidean", get_doublet_neighbor_parents: bool = False, diff --git a/src/scanpy/preprocessing/_simple.py b/src/scanpy/preprocessing/_simple.py index c22313827f..aea5d93324 100644 --- a/src/scanpy/preprocessing/_simple.py +++ b/src/scanpy/preprocessing/_simple.py @@ -13,6 +13,7 @@ import numpy as np import scipy as sp from anndata import AnnData +from legacy_api_wrap import legacy_api from pandas.api.types import CategoricalDtype from scipy.sparse import csr_matrix, issparse, isspmatrix_csr, spmatrix from sklearn.utils import check_array, sparsefuncs @@ -546,8 +547,18 @@ def sqrt( return X.sqrt() -def normalize_per_cell( # noqa: PLR0917 +@legacy_api( + "counts_per_cell_after", + "counts_per_cell", + "key_n_counts", + "copy", + "layers", + "use_rep", + "min_counts", +) +def normalize_per_cell( data: AnnData | np.ndarray | spmatrix, + *, counts_per_cell_after: float | None = None, counts_per_cell: np.ndarray | None = None, key_n_counts: str = "n_counts", @@ -1026,7 +1037,9 @@ def _downsample_total_counts(X, total_counts, random_state, replace): X = original_type(X) else: v = X.reshape(np.multiply(*X.shape)) - _downsample_array(v, total_counts, random_state, replace=replace, inplace=True) + _downsample_array( + v, total_counts, random_state=random_state, replace=replace, inplace=True + ) return X @@ -1034,6 +1047,7 @@ def _downsample_total_counts(X, total_counts, random_state, replace): def _downsample_array( col: np.ndarray, target: int, + *, random_state: AnyRandom = 0, replace: bool = True, inplace: bool = False, diff --git a/src/scanpy/readwrite.py b/src/scanpy/readwrite.py index 98b6438a90..90179daf46 100644 --- a/src/scanpy/readwrite.py +++ b/src/scanpy/readwrite.py @@ -20,6 +20,7 @@ read_mtx, read_text, ) +from legacy_api_wrap import legacy_api from matplotlib.image import imread from . import logging as logg @@ -672,8 +673,9 @@ def write( # ------------------------------------------------------------------------------- +@legacy_api("as_header") def read_params( - filename: Path | str, asheader: bool = False + filename: Path | str, *, as_header: bool = False ) -> dict[str, int | float | bool | str | None]: """\ Read parameter dictionary from text file. @@ -702,7 +704,7 @@ def read_params( params = OrderedDict([]) for line in filename.open(): if "=" in line: - if not asheader or line.startswith("#"): + if not as_header or line.startswith("#"): line = line[1:] if line.startswith("#") else line key, val = line.split("=") key = key.strip() @@ -1053,7 +1055,7 @@ def _check_datafile_present_and_download(path, backup_url=None): return True -def is_valid_filename(filename: Path, return_ext=False): +def is_valid_filename(filename: Path, *, return_ext: bool = False): """Check whether the argument is a filename.""" ext = filename.suffixes diff --git a/src/scanpy/tools/_ingest.py b/src/scanpy/tools/_ingest.py index 3d05937d81..136f58af46 100644 --- a/src/scanpy/tools/_ingest.py +++ b/src/scanpy/tools/_ingest.py @@ -5,6 +5,7 @@ import numpy as np import pandas as pd +from legacy_api_wrap import legacy_api from packaging.version import Version from scipy.sparse import issparse from sklearn.utils import check_random_state @@ -467,7 +468,8 @@ def map_labels(self, labels, method): else: raise NotImplementedError("Ingest supports knn labeling for now.") - def to_adata(self, inplace=False): + @legacy_api("inplace") + def to_adata(self, *, inplace: bool = False) -> AnnData | None: """\ Returns `adata_new` with mapped embeddings and labels. diff --git a/src/scanpy/tools/_rank_genes_groups.py b/src/scanpy/tools/_rank_genes_groups.py index 1fc2727091..3327fe7501 100644 --- a/src/scanpy/tools/_rank_genes_groups.py +++ b/src/scanpy/tools/_rank_genes_groups.py @@ -275,7 +275,7 @@ def t_test( yield group_index, scores, pvals def wilcoxon( - self, tie_correct: bool + self, *, tie_correct: bool ) -> Generator[tuple[int, NDArray[np.floating], NDArray[np.floating]], None, None]: from scipy import stats @@ -408,7 +408,7 @@ def compute_statistics( if method in {"t-test", "t-test_overestim_var"}: generate_test_results = self.t_test(method) elif method == "wilcoxon": - generate_test_results = self.wilcoxon(tie_correct) + generate_test_results = self.wilcoxon(tie_correct=tie_correct) elif method == "logreg": generate_test_results = self.logreg(**kwds) diff --git a/tests/test_neighbors_common.py b/tests/test_neighbors_common.py index b7c63eddc6..2ae59b2b5a 100644 --- a/tests/test_neighbors_common.py +++ b/tests/test_neighbors_common.py @@ -57,6 +57,7 @@ def mk_knn_matrix( @pytest.mark.parametrize("style", ["basic", "rapids", "sklearn"]) @pytest.mark.parametrize("duplicates", [True, False], ids=["duplicates", "unique"]) def test_ind_dist_shortcut_manual( + *, n_neighbors: int | None, style: Literal["basic", "rapids", "sklearn"], duplicates: bool, diff --git a/tests/test_normalization.py b/tests/test_normalization.py index 922d55a40a..2527c997db 100644 --- a/tests/test_normalization.py +++ b/tests/test_normalization.py @@ -236,7 +236,7 @@ def test_normalize_pearson_residuals_pca( n_cells, n_genes = adata.shape n_unmasked = n_genes - 5 adata.var["test_mask"] = np.r_[ - np.repeat(True, n_unmasked), np.repeat(False, n_genes - n_unmasked) + np.repeat(True, n_unmasked), np.repeat(False, n_genes - n_unmasked) # noqa: FBT003 ] n_var_copy = locals()[n_var_copy_name] assert isinstance(n_var_copy, (int, np.integer)) diff --git a/tests/test_rank_genes_groups.py b/tests/test_rank_genes_groups.py index e81d1c1112..a36e6b14f1 100644 --- a/tests/test_rank_genes_groups.py +++ b/tests/test_rank_genes_groups.py @@ -320,7 +320,7 @@ def test_mask_n_genes(n_genes_add, n_genes_out_add): pbmc = pbmc68k_reduced() mask_var = np.zeros(pbmc.shape[1]).astype(bool) - mask_var[:6].fill(True) + mask_var[:6].fill(True) # noqa: FBT003 no_genes = sum(mask_var) - 1 rank_genes_groups( diff --git a/tests/test_score_genes.py b/tests/test_score_genes.py index ddb4b1a3e4..7f0c00c8f2 100644 --- a/tests/test_score_genes.py +++ b/tests/test_score_genes.py @@ -277,7 +277,7 @@ def test_no_control_gene(): @pytest.mark.parametrize( "ctrl_as_ref", [True, False], ids=["ctrl_as_ref", "no_ctrl_as_ref"] ) -def test_gene_list_is_control(ctrl_as_ref: bool): +def test_gene_list_is_control(*, ctrl_as_ref: bool): np.random.seed(0) adata = sc.datasets.blobs(n_variables=10, n_observations=100, n_centers=20) adata.var_names = "g" + adata.var_names From 48d95663011d8df88b69422f477a127ab020c413 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 1 Aug 2024 18:16:12 +0200 Subject: [PATCH 025/118] Add Ruff pytest-style (#3191) --- pyproject.toml | 1 + src/scanpy/cli.py | 6 +-- src/scanpy/get/get.py | 7 +-- src/scanpy/plotting/_tools/scatterplots.py | 2 +- src/scanpy/tools/_leiden.py | 2 +- .../scanpy/_pytest/fixtures/__init__.py | 4 +- src/testing/scanpy/_pytest/fixtures/data.py | 14 +++--- tests/conftest.py | 8 +-- tests/test_aggregated.py | 6 +-- tests/test_binary.py | 19 ++++--- tests/test_clustering.py | 12 ++--- tests/test_datasets.py | 18 +++---- tests/test_embedding_plots.py | 12 +++-- tests/test_get.py | 8 +-- tests/test_highly_variable_genes.py | 4 +- tests/test_ingest.py | 2 +- tests/test_neighbors.py | 2 +- tests/test_neighbors_key_added.py | 5 +- tests/test_package_structure.py | 2 +- tests/test_paga.py | 10 ++-- tests/test_pca.py | 9 ++-- tests/test_plotting.py | 50 ++++++++++--------- tests/test_preprocessing.py | 26 +++++----- tests/test_preprocessing_distributed.py | 2 +- tests/test_qc_metrics.py | 2 +- tests/test_queries.py | 4 +- tests/test_read_10x.py | 6 +-- tests/test_scaling.py | 2 +- tests/test_score_genes.py | 2 +- tests/test_scrublet.py | 6 +-- 30 files changed, 136 insertions(+), 117 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ecde4651f4..e9311a47b8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -233,6 +233,7 @@ select = [ "PTH", # Pathlib instead of os.path "PLR0917", # Ban APIs with too many positional parameters "FBT", # No positional boolean parameters + "PT", # Pytest style ] ignore = [ # line too long -> we accept long comment lines; black gets rid of long code lines diff --git a/src/scanpy/cli.py b/src/scanpy/cli.py index 0ccdb8b33b..4a41c3a0d4 100644 --- a/src/scanpy/cli.py +++ b/src/scanpy/cli.py @@ -106,9 +106,9 @@ def parse_known_args( args: Sequence[str] | None = None, namespace: Namespace | None = None, ) -> tuple[Namespace, list[str]]: - assert ( - args is not None and namespace is None - ), "Only use DelegatingParser as subparser" + msg = "Only use DelegatingParser as subparser" + assert args is not None, msg + assert namespace is None, msg return Namespace(func=partial(run, [self.prog, *args], **self.cd.runargs)), [] diff --git a/src/scanpy/get/get.py b/src/scanpy/get/get.py index 4d073baeb2..c5e95de1ab 100644 --- a/src/scanpy/get/get.py +++ b/src/scanpy/get/get.py @@ -480,10 +480,11 @@ def _set_obs_rep( elif is_obsp: adata.obsp[obsp] = val else: - assert False, ( - "That was unexpected. Please report this bug at:\n\n\t" - " https://github.com/scverse/scanpy/issues" + msg = ( + "That was unexpected. Please report this bug at:\n\n" + "\thttps://github.com/scverse/scanpy/issues" ) + raise AssertionError(msg) def _check_mask( diff --git a/src/scanpy/plotting/_tools/scatterplots.py b/src/scanpy/plotting/_tools/scatterplots.py index 611b698078..ca44014459 100644 --- a/src/scanpy/plotting/_tools/scatterplots.py +++ b/src/scanpy/plotting/_tools/scatterplots.py @@ -1404,7 +1404,7 @@ def _broadcast_args(*args): lens = [len(arg) for arg in args] longest = max(lens) if not (set(lens) == {1, longest} or set(lens) == {longest}): - raise ValueError(f"Could not broadast together arguments with shapes: {lens}.") + raise ValueError(f"Could not broadcast together arguments with shapes: {lens}.") return list( [[arg[0] for _ in range(longest)] if len(arg) == 1 else arg for arg in args] ) diff --git a/src/scanpy/tools/_leiden.py b/src/scanpy/tools/_leiden.py index 4514fd8978..5a8ba00484 100644 --- a/src/scanpy/tools/_leiden.py +++ b/src/scanpy/tools/_leiden.py @@ -125,7 +125,7 @@ def leiden( if flavor == "igraph": if directed: raise ValueError( - "Cannot use igraph's leiden implemntation with a directed graph." + "Cannot use igraph’s leiden implementation with a directed graph." ) if partition_type is not None: raise ValueError( diff --git a/src/testing/scanpy/_pytest/fixtures/__init__.py b/src/testing/scanpy/_pytest/fixtures/__init__.py index 2a490ab6ab..db0d525589 100644 --- a/src/testing/scanpy/_pytest/fixtures/__init__.py +++ b/src/testing/scanpy/_pytest/fixtures/__init__.py @@ -12,10 +12,10 @@ import pytest from .data import ( - _pbmc3ks_parametrized_session, backed_adata, pbmc3k_parametrized, pbmc3k_parametrized_small, + pbmc3ks_parametrized_session, ) if TYPE_CHECKING: @@ -25,7 +25,7 @@ __all__ = [ "float_dtype", "_doctest_env", - "_pbmc3ks_parametrized_session", + "pbmc3ks_parametrized_session", "pbmc3k_parametrized", "pbmc3k_parametrized_small", "backed_adata", diff --git a/src/testing/scanpy/_pytest/fixtures/data.py b/src/testing/scanpy/_pytest/fixtures/data.py index 3d907c9fec..75ecd2a81e 100644 --- a/src/testing/scanpy/_pytest/fixtures/data.py +++ b/src/testing/scanpy/_pytest/fixtures/data.py @@ -40,7 +40,7 @@ def make_sparse(x): ), ids=lambda x: f"{x[0].__name__}-{x[1]}", ) -def _pbmc3ks_parametrized_session(request) -> dict[bool, AnnData]: +def pbmc3ks_parametrized_session(request) -> dict[bool, AnnData]: from ..._helpers.data import pbmc3k sparsity_func, dtype = request.param @@ -50,14 +50,14 @@ def _pbmc3ks_parametrized_session(request) -> dict[bool, AnnData]: } -@pytest.fixture -def pbmc3k_parametrized(_pbmc3ks_parametrized_session) -> Callable[[], AnnData]: - return _pbmc3ks_parametrized_session[False].copy +@pytest.fixture() +def pbmc3k_parametrized(pbmc3ks_parametrized_session) -> Callable[[], AnnData]: + return pbmc3ks_parametrized_session[False].copy -@pytest.fixture -def pbmc3k_parametrized_small(_pbmc3ks_parametrized_session) -> Callable[[], AnnData]: - return _pbmc3ks_parametrized_session[True].copy +@pytest.fixture() +def pbmc3k_parametrized_small(pbmc3ks_parametrized_session) -> Callable[[], AnnData]: + return pbmc3ks_parametrized_session[True].copy @pytest.fixture( diff --git a/tests/conftest.py b/tests/conftest.py index 52bc61168a..82a8e4166e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -56,7 +56,7 @@ def _caplog_adapter(caplog: pytest.LogCaptureFixture) -> Generator[None, None, N sc.settings._root_logger.removeHandler(caplog.handler) -@pytest.fixture +@pytest.fixture() def imported_modules(): return IMPORTED @@ -69,7 +69,7 @@ class CompareResult(TypedDict): tol: int -@pytest.fixture +@pytest.fixture() def check_same_image(add_nunit_attachment): from urllib.parse import quote @@ -117,7 +117,7 @@ def fmt_descr(descr): return check_same_image -@pytest.fixture +@pytest.fixture() def image_comparer(check_same_image): from matplotlib import pyplot as plt @@ -139,7 +139,7 @@ def save_and_compare(*path_parts: Path | os.PathLike, tol: int): return save_and_compare -@pytest.fixture +@pytest.fixture() def plt(): from matplotlib import pyplot as plt diff --git a/tests/test_aggregated.py b/tests/test_aggregated.py index ce680b8df5..f16bc80a48 100644 --- a/tests/test_aggregated.py +++ b/tests/test_aggregated.py @@ -22,13 +22,13 @@ def metric(request: pytest.FixtureRequest) -> AggType: return request.param -@pytest.fixture +@pytest.fixture() def df_base(): ax_base = ["A", "B"] return pd.DataFrame(index=ax_base) -@pytest.fixture +@pytest.fixture() def df_groupby(): ax_groupby = [ *["v0", "v1", "v2"], @@ -49,7 +49,7 @@ def df_groupby(): return df_groupby -@pytest.fixture +@pytest.fixture() def X(): data = [ *[[0, -2], [1, 13], [2, 1]], # v diff --git a/tests/test_binary.py b/tests/test_binary.py index 6b70c824f3..4e1ce7e790 100644 --- a/tests/test_binary.py +++ b/tests/test_binary.py @@ -2,6 +2,7 @@ import os import re +from contextlib import nullcontext from pathlib import Path from subprocess import PIPE from typing import TYPE_CHECKING @@ -18,8 +19,8 @@ HERE = Path(__file__).parent -@pytest.fixture -def set_path(monkeypatch: MonkeyPatch) -> None: +@pytest.fixture() +def _set_path(monkeypatch: MonkeyPatch) -> None: monkeypatch.setenv("PATH", str(HERE / "_scripts"), prepend=os.pathsep) @@ -31,15 +32,18 @@ def test_builtin_settings(capsys: CaptureFixture): @pytest.mark.parametrize("args", [[], ["-h"]]) def test_help_displayed(args: list[str], capsys: CaptureFixture): - try: # -h raises it, no args doesn’t. Maybe not ideal but meh. + # -h raises it, no args doesn’t. Maybe not ideal but meh. + ctx = pytest.raises(SystemExit) if args else nullcontext() + with ctx as se: main(args) - except SystemExit as se: - assert se.code == 0 + if se is not None: + assert se.value.code == 0 captured = capsys.readouterr() assert captured.out.startswith("usage: ") -def test_help_output(set_path: None, capsys: CaptureFixture): +@pytest.mark.usefixtures("_set_path") +def test_help_output(capsys: CaptureFixture): with pytest.raises(SystemExit, match="^0$"): main(["-h"]) captured = capsys.readouterr() @@ -50,7 +54,8 @@ def test_help_output(set_path: None, capsys: CaptureFixture): ) -def test_external(set_path: None): +@pytest.mark.usefixtures("_set_path") +def test_external(): # We need to capture the output manually, since subprocesses don’t write to sys.stderr cmdline = ["testbin", "-t", "--testarg", "testpos"] cmd = main(cmdline, stdout=PIPE, encoding="utf-8", check=True) diff --git a/tests/test_clustering.py b/tests/test_clustering.py index 1972842a05..e87b586325 100644 --- a/tests/test_clustering.py +++ b/tests/test_clustering.py @@ -8,7 +8,7 @@ from testing.scanpy._pytest.marks import needs -@pytest.fixture +@pytest.fixture() def adata_neighbors(): return pbmc68k_reduced() @@ -75,13 +75,13 @@ def test_leiden_random_state(adata_neighbors, flavor): @needs.igraph def test_leiden_igraph_directed(adata_neighbors): - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=r"Cannot use igraph’s leiden.*directed"): sc.tl.leiden(adata_neighbors, flavor="igraph", directed=True) @needs.igraph def test_leiden_wrong_flavor(adata_neighbors): - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=r"flavor must be.*'igraph'.*'leidenalg'.*but"): sc.tl.leiden(adata_neighbors, flavor="foo") @@ -90,7 +90,7 @@ def test_leiden_wrong_flavor(adata_neighbors): def test_leiden_igraph_partition_type(adata_neighbors): import leidenalg - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=r"Do not pass in partition_type"): sc.tl.leiden( adata_neighbors, flavor="igraph", @@ -147,7 +147,7 @@ def test_leiden_objective_function(adata_neighbors): @needs.igraph @pytest.mark.parametrize( - "clustering,key", + ("clustering", "key"), [ pytest.param(sc.tl.louvain, "louvain", marks=needs.louvain), pytest.param(sc.tl.leiden, "leiden", marks=needs.leidenalg), @@ -215,7 +215,7 @@ def test_partition_type(adata_neighbors): @pytest.mark.parametrize( - "clustering,default_key,default_res,custom_resolutions", + ("clustering", "default_key", "default_res", "custom_resolutions"), [ pytest.param(sc.tl.leiden, "leiden", 0.8, [0.9, 1.1], marks=needs.leidenalg), pytest.param(sc.tl.louvain, "louvain", 0.8, [0.9, 1.1], marks=needs.louvain), diff --git a/tests/test_datasets.py b/tests/test_datasets.py index 4bad3800d7..e46e68e435 100644 --- a/tests/test_datasets.py +++ b/tests/test_datasets.py @@ -33,7 +33,7 @@ def _tmp_dataset_dir(tmp_path: Path) -> None: sc.settings.datasetdir = tmp_path / "scanpy_data" -@pytest.mark.internet +@pytest.mark.internet() def test_burczynski06(): with pytest.warns(UserWarning, match=r"Variable names are not unique"): adata = sc.datasets.burczynski06() @@ -41,7 +41,7 @@ def test_burczynski06(): assert not (adata.X == 0).any() -@pytest.mark.internet +@pytest.mark.internet() @needs.openpyxl def test_moignard15(): with warnings.catch_warnings(): @@ -56,19 +56,19 @@ def test_moignard15(): assert adata.shape == (3934, 42) -@pytest.mark.internet +@pytest.mark.internet() def test_paul15(): sc.datasets.paul15() -@pytest.mark.internet +@pytest.mark.internet() def test_pbmc3k(): adata = sc.datasets.pbmc3k() assert adata.shape == (2700, 32738) assert "CD8A" in adata.var_names -@pytest.mark.internet +@pytest.mark.internet() def test_pbmc3k_processed(): with warnings.catch_warnings(record=True) as records: adata = sc.datasets.pbmc3k_processed() @@ -78,7 +78,7 @@ def test_pbmc3k_processed(): assert len(records) == 0 -@pytest.mark.internet +@pytest.mark.internet() def test_ebi_expression_atlas(): adata = sc.datasets.ebi_expression_atlas("E-MTAB-4888") # The shape changes sometimes @@ -111,7 +111,7 @@ def test_pbmc68k_reduced(): sc.datasets.pbmc68k_reduced() -@pytest.mark.internet +@pytest.mark.internet() def test_visium_datasets(): """Tests that reading/ downloading works and is does not have global effects.""" with pytest.warns(UserWarning, match=r"Variable names are not unique"): @@ -121,7 +121,7 @@ def test_visium_datasets(): assert_adata_equal(hheart, hheart_again) -@pytest.mark.internet +@pytest.mark.internet() def test_visium_datasets_dir_change(tmp_path: Path): """Test that changing the dataset dir doesn't break reading.""" with pytest.warns(UserWarning, match=r"Variable names are not unique"): @@ -132,7 +132,7 @@ def test_visium_datasets_dir_change(tmp_path: Path): assert_adata_equal(mbrain, mbrain_again) -@pytest.mark.internet +@pytest.mark.internet() def test_visium_datasets_images(): """Test that image download works and is does not have global effects.""" diff --git a/tests/test_embedding_plots.py b/tests/test_embedding_plots.py index 1420687084..3c1bab6d51 100644 --- a/tests/test_embedding_plots.py +++ b/tests/test_embedding_plots.py @@ -85,7 +85,7 @@ def adata(): return adata -@pytest.fixture +@pytest.fixture() def fixture_request(request): """Returns a Request object. @@ -234,7 +234,10 @@ def test_enumerated_palettes(fixture_request, adata, tmpdir, plotfunc): def test_dimension_broadcasting(adata, tmpdir, check_same_image): tmpdir = Path(tmpdir) - with pytest.raises(ValueError): + with pytest.raises( + ValueError, + match=r"Could not broadcast together arguments with shapes: \[2, 3, 1\]", + ): sc.pl.pca( adata, color=["label", "1_missing"], dimensions=[(0, 1), (1, 2), (2, 3)] ) @@ -255,7 +258,10 @@ def test_dimension_broadcasting(adata, tmpdir, check_same_image): def test_marker_broadcasting(adata, tmpdir, check_same_image): tmpdir = Path(tmpdir) - with pytest.raises(ValueError): + with pytest.raises( + ValueError, + match=r"Could not broadcast together arguments with shapes: \[2, 1, 3\]", + ): sc.pl.pca(adata, color=["label", "1_missing"], marker=[".", "^", "x"]) dims_pth = tmpdir / "broadcast_markers.png" diff --git a/tests/test_get.py b/tests/test_get.py index a171220243..4eff3ee23f 100644 --- a/tests/test_get.py +++ b/tests/test_get.py @@ -33,7 +33,7 @@ def transpose_adata(adata: AnnData, *, expect_duplicates: bool = False) -> AnnDa ) -@pytest.fixture +@pytest.fixture() def adata(): """ adata.X is np.ones((2, 2)) @@ -327,7 +327,7 @@ def test_non_unique_cols_value_error(): index=[f"gene_{i}" for i in range(N)], ), ) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=r"adata\.obs contains duplicated columns"): sc.get.obs_df(adata, ["repeated_col"]) @@ -337,7 +337,7 @@ def test_non_unique_var_index_value_error(): obs=pd.DataFrame(index=["cell-0", "cell-1"]), var=pd.DataFrame(index=["gene-0", "gene-0", "gene-1"]), ) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=r"adata\.var_names contains duplicated items"): sc.get.obs_df(adata, ["gene-0"]) @@ -456,7 +456,7 @@ def shared_key_adata(request): r"'var_id'.* adata\.obs .* adata\.raw\.var\['gene_symbols'\]", ) else: - assert False + pytest.fail("add branch for new kind") def test_shared_key_errors(shared_key_adata): diff --git a/tests/test_highly_variable_genes.py b/tests/test_highly_variable_genes.py index 391a83ddf0..8b87074fe1 100644 --- a/tests/test_highly_variable_genes.py +++ b/tests/test_highly_variable_genes.py @@ -36,7 +36,7 @@ def adata_sess() -> AnnData: return adata -@pytest.fixture +@pytest.fixture() def adata(adata_sess: AnnData) -> AnnData: return adata_sess.copy() @@ -127,7 +127,7 @@ def test_keep_layer(base, flavor): elif flavor == "cell_ranger": sc.pp.highly_variable_genes(adata, flavor=flavor) else: - assert False + pytest.fail(f"Unknown {flavor=}") assert np.allclose(X_orig.toarray(), adata.X.toarray()) diff --git a/tests/test_ingest.py b/tests/test_ingest.py index 2c57342de1..31f38a40a7 100644 --- a/tests/test_ingest.py +++ b/tests/test_ingest.py @@ -26,7 +26,7 @@ T = np.array([[2.0, 3.5, 4.0, 1.0, 4.7], [3.2, 2.0, 5.0, 5.0, 8.0]], dtype=np.float32) -@pytest.fixture +@pytest.fixture() def adatas(): pbmc = pbmc68k_reduced() n_split = 500 diff --git a/tests/test_neighbors.py b/tests/test_neighbors.py index 806594ff8d..1cf74a8d8f 100644 --- a/tests/test_neighbors.py +++ b/tests/test_neighbors.py @@ -119,7 +119,7 @@ def get_neighbors() -> Neighbors: return Neighbors(anndata_v0_8_constructor_compat(np.array(X))) -@pytest.fixture +@pytest.fixture() def neigh() -> Neighbors: return get_neighbors() diff --git a/tests/test_neighbors_key_added.py b/tests/test_neighbors_key_added.py index 4f30cee047..4bc4a068f9 100644 --- a/tests/test_neighbors_key_added.py +++ b/tests/test_neighbors_key_added.py @@ -11,7 +11,7 @@ key = "test" -@pytest.fixture +@pytest.fixture() def adata(): return sc.AnnData(pbmc68k_reduced().X) @@ -33,7 +33,8 @@ def test_neighbors_key_added(adata): def test_neighbors_pca_keys_added_without_previous_pca_run(adata): - assert "pca" not in adata.uns and "X_pca" not in adata.obsm + assert "pca" not in adata.uns + assert "X_pca" not in adata.obsm with pytest.warns( UserWarning, match=r".*Falling back to preprocessing with `sc.pp.pca` and default params", diff --git a/tests/test_package_structure.py b/tests/test_package_structure.py index 19a6836e65..58df6515e9 100644 --- a/tests/test_package_structure.py +++ b/tests/test_package_structure.py @@ -53,7 +53,7 @@ ] -@pytest.fixture +@pytest.fixture() def in_project_dir(): wd_orig = Path.cwd() os.chdir(proj_dir) diff --git a/tests/test_paga.py b/tests/test_paga.py index 2f13d862b4..cbbb3095fc 100644 --- a/tests/test_paga.py +++ b/tests/test_paga.py @@ -19,7 +19,7 @@ @pytest.fixture(scope="module") -def _pbmc_session(): +def pbmc_session(): pbmc = pbmc68k_reduced() sc.tl.paga(pbmc, groups="bulk_labels") pbmc.obs["cool_feature"] = pbmc[:, "CST3"].X.squeeze().copy() @@ -27,13 +27,13 @@ def _pbmc_session(): return pbmc -@pytest.fixture -def pbmc(_pbmc_session): - return _pbmc_session.copy() +@pytest.fixture() +def pbmc(pbmc_session): + return pbmc_session.copy() @pytest.mark.parametrize( - "test_id,func", + ("test_id", "func"), [ ("", sc.pl.paga), ("continuous", partial(sc.pl.paga, color="CST3")), diff --git a/tests/test_pca.py b/tests/test_pca.py index 961271a306..4f614e6864 100644 --- a/tests/test_pca.py +++ b/tests/test_pca.py @@ -110,7 +110,7 @@ def zero_center(request: pytest.FixtureRequest): return request.param -@pytest.fixture +@pytest.fixture() def pca_params( array_type, svd_solver_type: Literal[None, "valid", "invalid"], zero_center ): @@ -136,7 +136,7 @@ def pca_params( else {"arpack", "randomized"} ) else: - assert False, f"Unknown array type {array_type}" + pytest.fail(f"Unknown array type {array_type}") if svd_solver_type == "invalid": svd_solver = all_svd_solvers - svd_solver expected_warning = "Ignoring" @@ -243,7 +243,10 @@ def test_pca_shapes(): sc.pp.pca(adata) assert adata.obsm["X_pca"].shape == (20, 19) - with pytest.raises(ValueError): + with pytest.raises( + ValueError, + match=r"n_components=100 must be between 1 and.*20 with svd_solver='arpack'", + ): sc.pp.pca(adata, n_comps=100) diff --git a/tests/test_plotting.py b/tests/test_plotting.py index 96b590268b..c8b5660e66 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -156,7 +156,7 @@ def test_heatmap(image_comparer): reason="https://github.com/mwaskom/seaborn/issues/1953", ) @pytest.mark.parametrize( - "obs_keys,name", + ("obs_keys", "name"), [(None, "clustermap"), ("cell_type", "clustermap_withcolor")], ) def test_clustermap(image_comparer, obs_keys, name): @@ -168,7 +168,7 @@ def test_clustermap(image_comparer, obs_keys, name): @pytest.mark.parametrize( - "id,fn", + ("id", "fn"), [ ( "dotplot", @@ -562,7 +562,7 @@ def test_correlation(image_comparer): @pytest.mark.parametrize( - "name,fn", + ("name", "fn"), [ ( "ranked_genes_sharey", @@ -793,7 +793,7 @@ def test_rank_genes_groups(image_comparer, name, fn): @pytest.fixture(scope="session") -def _gene_symbols_adatas(): +def gene_symbols_adatas_session() -> tuple[AnnData, AnnData]: """Create two anndata objects which are equivalent except for var_names Both have ensembl ids and hgnc symbols as columns in var. The first has ensembl @@ -825,22 +825,22 @@ def _gene_symbols_adatas(): return a, b -@pytest.fixture -def gene_symbols_adatas(_gene_symbols_adatas): - a, b = _gene_symbols_adatas +@pytest.fixture() +def gene_symbols_adatas(gene_symbols_adatas_session) -> tuple[AnnData, AnnData]: + a, b = gene_symbols_adatas_session return a.copy(), b.copy() @pytest.mark.parametrize( "func", - ( + [ sc.pl.rank_genes_groups_dotplot, sc.pl.rank_genes_groups_heatmap, sc.pl.rank_genes_groups_matrixplot, sc.pl.rank_genes_groups_stacked_violin, sc.pl.rank_genes_groups_tracksplot, # TODO: add other rank_genes_groups plots here once they work - ), + ], ) def test_plot_rank_genes_groups_gene_symbols( gene_symbols_adatas, func, tmp_path, check_same_image @@ -876,14 +876,14 @@ def test_plot_rank_genes_groups_gene_symbols( @pytest.mark.parametrize( "func", - ( + [ sc.pl.rank_genes_groups_dotplot, sc.pl.rank_genes_groups_heatmap, sc.pl.rank_genes_groups_matrixplot, sc.pl.rank_genes_groups_stacked_violin, sc.pl.rank_genes_groups_tracksplot, # TODO: add other rank_genes_groups plots here once they work - ), + ], ) def test_rank_genes_groups_plots_n_genes_vs_var_names(tmp_path, func, check_same_image): """\ @@ -933,7 +933,7 @@ def wrapped(pth, **kwargs): @pytest.mark.parametrize( - "id,fn", + ("id", "fn"), [ ("heatmap", sc.pl.heatmap), ("dotplot", sc.pl.dotplot), @@ -955,8 +955,8 @@ def test_genes_symbols(image_comparer, id, fn): save_and_compare_images(f"{id}_gene_symbols") -@pytest.fixture(scope="module") -def _pbmc_scatterplots_session(): +@pytest.fixture(scope="session") +def pbmc_scatterplots_session() -> AnnData: # Wrapped in another fixture to avoid mutation pbmc = pbmc68k_reduced() pbmc.obs["mask"] = pbmc.obs["louvain"].isin(["0", "1", "3"]) @@ -969,13 +969,13 @@ def _pbmc_scatterplots_session(): return pbmc -@pytest.fixture -def pbmc_scatterplots(_pbmc_scatterplots_session): - return _pbmc_scatterplots_session.copy() +@pytest.fixture() +def pbmc_scatterplots(pbmc_scatterplots_session) -> AnnData: + return pbmc_scatterplots_session.copy() @pytest.mark.parametrize( - "id,fn", + ("id", "fn"), [ ("pca", partial(sc.pl.pca, color="bulk_labels")), ( @@ -1295,7 +1295,7 @@ def test_binary_scatter(image_comparer): def test_scatter_specify_layer_and_raw(): pbmc = pbmc68k_reduced() pbmc.layers["layer"] = pbmc.raw.X.copy() - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=r"Cannot use both a layer and.*raw"): sc.pl.umap(pbmc, color="HES4", use_raw=True, layer="layer") @@ -1328,7 +1328,7 @@ def test_scatter_no_basis_per_var(image_comparer): save_and_compare_images("scatter_AAAGCCTGGCTAAC-1_vs_AAATTCGATGCACA-1") -@pytest.fixture +@pytest.fixture() def pbmc_filtered() -> Callable[[], AnnData]: pbmc = pbmc68k_reduced() sc.pp.filter_genes(pbmc, min_cells=10) @@ -1361,7 +1361,7 @@ def test_scatter_no_basis_raw(check_same_image, pbmc_filtered, tmpdir): @pytest.mark.parametrize( - "x,y,color,use_raw", + ("x", "y", "color", "use_raw"), [ # test that plotting fails with a ValueError if trying to plot # var_names only found in raw and use_raw is False @@ -1380,7 +1380,9 @@ def test_scatter_no_basis_value_error(pbmc_filtered, x, y, color, use_raw): raise a `ValueError`. This test checks that this happens as expected. """ - with pytest.raises(ValueError): + with pytest.raises( + ValueError, match=r"inputs must all come from either `\.obs` or `\.var`" + ): sc.pl.scatter(pbmc_filtered(), x=x, y=y, color=color, use_raw=use_raw) @@ -1577,14 +1579,14 @@ def test_repeated_colors_w_missing_value(): @pytest.mark.parametrize( "plot", - ( + [ sc.pl.rank_genes_groups_dotplot, sc.pl.rank_genes_groups_heatmap, sc.pl.rank_genes_groups_matrixplot, sc.pl.rank_genes_groups_stacked_violin, sc.pl.rank_genes_groups_tracksplot, # TODO: add other rank_genes_groups plots here once they work - ), + ], ) def test_filter_rank_genes_groups_plots(tmp_path, plot, check_same_image): N_GENES = 4 diff --git a/tests/test_preprocessing.py b/tests/test_preprocessing.py index 9504b14217..a63011bff4 100644 --- a/tests/test_preprocessing.py +++ b/tests/test_preprocessing.py @@ -356,11 +356,11 @@ def test_downsample_counts_per_cell(count_matrix_format, replace, dtype): X = np.random.randint(0, 100, (1000, 100)) * np.random.binomial(1, 0.3, (1000, 100)) X = X.astype(dtype) adata = anndata_v0_8_constructor_compat(X=count_matrix_format(X).astype(dtype)) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=r"Must specify exactly one"): sc.pp.downsample_counts( adata, counts_per_cell=TARGET, total_counts=TARGET, replace=replace ) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=r"Must specify exactly one"): sc.pp.downsample_counts(adata, replace=replace) initial_totals = np.ravel(adata.X.sum(axis=1)) adata = sc.pp.downsample_counts( @@ -389,7 +389,7 @@ def test_downsample_counts_per_cell_multiple_targets( X = X.astype(dtype) adata = anndata_v0_8_constructor_compat(X=count_matrix_format(X).astype(dtype)) initial_totals = np.ravel(adata.X.sum(axis=1)) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=r"counts_per_cell.*length as number of obs"): sc.pp.downsample_counts(adata, counts_per_cell=[40, 10], replace=replace) adata = sc.pp.downsample_counts( adata, counts_per_cell=TARGETS, replace=replace, copy=True @@ -448,12 +448,12 @@ def test_recipe_weinreb(): @pytest.mark.parametrize("array_type", ARRAY_TYPES) @pytest.mark.parametrize( - "max_cells,max_counts,min_cells,min_counts", + ("max_cells", "max_counts", "min_cells", "min_counts"), [ - [100, None, None, None], - [None, 100, None, None], - [None, None, 20, None], - [None, None, None, 20], + (100, None, None, None), + (None, 100, None, None), + (None, None, 20, None), + (None, None, None, 20), ], ) def test_filter_genes(array_type, max_cells, max_counts, min_cells, min_counts): @@ -487,12 +487,12 @@ def test_filter_genes(array_type, max_cells, max_counts, min_cells, min_counts): @pytest.mark.parametrize("array_type", ARRAY_TYPES) @pytest.mark.parametrize( - "max_genes,max_counts,min_genes,min_counts", + ("max_genes", "max_counts", "min_genes", "min_counts"), [ - [100, None, None, None], - [None, 100, None, None], - [None, None, 20, None], - [None, None, None, 20], + (100, None, None, None), + (None, 100, None, None), + (None, None, 20, None), + (None, None, None, 20), ], ) def test_filter_cells(array_type, max_genes, max_counts, min_genes, min_counts): diff --git a/tests/test_preprocessing_distributed.py b/tests/test_preprocessing_distributed.py index fcbe41c465..f0451fb07b 100644 --- a/tests/test_preprocessing_distributed.py +++ b/tests/test_preprocessing_distributed.py @@ -156,7 +156,7 @@ def test_write_zarr(adata: AnnData, adata_dist: AnnData): elif adata_dist.uns["dist-mode"] == "direct": adata_dist.X.to_zarr(temp_store.dir_path("X"), chunks) else: - assert False, "add branch for new dist-mode" + pytest.fail("add branch for new dist-mode") # read back as zarr directly and check it is the same as adata.X adata_log1p = read_zarr(temp_store) diff --git a/tests/test_qc_metrics.py b/tests/test_qc_metrics.py index 83971fa2ce..16449a5eed 100644 --- a/tests/test_qc_metrics.py +++ b/tests/test_qc_metrics.py @@ -15,7 +15,7 @@ ) -@pytest.fixture +@pytest.fixture() def anndata(): a = np.random.binomial(100, 0.005, (1000, 1000)) adata = AnnData( diff --git a/tests/test_queries.py b/tests/test_queries.py index d25df9d331..769b7aa2d1 100644 --- a/tests/test_queries.py +++ b/tests/test_queries.py @@ -8,7 +8,7 @@ from testing.scanpy._pytest.marks import needs -@pytest.mark.internet +@pytest.mark.internet() @needs.gprofiler def test_enrich(): pbmc = pbmc68k_reduced() @@ -33,7 +33,7 @@ def test_enrich(): assert "set2" in enrich_list["query"].unique() -@pytest.mark.internet +@pytest.mark.internet() @needs.pybiomart def test_mito_genes(): pbmc = pbmc68k_reduced() diff --git a/tests/test_read_10x.py b/tests/test_read_10x.py index 1fe7d20315..7b31f6bddf 100644 --- a/tests/test_read_10x.py +++ b/tests/test_read_10x.py @@ -23,7 +23,7 @@ def assert_anndata_equal(a1, a2): @pytest.mark.parametrize( - ["mtx_path", "h5_path"], + ("mtx_path", "h5_path"), [ pytest.param( ROOT / "1.2.0" / "filtered_gene_bc_matrices" / "hg19_chr21", @@ -109,7 +109,7 @@ def test_error_10x_h5_legacy(tmp_path): with h5py.File(onepth, "r") as one, h5py.File(twopth, "w") as two: one.copy("hg19_chr21", two) one.copy("hg19_chr21", two, name="hg19_chr21_copy") - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=r"contains more than one genome"): sc.read_10x_h5(twopth) sc.read_10x_h5(twopth, genome="hg19_chr21_copy") @@ -140,7 +140,7 @@ def visium_pth(request, tmp_path) -> Path: (orig.parent / "tissue_positions.csv").write_text(csv) return visium2_pth else: - assert False + pytest.fail("add branch for new visium version") def test_read_visium_counts(visium_pth): diff --git a/tests/test_scaling.py b/tests/test_scaling.py index b169f7a51e..fad2443dc1 100644 --- a/tests/test_scaling.py +++ b/tests/test_scaling.py @@ -114,7 +114,7 @@ def test_scale(*, typ, dtype, mask_obs, X, X_centered, X_scaled): def test_mask_string(): - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=r"Cannot refer to mask.* without.*anndata"): sc.pp.scale(np.array(X_original), mask_obs="mask") adata = AnnData(np.array(X_for_mask, dtype="float32")) adata.obs["some cells"] = np.array((0, 0, 1, 1, 1, 0, 0), dtype=bool) diff --git a/tests/test_score_genes.py b/tests/test_score_genes.py index 7f0c00c8f2..c243b8e022 100644 --- a/tests/test_score_genes.py +++ b/tests/test_score_genes.py @@ -221,7 +221,7 @@ def test_missing_genes(): # These genes have a different length of name non_extant_genes = _create_random_gene_names(n_genes=3, name_length=7) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=r"No valid genes were passed for scoring"): sc.tl.score_genes(adata, non_extant_genes) diff --git a/tests/test_scrublet.py b/tests/test_scrublet.py index b3c7172384..d8df27d710 100644 --- a/tests/test_scrublet.py +++ b/tests/test_scrublet.py @@ -167,7 +167,7 @@ def test_scrublet_data(): @pytest.fixture(scope="module") -def _scrub_small_sess() -> AnnData: +def scrub_small_sess() -> AnnData: # Reduce size of input for faster test adata = pbmc200() sc.pp.filter_genes(adata, min_counts=100) @@ -177,8 +177,8 @@ def _scrub_small_sess() -> AnnData: @pytest.fixture() -def scrub_small(_scrub_small_sess: AnnData): - return _scrub_small_sess.copy() +def scrub_small(scrub_small_sess: AnnData): + return scrub_small_sess.copy() test_params = { From 5afa91e4cd77b4d88b000917ea618f99c2227517 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 2 Aug 2024 11:11:13 +0200 Subject: [PATCH 026/118] Add key_added to umap, tsne, and pca (#3184) --- docs/release-notes/1.11.0.md | 3 +- src/scanpy/preprocessing/_pca.py | 22 +++++++++++---- src/scanpy/tools/_tsne.py | 14 ++++++++-- src/scanpy/tools/_umap.py | 14 ++++++++-- tests/test_embedding.py | 48 ++++++++++++++++++++++---------- tests/test_pca.py | 23 ++++++++++----- 6 files changed, 91 insertions(+), 33 deletions(-) diff --git a/docs/release-notes/1.11.0.md b/docs/release-notes/1.11.0.md index fee2d0b1a9..c948f8068a 100644 --- a/docs/release-notes/1.11.0.md +++ b/docs/release-notes/1.11.0.md @@ -3,8 +3,9 @@ #### Features -* Add layer argument to {func}`scanpy.tl.score_genes` and {func}`scanpy.tl.score_genes_cell_cycle` {pr}`2921` {smaller}`L Zappia` +* Add `layer` argument to {func}`scanpy.tl.score_genes` and {func}`scanpy.tl.score_genes_cell_cycle` {pr}`2921` {smaller}`L Zappia` * Prevent `raw` conflict with `layer` in {func}`~scanpy.tl.score_genes` {pr}`3155` {smaller}`S Dicks` +* Add `key_added` argument to {func}`~scanpy.pp.pca`, {func}`~scanpy.tl.tsne` and {func}`~scanpy.tl.umap` {pr}`3184` {smaller}`P Angerer` #### Docs diff --git a/src/scanpy/preprocessing/_pca.py b/src/scanpy/preprocessing/_pca.py index 0e7d28a0ef..5b5706c123 100644 --- a/src/scanpy/preprocessing/_pca.py +++ b/src/scanpy/preprocessing/_pca.py @@ -46,6 +46,7 @@ def pca( dtype: DTypeLike = "float32", chunked: bool = False, chunk_size: int | None = None, + key_added: str | None = None, copy: bool = False, ) -> AnnData | np.ndarray | spmatrix | None: """\ @@ -137,6 +138,15 @@ def pca( chunk_size Number of observations to include in each chunk. Required if `chunked=True` was passed. + key_added + If not specified, the embedding is stored as + :attr:`~anndata.AnnData.obsm`\\ `['X_pca']`, the loadings as + :attr:`~anndata.AnnData.varm`\\ `['PCs']`, and the the parameters in + :attr:`~anndata.AnnData.uns`\\ `['pca']`. + If specified, the embedding is stored as + :attr:`~anndata.AnnData.obsm`\\ ``[key_added]``, the loadings as + :attr:`~anndata.AnnData.varm`\\ ``[key_added]``, and the the parameters in + :attr:`~anndata.AnnData.uns`\\ ``[key_added]``. copy If an :class:`~anndata.AnnData` is passed, determines whether a copy is returned. Is ignored otherwise. @@ -150,13 +160,13 @@ def pca( Otherwise, it returns `None` if `copy=False`, else an updated `AnnData` object. Sets the following fields: - `.obsm['X_pca']` : :class:`~scipy.sparse.spmatrix` | :class:`~numpy.ndarray` (shape `(adata.n_obs, n_comps)`) + `.obsm['X_pca' | key_added]` : :class:`~scipy.sparse.spmatrix` | :class:`~numpy.ndarray` (shape `(adata.n_obs, n_comps)`) PCA representation of data. - `.varm['PCs']` : :class:`~numpy.ndarray` (shape `(adata.n_vars, n_comps)`) + `.varm['PCs' | key_added]` : :class:`~numpy.ndarray` (shape `(adata.n_vars, n_comps)`) The principal components containing the loadings. - `.uns['pca']['variance_ratio']` : :class:`~numpy.ndarray` (shape `(n_comps,)`) + `.uns['pca' | key_added]['variance_ratio']` : :class:`~numpy.ndarray` (shape `(n_comps,)`) Ratio of explained variance. - `.uns['pca']['variance']` : :class:`~numpy.ndarray` (shape `(n_comps,)`) + `.uns['pca' | key_added]['variance']` : :class:`~numpy.ndarray` (shape `(n_comps,)`) Explained variance, equivalent to the eigenvalues of the covariance matrix. """ @@ -313,7 +323,9 @@ def pca( X_pca = X_pca.astype(dtype) if data_is_AnnData: - key_obsm, key_varm, key_uns = ("X_pca", "PCs", "pca") + key_obsm, key_varm, key_uns = ( + ("X_pca", "PCs", "pca") if key_added is None else [key_added] * 3 + ) adata.obsm[key_obsm] = X_pca if mask_var is not None: diff --git a/src/scanpy/tools/_tsne.py b/src/scanpy/tools/_tsne.py index e1b5fe7e7c..23d490218b 100644 --- a/src/scanpy/tools/_tsne.py +++ b/src/scanpy/tools/_tsne.py @@ -41,6 +41,7 @@ def tsne( random_state: AnyRandom = 0, use_fast_tsne: bool = False, n_jobs: int | None = None, + key_added: str | None = None, copy: bool = False, ) -> AnnData | None: """\ @@ -88,6 +89,13 @@ def tsne( n_jobs Number of jobs for parallel computation. `None` means using :attr:`scanpy._settings.ScanpyConfig.n_jobs`. + key_added + If not specified, the embedding is stored as + :attr:`~anndata.AnnData.obsm`\\ `['X_tsne']` and the the parameters in + :attr:`~anndata.AnnData.uns`\\ `['tsne']`. + If specified, the embedding is stored as + :attr:`~anndata.AnnData.obsm`\\ ``[key_added]`` and the the parameters in + :attr:`~anndata.AnnData.uns`\\ ``[key_added]``. copy Return a copy instead of writing to `adata`. @@ -95,9 +103,9 @@ def tsne( ------- Returns `None` if `copy=False`, else returns an `AnnData` object. Sets the following fields: - `adata.obsm['X_tsne']` : :class:`numpy.ndarray` (dtype `float`) + `adata.obsm['X_tsne' | key_added]` : :class:`numpy.ndarray` (dtype `float`) tSNE coordinates of data. - `adata.uns['tsne']` : :class:`dict` + `adata.uns['tsne' | key_added]` : :class:`dict` tSNE parameters. """ @@ -173,7 +181,7 @@ def tsne( metric=metric, use_rep=use_rep, ) - key_uns, key_obsm = ("tsne", "X_tsne") + key_uns, key_obsm = ("tsne", "X_tsne") if key_added is None else [key_added] * 2 adata.obsm[key_obsm] = X_tsne # annotate samples with tSNE coordinates adata.uns[key_uns] = dict(params={k: v for k, v in params.items() if v is not None}) diff --git a/src/scanpy/tools/_umap.py b/src/scanpy/tools/_umap.py index 061315ca65..c23b5551fa 100644 --- a/src/scanpy/tools/_umap.py +++ b/src/scanpy/tools/_umap.py @@ -53,6 +53,7 @@ def umap( a: float | None = None, b: float | None = None, method: Literal["umap", "rapids"] = "umap", + key_added: str | None = None, neighbors_key: str = "neighbors", copy: bool = False, ) -> AnnData | None: @@ -132,6 +133,13 @@ def umap( .. deprecated:: 1.10.0 Use :func:`rapids_singlecell.tl.umap` instead. + key_added + If not specified, the embedding is stored as + :attr:`~anndata.AnnData.obsm`\\ `['X_umap']` and the the parameters in + :attr:`~anndata.AnnData.uns`\\ `['umap']`. + If specified, the embedding is stored as + :attr:`~anndata.AnnData.obsm`\\ ``[key_added]`` and the the parameters in + :attr:`~anndata.AnnData.uns`\\ ``[key_added]``. neighbors_key Umap looks in :attr:`~anndata.AnnData.uns`\\ ``[neighbors_key]`` for neighbors settings and @@ -143,15 +151,15 @@ def umap( ------- Returns `None` if `copy=False`, else returns an `AnnData` object. Sets the following fields: - `adata.obsm['X_umap']` : :class:`numpy.ndarray` (dtype `float`) + `adata.obsm['X_umap' | key_added]` : :class:`numpy.ndarray` (dtype `float`) UMAP coordinates of data. - `adata.uns['umap']` : :class:`dict` + `adata.uns['umap' | key_added]` : :class:`dict` UMAP parameters. """ adata = adata.copy() if copy else adata - key_obsm, key_uns = ("X_umap", "umap") + key_obsm, key_uns = ("X_umap", "umap") if key_added is None else [key_added] * 2 if neighbors_key is None: # backwards compat neighbors_key = "neighbors" diff --git a/tests/test_embedding.py b/tests/test_embedding.py index 86fbd7e656..692157a084 100644 --- a/tests/test_embedding.py +++ b/tests/test_embedding.py @@ -9,36 +9,56 @@ from testing.scanpy._pytest.marks import needs -def test_tsne(): - pbmc = pbmc68k_reduced() +@pytest.mark.parametrize( + ("key_added", "key_obsm", "key_uns"), + [ + pytest.param(None, "X_tsne", "tsne", id="None"), + pytest.param("custom_key", "custom_key", "custom_key", id="custom_key"), + ], +) +def test_tsne(key_added: str | None, key_obsm: str, key_uns: str): + pbmc = pbmc68k_reduced()[:200].copy() euclidean1 = sc.tl.tsne(pbmc, metric="euclidean", copy=True) with pytest.warns(UserWarning, match="In previous versions of scanpy"): - euclidean2 = sc.tl.tsne(pbmc, metric="euclidean", n_jobs=2, copy=True) + euclidean2 = sc.tl.tsne( + pbmc, metric="euclidean", n_jobs=2, key_added=key_added, copy=True + ) cosine = sc.tl.tsne(pbmc, metric="cosine", copy=True) # Reproducibility - np.testing.assert_equal(euclidean1.obsm["X_tsne"], euclidean2.obsm["X_tsne"]) + np.testing.assert_equal(euclidean1.obsm["X_tsne"], euclidean2.obsm[key_obsm]) # Metric has some effect assert not np.array_equal(euclidean1.obsm["X_tsne"], cosine.obsm["X_tsne"]) # Params are recorded assert euclidean1.uns["tsne"]["params"]["n_jobs"] == 1 - assert euclidean2.uns["tsne"]["params"]["n_jobs"] == 2 + assert euclidean2.uns[key_uns]["params"]["n_jobs"] == 2 assert cosine.uns["tsne"]["params"]["n_jobs"] == 1 assert euclidean1.uns["tsne"]["params"]["metric"] == "euclidean" - assert euclidean2.uns["tsne"]["params"]["metric"] == "euclidean" + assert euclidean2.uns[key_uns]["params"]["metric"] == "euclidean" assert cosine.uns["tsne"]["params"]["metric"] == "cosine" -def test_umap_init_dtype(): - pbmc = pbmc68k_reduced()[:100, :].copy() - sc.tl.umap(pbmc, init_pos=pbmc.obsm["X_pca"][:, :2].astype(np.float32)) - embed1 = pbmc.obsm["X_umap"].copy() - sc.tl.umap(pbmc, init_pos=pbmc.obsm["X_pca"][:, :2].astype(np.float64)) - embed2 = pbmc.obsm["X_umap"].copy() - assert_array_almost_equal(embed1, embed2) - assert_array_almost_equal(embed1, embed2) +@pytest.mark.parametrize( + ("key_added", "key_obsm", "key_uns"), + [ + pytest.param(None, "X_umap", "umap", id="None"), + pytest.param("custom_key", "custom_key", "custom_key", id="custom_key"), + ], +) +def test_umap_init_dtype(key_added: str | None, key_obsm: str, key_uns: str): + pbmc1 = pbmc68k_reduced()[:100, :].copy() + pbmc2 = pbmc1.copy() + for pbmc, dtype, k in [(pbmc1, np.float32, None), (pbmc2, np.float64, key_added)]: + sc.tl.umap(pbmc, init_pos=pbmc.obsm["X_pca"][:, :2].astype(dtype), key_added=k) + + # check that embeddings are close for different dtypes + assert_array_almost_equal(pbmc1.obsm["X_umap"], pbmc2.obsm[key_obsm]) + + # check that params are recorded + assert pbmc1.uns["umap"]["params"]["a"] == pbmc2.uns[key_uns]["params"]["a"] + assert pbmc1.uns["umap"]["params"]["b"] == pbmc2.uns[key_uns]["params"]["b"] @pytest.mark.parametrize( diff --git a/tests/test_pca.py b/tests/test_pca.py index 4f614e6864..54c21a1391 100644 --- a/tests/test_pca.py +++ b/tests/test_pca.py @@ -250,27 +250,36 @@ def test_pca_shapes(): sc.pp.pca(adata, n_comps=100) -def test_pca_sparse(): +@pytest.mark.parametrize( + ("key_added", "keys_expected"), + [ + pytest.param(None, ("X_pca", "PCs", "pca"), id="None"), + pytest.param("custom_key", ("custom_key",) * 3, id="custom_key"), + ], +) +def test_pca_sparse(key_added: str | None, keys_expected: tuple[str, str, str]): """ Tests that implicitly centered pca on sparse arrays returns equivalent results to explicit centering on dense arrays. """ - pbmc = pbmc3k_normalized() + pbmc = pbmc3k_normalized()[:200].copy() pbmc_dense = pbmc.copy() pbmc_dense.X = pbmc_dense.X.toarray() implicit = sc.pp.pca(pbmc, dtype=np.float64, copy=True) - explicit = sc.pp.pca(pbmc_dense, dtype=np.float64, copy=True) + explicit = sc.pp.pca(pbmc_dense, dtype=np.float64, key_added=key_added, copy=True) + + key_obsm, key_varm, key_uns = keys_expected np.testing.assert_allclose( - implicit.uns["pca"]["variance"], explicit.uns["pca"]["variance"] + implicit.uns["pca"]["variance"], explicit.uns[key_uns]["variance"] ) np.testing.assert_allclose( - implicit.uns["pca"]["variance_ratio"], explicit.uns["pca"]["variance_ratio"] + implicit.uns["pca"]["variance_ratio"], explicit.uns[key_uns]["variance_ratio"] ) - np.testing.assert_allclose(implicit.obsm["X_pca"], explicit.obsm["X_pca"]) - np.testing.assert_allclose(implicit.varm["PCs"], explicit.varm["PCs"]) + np.testing.assert_allclose(implicit.obsm["X_pca"], explicit.obsm[key_obsm]) + np.testing.assert_allclose(implicit.varm["PCs"], explicit.varm[key_varm]) def test_pca_reproducible(array_type): From f7c9c9708635ef1d674d48cd24c208e2213b7404 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Mon, 5 Aug 2024 14:01:26 +0200 Subject: [PATCH 027/118] Fix [source] links (#3194) --- docs/conf.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 2980ac58b2..9a5626d6b0 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -3,7 +3,7 @@ import sys from datetime import datetime from functools import partial -from pathlib import Path +from pathlib import Path, PurePosixPath from typing import TYPE_CHECKING import matplotlib # noqa @@ -237,8 +237,9 @@ def setup(app: Sphinx): plot_html_show_source_link = False plot_working_directory = HERE.parent # Project root -# extlinks config +# link config extlinks = { "issue": ("https://github.com/scverse/scanpy/issues/%s", "issue%s"), "pr": ("https://github.com/scverse/scanpy/pull/%s", "pr%s"), } +rtd_links_prefix = PurePosixPath("src") From 7b133d482ad27c5250694d8c564816fb1e06a8a9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 09:51:56 +0200 Subject: [PATCH 028/118] [pre-commit.ci] pre-commit autoupdate (#3197) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1c44692b47..7dab13996e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.5.5 + rev: v0.5.6 hooks: - id: ruff types_or: [python, pyi, jupyter] From ffd3a60b3174030b72cc99d022f924912144162c Mon Sep 17 00:00:00 2001 From: Ilan Gold Date: Tue, 6 Aug 2024 13:59:33 -0400 Subject: [PATCH 029/118] (fix): resolve data ordering to match axis for stacked violin plots (#3196) * (fix): resolve axis ordering * (chore): release note * (chore): add test * (fix): make testing faster and more robust * (fix): light refactor * (fix): clean up comments * (chore): add more comments * (fix): remove test * Update src/scanpy/plotting/_stacked_violin.py * (chore): add test to cement behavior * (fix): tolerance that is sensitive enough for `main` difference --------- Co-authored-by: Philipp A. --- docs/release-notes/1.10.3.md | 1 + src/scanpy/plotting/_stacked_violin.py | 39 ++++++++++++++---- .../expected.png | Bin 0 -> 28537 bytes tests/test_plotting.py | 24 +++++++++++ 4 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 tests/_images/stacked_violin_swap_axes_pbmc68k_reduced/expected.png diff --git a/docs/release-notes/1.10.3.md b/docs/release-notes/1.10.3.md index 6ed21a12d7..b7bd113d3c 100644 --- a/docs/release-notes/1.10.3.md +++ b/docs/release-notes/1.10.3.md @@ -12,5 +12,6 @@ * Add compatibility with {mod}`numpy` 2.0 {pr}`3065` and {pr}`3115` {smaller}`P Angerer` * Fix `legend_loc` argument in {func}`scanpy.pl.embedding` not accepting matplotlib parameters {pr}`3163` {smaller}`P Angerer` * Fix dispersion cutoff in {func}`~scanpy.pp.highly_variable_genes` in presence of `NaN`s {pr}`3176` {smaller}`P Angerer` +* Fix axis labeling for swapped axes in {func}`~scanpy.pl.rank_genes_groups_stacked_violin` {pr}`3196` {smaller}`Ilan Gold` #### Performance diff --git a/src/scanpy/plotting/_stacked_violin.py b/src/scanpy/plotting/_stacked_violin.py index b78184004f..862bf76098 100644 --- a/src/scanpy/plotting/_stacked_violin.py +++ b/src/scanpy/plotting/_stacked_violin.py @@ -410,8 +410,27 @@ def _mainplot(self, ax: Axes): colormap_array = cmap(normalize(_color_df.values)) x_spacer_size = self.plot_x_padding y_spacer_size = self.plot_y_padding + + # All columns should have a unique name, yet, frequently + # gene names are repeated in self.var_names, otherwise the + # violin plot will not distinguish those genes + _matrix.columns = [f"{x}_{idx}" for idx, x in enumerate(_matrix.columns)] + + # Ensure the categories axis is always ordered identically. + # If the axes are not swapped, the above _matrix.columns is used in the actual violin plot (i.e., unique names). + # If they are swapped, then use the same as the labels used below. + # Without this, `_make_rows_of_violinplots` does not know about the order of the categories in labels. + labels = _color_df.columns + x_axis_order = labels if self.are_axes_swapped else _matrix.columns + self._make_rows_of_violinplots( - ax, _matrix, colormap_array, _color_df, x_spacer_size, y_spacer_size + ax, + _matrix, + colormap_array, + _color_df, + x_spacer_size, + y_spacer_size, + x_axis_order, ) # turn on axis for `ax` as this is turned off @@ -434,7 +453,6 @@ def _mainplot(self, ax: Axes): # 0.5 to position the ticks on the center of the violins x_ticks = np.arange(_color_df.shape[1]) + 0.5 ax.set_xticks(x_ticks) - labels = _color_df.columns ax.set_xticklabels(labels, minor=False, ha="center") # rotate x tick labels if they are longer than 2 characters if max([len(x) for x in labels]) > 2: @@ -445,7 +463,14 @@ def _mainplot(self, ax: Axes): return normalize def _make_rows_of_violinplots( - self, ax, _matrix, colormap_array, _color_df, x_spacer_size, y_spacer_size + self, + ax, + _matrix, + colormap_array, + _color_df, + x_spacer_size, + y_spacer_size, + x_axis_order, ): import seaborn as sns # Slow import, only import if called @@ -460,11 +485,6 @@ def _make_rows_of_violinplots( else: row_colors = [None] * _color_df.shape[0] - # All columns should have a unique name, yet, frequently - # gene names are repeated in self.var_names, otherwise the - # violin plot will not distinguish those genes - _matrix.columns = [f"{x}_{idx}" for idx, x in enumerate(_matrix.columns)] - # transform the dataframe into a dataframe having three columns: # the categories name (from groupby), # the gene name @@ -543,9 +563,10 @@ def _make_rows_of_violinplots( hue=None if palette_colors is None else x, palette=palette_colors, color=row_colors[idx], + order=x_axis_order, + hue_order=x_axis_order, **self.kwds, ) - if self.stripplot: row_ax = sns.stripplot( x=x, diff --git a/tests/_images/stacked_violin_swap_axes_pbmc68k_reduced/expected.png b/tests/_images/stacked_violin_swap_axes_pbmc68k_reduced/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..ab80e8e7136d2a9e10e5181a57fb5f228a421e60 GIT binary patch literal 28537 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 RO~l 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 literal 0 HcmV?d00001 diff --git a/tests/test_plotting.py b/tests/test_plotting.py index c8b5660e66..3b86a9e0d5 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -424,6 +424,30 @@ def test_stacked_violin_obj(image_comparer, plt): save_and_compare_images("stacked_violin_return_fig") +# checking for https://github.com/scverse/scanpy/issues/3152 +def test_stacked_violin_swap_axes_match(image_comparer): + save_and_compare_images = partial(image_comparer, ROOT, tol=10) + pbmc = pbmc68k_reduced() + sc.tl.rank_genes_groups( + pbmc, + "bulk_labels", + method="wilcoxon", + tie_correct=True, + pts=True, + key_added="wilcoxon", + ) + swapped_ax = sc.pl.rank_genes_groups_stacked_violin( + pbmc, + n_genes=2, + key="wilcoxon", + groupby="bulk_labels", + swap_axes=True, + return_fig=True, + ) + swapped_ax.show() + save_and_compare_images("stacked_violin_swap_axes_pbmc68k_reduced") + + def test_tracksplot(image_comparer): save_and_compare_images = partial(image_comparer, ROOT, tol=15) From 06d1bb3af14d0d6ef920ecafee71059c9eaada44 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2024 12:22:46 +0200 Subject: [PATCH 030/118] [pre-commit.ci] pre-commit autoupdate (#3207) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7dab13996e..63c9eafbae 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.5.6 + rev: v0.5.7 hooks: - id: ruff types_or: [python, pyi, jupyter] From ad496e9ecbf9728e2ec3e485c748e82058e59e0e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 22 Aug 2024 13:08:03 +0200 Subject: [PATCH 031/118] [pre-commit.ci] pre-commit autoupdate (#3210) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- .../scanpy/_pytest/fixtures/__init__.py | 2 +- src/testing/scanpy/_pytest/fixtures/data.py | 4 ++-- tests/conftest.py | 8 ++++---- tests/test_aggregated.py | 6 +++--- tests/test_binary.py | 2 +- tests/test_clustering.py | 2 +- tests/test_datasets.py | 18 +++++++++--------- tests/test_embedding_plots.py | 2 +- tests/test_get.py | 2 +- tests/test_highly_variable_genes.py | 2 +- tests/test_ingest.py | 2 +- tests/test_neighbors.py | 2 +- tests/test_neighbors_key_added.py | 2 +- tests/test_package_structure.py | 2 +- tests/test_paga.py | 2 +- tests/test_pca.py | 2 +- tests/test_plotting.py | 6 +++--- tests/test_preprocessing_distributed.py | 2 +- tests/test_qc_metrics.py | 2 +- tests/test_queries.py | 4 ++-- tests/test_scrublet.py | 2 +- 22 files changed, 39 insertions(+), 39 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 63c9eafbae..26fb8aebea 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.5.7 + rev: v0.6.1 hooks: - id: ruff types_or: [python, pyi, jupyter] diff --git a/src/testing/scanpy/_pytest/fixtures/__init__.py b/src/testing/scanpy/_pytest/fixtures/__init__.py index db0d525589..7578473786 100644 --- a/src/testing/scanpy/_pytest/fixtures/__init__.py +++ b/src/testing/scanpy/_pytest/fixtures/__init__.py @@ -37,7 +37,7 @@ def float_dtype(request): return request.param -@pytest.fixture() +@pytest.fixture def _doctest_env(cache: pytest.Cache, tmp_path: Path) -> Generator[None, None, None]: from scanpy._compat import chdir diff --git a/src/testing/scanpy/_pytest/fixtures/data.py b/src/testing/scanpy/_pytest/fixtures/data.py index 75ecd2a81e..d2be706076 100644 --- a/src/testing/scanpy/_pytest/fixtures/data.py +++ b/src/testing/scanpy/_pytest/fixtures/data.py @@ -50,12 +50,12 @@ def pbmc3ks_parametrized_session(request) -> dict[bool, AnnData]: } -@pytest.fixture() +@pytest.fixture def pbmc3k_parametrized(pbmc3ks_parametrized_session) -> Callable[[], AnnData]: return pbmc3ks_parametrized_session[False].copy -@pytest.fixture() +@pytest.fixture def pbmc3k_parametrized_small(pbmc3ks_parametrized_session) -> Callable[[], AnnData]: return pbmc3ks_parametrized_session[True].copy diff --git a/tests/conftest.py b/tests/conftest.py index 82a8e4166e..52bc61168a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -56,7 +56,7 @@ def _caplog_adapter(caplog: pytest.LogCaptureFixture) -> Generator[None, None, N sc.settings._root_logger.removeHandler(caplog.handler) -@pytest.fixture() +@pytest.fixture def imported_modules(): return IMPORTED @@ -69,7 +69,7 @@ class CompareResult(TypedDict): tol: int -@pytest.fixture() +@pytest.fixture def check_same_image(add_nunit_attachment): from urllib.parse import quote @@ -117,7 +117,7 @@ def fmt_descr(descr): return check_same_image -@pytest.fixture() +@pytest.fixture def image_comparer(check_same_image): from matplotlib import pyplot as plt @@ -139,7 +139,7 @@ def save_and_compare(*path_parts: Path | os.PathLike, tol: int): return save_and_compare -@pytest.fixture() +@pytest.fixture def plt(): from matplotlib import pyplot as plt diff --git a/tests/test_aggregated.py b/tests/test_aggregated.py index f16bc80a48..ce680b8df5 100644 --- a/tests/test_aggregated.py +++ b/tests/test_aggregated.py @@ -22,13 +22,13 @@ def metric(request: pytest.FixtureRequest) -> AggType: return request.param -@pytest.fixture() +@pytest.fixture def df_base(): ax_base = ["A", "B"] return pd.DataFrame(index=ax_base) -@pytest.fixture() +@pytest.fixture def df_groupby(): ax_groupby = [ *["v0", "v1", "v2"], @@ -49,7 +49,7 @@ def df_groupby(): return df_groupby -@pytest.fixture() +@pytest.fixture def X(): data = [ *[[0, -2], [1, 13], [2, 1]], # v diff --git a/tests/test_binary.py b/tests/test_binary.py index 4e1ce7e790..2cf1aa1bee 100644 --- a/tests/test_binary.py +++ b/tests/test_binary.py @@ -19,7 +19,7 @@ HERE = Path(__file__).parent -@pytest.fixture() +@pytest.fixture def _set_path(monkeypatch: MonkeyPatch) -> None: monkeypatch.setenv("PATH", str(HERE / "_scripts"), prepend=os.pathsep) diff --git a/tests/test_clustering.py b/tests/test_clustering.py index e87b586325..260513ff45 100644 --- a/tests/test_clustering.py +++ b/tests/test_clustering.py @@ -8,7 +8,7 @@ from testing.scanpy._pytest.marks import needs -@pytest.fixture() +@pytest.fixture def adata_neighbors(): return pbmc68k_reduced() diff --git a/tests/test_datasets.py b/tests/test_datasets.py index e46e68e435..4bad3800d7 100644 --- a/tests/test_datasets.py +++ b/tests/test_datasets.py @@ -33,7 +33,7 @@ def _tmp_dataset_dir(tmp_path: Path) -> None: sc.settings.datasetdir = tmp_path / "scanpy_data" -@pytest.mark.internet() +@pytest.mark.internet def test_burczynski06(): with pytest.warns(UserWarning, match=r"Variable names are not unique"): adata = sc.datasets.burczynski06() @@ -41,7 +41,7 @@ def test_burczynski06(): assert not (adata.X == 0).any() -@pytest.mark.internet() +@pytest.mark.internet @needs.openpyxl def test_moignard15(): with warnings.catch_warnings(): @@ -56,19 +56,19 @@ def test_moignard15(): assert adata.shape == (3934, 42) -@pytest.mark.internet() +@pytest.mark.internet def test_paul15(): sc.datasets.paul15() -@pytest.mark.internet() +@pytest.mark.internet def test_pbmc3k(): adata = sc.datasets.pbmc3k() assert adata.shape == (2700, 32738) assert "CD8A" in adata.var_names -@pytest.mark.internet() +@pytest.mark.internet def test_pbmc3k_processed(): with warnings.catch_warnings(record=True) as records: adata = sc.datasets.pbmc3k_processed() @@ -78,7 +78,7 @@ def test_pbmc3k_processed(): assert len(records) == 0 -@pytest.mark.internet() +@pytest.mark.internet def test_ebi_expression_atlas(): adata = sc.datasets.ebi_expression_atlas("E-MTAB-4888") # The shape changes sometimes @@ -111,7 +111,7 @@ def test_pbmc68k_reduced(): sc.datasets.pbmc68k_reduced() -@pytest.mark.internet() +@pytest.mark.internet def test_visium_datasets(): """Tests that reading/ downloading works and is does not have global effects.""" with pytest.warns(UserWarning, match=r"Variable names are not unique"): @@ -121,7 +121,7 @@ def test_visium_datasets(): assert_adata_equal(hheart, hheart_again) -@pytest.mark.internet() +@pytest.mark.internet def test_visium_datasets_dir_change(tmp_path: Path): """Test that changing the dataset dir doesn't break reading.""" with pytest.warns(UserWarning, match=r"Variable names are not unique"): @@ -132,7 +132,7 @@ def test_visium_datasets_dir_change(tmp_path: Path): assert_adata_equal(mbrain, mbrain_again) -@pytest.mark.internet() +@pytest.mark.internet def test_visium_datasets_images(): """Test that image download works and is does not have global effects.""" diff --git a/tests/test_embedding_plots.py b/tests/test_embedding_plots.py index 3c1bab6d51..d48f44b2b6 100644 --- a/tests/test_embedding_plots.py +++ b/tests/test_embedding_plots.py @@ -85,7 +85,7 @@ def adata(): return adata -@pytest.fixture() +@pytest.fixture def fixture_request(request): """Returns a Request object. diff --git a/tests/test_get.py b/tests/test_get.py index 4eff3ee23f..673b26787d 100644 --- a/tests/test_get.py +++ b/tests/test_get.py @@ -33,7 +33,7 @@ def transpose_adata(adata: AnnData, *, expect_duplicates: bool = False) -> AnnDa ) -@pytest.fixture() +@pytest.fixture def adata(): """ adata.X is np.ones((2, 2)) diff --git a/tests/test_highly_variable_genes.py b/tests/test_highly_variable_genes.py index 8b87074fe1..f3b9298505 100644 --- a/tests/test_highly_variable_genes.py +++ b/tests/test_highly_variable_genes.py @@ -36,7 +36,7 @@ def adata_sess() -> AnnData: return adata -@pytest.fixture() +@pytest.fixture def adata(adata_sess: AnnData) -> AnnData: return adata_sess.copy() diff --git a/tests/test_ingest.py b/tests/test_ingest.py index 31f38a40a7..2c57342de1 100644 --- a/tests/test_ingest.py +++ b/tests/test_ingest.py @@ -26,7 +26,7 @@ T = np.array([[2.0, 3.5, 4.0, 1.0, 4.7], [3.2, 2.0, 5.0, 5.0, 8.0]], dtype=np.float32) -@pytest.fixture() +@pytest.fixture def adatas(): pbmc = pbmc68k_reduced() n_split = 500 diff --git a/tests/test_neighbors.py b/tests/test_neighbors.py index 1cf74a8d8f..806594ff8d 100644 --- a/tests/test_neighbors.py +++ b/tests/test_neighbors.py @@ -119,7 +119,7 @@ def get_neighbors() -> Neighbors: return Neighbors(anndata_v0_8_constructor_compat(np.array(X))) -@pytest.fixture() +@pytest.fixture def neigh() -> Neighbors: return get_neighbors() diff --git a/tests/test_neighbors_key_added.py b/tests/test_neighbors_key_added.py index 4bc4a068f9..1da87f8ba9 100644 --- a/tests/test_neighbors_key_added.py +++ b/tests/test_neighbors_key_added.py @@ -11,7 +11,7 @@ key = "test" -@pytest.fixture() +@pytest.fixture def adata(): return sc.AnnData(pbmc68k_reduced().X) diff --git a/tests/test_package_structure.py b/tests/test_package_structure.py index 58df6515e9..19a6836e65 100644 --- a/tests/test_package_structure.py +++ b/tests/test_package_structure.py @@ -53,7 +53,7 @@ ] -@pytest.fixture() +@pytest.fixture def in_project_dir(): wd_orig = Path.cwd() os.chdir(proj_dir) diff --git a/tests/test_paga.py b/tests/test_paga.py index cbbb3095fc..d8de573fee 100644 --- a/tests/test_paga.py +++ b/tests/test_paga.py @@ -27,7 +27,7 @@ def pbmc_session(): return pbmc -@pytest.fixture() +@pytest.fixture def pbmc(pbmc_session): return pbmc_session.copy() diff --git a/tests/test_pca.py b/tests/test_pca.py index 54c21a1391..bebb752998 100644 --- a/tests/test_pca.py +++ b/tests/test_pca.py @@ -110,7 +110,7 @@ def zero_center(request: pytest.FixtureRequest): return request.param -@pytest.fixture() +@pytest.fixture def pca_params( array_type, svd_solver_type: Literal[None, "valid", "invalid"], zero_center ): diff --git a/tests/test_plotting.py b/tests/test_plotting.py index 3b86a9e0d5..b2d14b52a7 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -849,7 +849,7 @@ def gene_symbols_adatas_session() -> tuple[AnnData, AnnData]: return a, b -@pytest.fixture() +@pytest.fixture def gene_symbols_adatas(gene_symbols_adatas_session) -> tuple[AnnData, AnnData]: a, b = gene_symbols_adatas_session return a.copy(), b.copy() @@ -993,7 +993,7 @@ def pbmc_scatterplots_session() -> AnnData: return pbmc -@pytest.fixture() +@pytest.fixture def pbmc_scatterplots(pbmc_scatterplots_session) -> AnnData: return pbmc_scatterplots_session.copy() @@ -1352,7 +1352,7 @@ def test_scatter_no_basis_per_var(image_comparer): save_and_compare_images("scatter_AAAGCCTGGCTAAC-1_vs_AAATTCGATGCACA-1") -@pytest.fixture() +@pytest.fixture def pbmc_filtered() -> Callable[[], AnnData]: pbmc = pbmc68k_reduced() sc.pp.filter_genes(pbmc, min_cells=10) diff --git a/tests/test_preprocessing_distributed.py b/tests/test_preprocessing_distributed.py index f0451fb07b..a1b99121ef 100644 --- a/tests/test_preprocessing_distributed.py +++ b/tests/test_preprocessing_distributed.py @@ -31,7 +31,7 @@ pytestmark = [needs.zarr] -@pytest.fixture() +@pytest.fixture @filter_oldformatwarning def adata() -> AnnData: a = read_zarr(input_file) diff --git a/tests/test_qc_metrics.py b/tests/test_qc_metrics.py index 16449a5eed..83971fa2ce 100644 --- a/tests/test_qc_metrics.py +++ b/tests/test_qc_metrics.py @@ -15,7 +15,7 @@ ) -@pytest.fixture() +@pytest.fixture def anndata(): a = np.random.binomial(100, 0.005, (1000, 1000)) adata = AnnData( diff --git a/tests/test_queries.py b/tests/test_queries.py index 769b7aa2d1..d25df9d331 100644 --- a/tests/test_queries.py +++ b/tests/test_queries.py @@ -8,7 +8,7 @@ from testing.scanpy._pytest.marks import needs -@pytest.mark.internet() +@pytest.mark.internet @needs.gprofiler def test_enrich(): pbmc = pbmc68k_reduced() @@ -33,7 +33,7 @@ def test_enrich(): assert "set2" in enrich_list["query"].unique() -@pytest.mark.internet() +@pytest.mark.internet @needs.pybiomart def test_mito_genes(): pbmc = pbmc68k_reduced() diff --git a/tests/test_scrublet.py b/tests/test_scrublet.py index d8df27d710..dc08d24837 100644 --- a/tests/test_scrublet.py +++ b/tests/test_scrublet.py @@ -176,7 +176,7 @@ def scrub_small_sess() -> AnnData: return adata -@pytest.fixture() +@pytest.fixture def scrub_small(scrub_small_sess: AnnData): return scrub_small_sess.copy() From 87b6d1356e66dfe91803a47d6d7b9159eda45faa Mon Sep 17 00:00:00 2001 From: Ilan Gold Date: Fri, 30 Aug 2024 17:33:46 +0200 Subject: [PATCH 032/118] (fix): Upper bound `dask` (#3217) Co-authored-by: Philipp A. --- docs/release-notes/1.10.3.md | 1 + pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/1.10.3.md b/docs/release-notes/1.10.3.md index b7bd113d3c..5fcdc4400a 100644 --- a/docs/release-notes/1.10.3.md +++ b/docs/release-notes/1.10.3.md @@ -13,5 +13,6 @@ * Fix `legend_loc` argument in {func}`scanpy.pl.embedding` not accepting matplotlib parameters {pr}`3163` {smaller}`P Angerer` * Fix dispersion cutoff in {func}`~scanpy.pp.highly_variable_genes` in presence of `NaN`s {pr}`3176` {smaller}`P Angerer` * Fix axis labeling for swapped axes in {func}`~scanpy.pl.rank_genes_groups_stacked_violin` {pr}`3196` {smaller}`Ilan Gold` +* Upper bound dask on account of {issue}`scverse/anndata#1579` {pr}`3217` {smaller}`Ilan Gold` #### Performance diff --git a/pyproject.toml b/pyproject.toml index e9311a47b8..cde2ce89fb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -148,7 +148,7 @@ scanorama = ["scanorama"] # Scanorama dataset integration scrublet = ["scikit-image"] # Doublet detection with automatic thresholds # Acceleration rapids = ["cudf>=0.9", "cuml>=0.9", "cugraph>=0.9"] # GPU accelerated calculation of neighbors -dask = ["dask[array]>=2022.09.2"] # Use the Dask parallelization engine +dask = ["dask[array]>=2022.09.2,<2024.8.0"] # Use the Dask parallelization engine dask-ml = ["dask-ml", "scanpy[dask]"] # Dask-ML for sklearn-like API [tool.hatch.build.targets.wheel] From 38cc893bcb6cf8dfd5528a799a32455cba910c46 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Mon, 2 Sep 2024 09:30:39 +0200 Subject: [PATCH 033/118] Update notebooks (#3216) --- docs/extensions/canonical_tutorial.py | 24 ++++++++++++++++++++++++ docs/how-to/knn-transformers.ipynb | 2 +- docs/how-to/plotting-with-marsilea.ipynb | 2 +- notebooks | 2 +- 4 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 docs/extensions/canonical_tutorial.py diff --git a/docs/extensions/canonical_tutorial.py b/docs/extensions/canonical_tutorial.py new file mode 100644 index 0000000000..b459fbb059 --- /dev/null +++ b/docs/extensions/canonical_tutorial.py @@ -0,0 +1,24 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +from sphinx.util.docutils import SphinxDirective + +if TYPE_CHECKING: + from typing import ClassVar + + from docutils import nodes + from sphinx.application import Sphinx + + +class CanonicalTutorial(SphinxDirective): + """In the scanpy-tutorials repo, this links to the canonical location (here!).""" + + required_arguments: ClassVar = 1 + + def run(self) -> list[nodes.Node]: + return [] + + +def setup(app: Sphinx) -> None: + app.add_directive("canonical-tutorial", CanonicalTutorial) diff --git a/docs/how-to/knn-transformers.ipynb b/docs/how-to/knn-transformers.ipynb index 74ae4f265b..f97950c67e 120000 --- a/docs/how-to/knn-transformers.ipynb +++ b/docs/how-to/knn-transformers.ipynb @@ -1 +1 @@ -../../notebooks/knn-transformers.ipynb \ No newline at end of file +../../notebooks/how-to/knn-transformers.ipynb \ No newline at end of file diff --git a/docs/how-to/plotting-with-marsilea.ipynb b/docs/how-to/plotting-with-marsilea.ipynb index 45b62b725a..1deff1bb72 120000 --- a/docs/how-to/plotting-with-marsilea.ipynb +++ b/docs/how-to/plotting-with-marsilea.ipynb @@ -1 +1 @@ -../../notebooks/plotting-with-marsilea.ipynb \ No newline at end of file +../../notebooks/how-to/plotting-with-marsilea.ipynb \ No newline at end of file diff --git a/notebooks b/notebooks index 02c4946e0b..3385df77ce 160000 --- a/notebooks +++ b/notebooks @@ -1 +1 @@ -Subproject commit 02c4946e0be47e033355ef84b2a4909b302d2513 +Subproject commit 3385df77ce0f63987104bc644562a811c5d1b441 From 567b1e224a12ee0e0206cd99699623b09d59b8f1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 20:33:14 +0200 Subject: [PATCH 034/118] [pre-commit.ci] pre-commit autoupdate (#3213) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 26fb8aebea..5cf457c07d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.1 + rev: v0.6.3 hooks: - id: ruff types_or: [python, pyi, jupyter] From 2f6720bbf27aabfcd035b515f38955b36eb89b49 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 13 Sep 2024 10:17:52 +0200 Subject: [PATCH 035/118] [pre-commit.ci] pre-commit autoupdate (#3225) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5cf457c07d..ef3d2e951e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.3 + rev: v0.6.4 hooks: - id: ruff types_or: [python, pyi, jupyter] From ab16928a1005ff67bacd35226e25e8c7cd7ebc6e Mon Sep 17 00:00:00 2001 From: Amin Alam Date: Fri, 13 Sep 2024 11:57:05 +0200 Subject: [PATCH 036/118] fa2 library changed to fa2_modified (#3220) Co-authored-by: Philipp A. --- docs/release-notes/1.10.3.md | 4 + src/scanpy/plotting/_tools/paga.py | 65 ++++--------- src/scanpy/plotting/_tools/scatterplots.py | 4 +- src/scanpy/plotting/_utils.py | 60 +++++++----- src/scanpy/tools/_draw_graph.py | 103 ++++++++++++--------- 5 files changed, 122 insertions(+), 114 deletions(-) diff --git a/docs/release-notes/1.10.3.md b/docs/release-notes/1.10.3.md index 5fcdc4400a..6ba996730c 100644 --- a/docs/release-notes/1.10.3.md +++ b/docs/release-notes/1.10.3.md @@ -14,5 +14,9 @@ * Fix dispersion cutoff in {func}`~scanpy.pp.highly_variable_genes` in presence of `NaN`s {pr}`3176` {smaller}`P Angerer` * Fix axis labeling for swapped axes in {func}`~scanpy.pl.rank_genes_groups_stacked_violin` {pr}`3196` {smaller}`Ilan Gold` * Upper bound dask on account of {issue}`scverse/anndata#1579` {pr}`3217` {smaller}`Ilan Gold` +* The [fa2-modified][] package replaces [forceatlas2][] for the latter’s lack of maintenance. {pr}`3220` {smaller}`A Alam` + +[fa2-modified]: https://github.com/AminAlam/fa2_modified +[forceatlas2]: https://github.com/bhargavchippada/forceatlas2 #### Performance diff --git a/src/scanpy/plotting/_tools/paga.py b/src/scanpy/plotting/_tools/paga.py index 49fe1c9d2c..6ea2560b10 100644 --- a/src/scanpy/plotting/_tools/paga.py +++ b/src/scanpy/plotting/_tools/paga.py @@ -16,6 +16,8 @@ from scipy.sparse import issparse from sklearn.utils import check_random_state +from scanpy.tools._draw_graph import coerce_fa2_layout, fa2_positions + from ... import _utils as _sc_utils from ... import logging as logg from ..._compat import old_positionals @@ -25,13 +27,17 @@ if TYPE_CHECKING: from collections.abc import Mapping, Sequence - from typing import Any, Literal + from typing import Any, Literal, Union from anndata import AnnData from matplotlib.axes import Axes from matplotlib.colors import Colormap + from scipy.sparse import spmatrix + + from ...tools._draw_graph import _Layout as _LayoutWithoutEqTree + from .._utils import _FontSize, _FontWeight, _LegendLoc - from .._utils import _FontSize, _FontWeight, _IGraphLayout, _LegendLoc + _Layout = Union[_LayoutWithoutEqTree, Literal["eq_tree"]] @old_positionals( @@ -202,13 +208,13 @@ def paga_compare( def _compute_pos( - adjacency_solid, + adjacency_solid: spmatrix | np.ndarray, *, - layout=None, - random_state=0, - init_pos=None, + layout: _Layout | None = None, + random_state: _sc_utils.AnyRandom = 0, + init_pos: np.ndarray | None = None, adj_tree=None, - root=0, + root: int = 0, layout_kwds: Mapping[str, Any] = MappingProxyType({}), ): import random @@ -220,50 +226,15 @@ def _compute_pos( nx_g_solid = nx.Graph(adjacency_solid) if layout is None: layout = "fr" - if layout == "fa": - try: - from fa2 import ForceAtlas2 - except ImportError: - logg.warning( - "Package 'fa2' is not installed, falling back to layout 'fr'." - "To use the faster and better ForceAtlas2 layout, " - "install package 'fa2' (`pip install fa2`)." - ) - layout = "fr" + layout = coerce_fa2_layout(layout) if layout == "fa": # np.random.seed(random_state) if init_pos is None: init_coords = random_state.random_sample((adjacency_solid.shape[0], 2)) else: init_coords = init_pos.copy() - forceatlas2 = ForceAtlas2( - # Behavior alternatives - outboundAttractionDistribution=False, # Dissuade hubs - linLogMode=False, # NOT IMPLEMENTED - adjustSizes=False, # Prevent overlap (NOT IMPLEMENTED) - edgeWeightInfluence=1.0, - # Performance - jitterTolerance=1.0, # Tolerance - barnesHutOptimize=True, - barnesHutTheta=1.2, - multiThreaded=False, # NOT IMPLEMENTED - # Tuning - scalingRatio=2.0, - strongGravityMode=False, - gravity=1.0, - # Log - verbose=False, - ) - if "maxiter" in layout_kwds: - iterations = layout_kwds["maxiter"] - elif "iterations" in layout_kwds: - iterations = layout_kwds["iterations"] - else: - iterations = 500 - pos_list = forceatlas2.forceatlas2( - adjacency_solid, pos=init_coords, iterations=iterations - ) - pos = {n: [p[0], -p[1]] for n, p in enumerate(pos_list)} + pos_list = fa2_positions(adjacency_solid, init_coords, **layout_kwds) + pos = {n: (x, -y) for n, (x, y) in enumerate(pos_list)} elif layout == "eq_tree": nx_g_tree = nx.Graph(adj_tree) pos = _utils.hierarchy_pos(nx_g_tree, root) @@ -302,7 +273,7 @@ def _compute_pos( ).coords except AttributeError: # hack for empty graphs... pos_list = g.layout(layout, seed=init_coords, **layout_kwds).coords - pos = {n: [p[0], -p[1]] for n, p in enumerate(pos_list)} + pos = {n: (x, -y) for n, (x, y) in enumerate(pos_list)} if len(pos) == 1: pos[0] = (0.5, 0.5) pos_array = np.array([pos[n] for count, n in enumerate(nx_g_solid)]) @@ -333,7 +304,7 @@ def paga( *, threshold: float | None = None, color: str | Mapping[str | int, Mapping[Any, float]] | None = None, - layout: _IGraphLayout | None = None, + layout: _Layout | None = None, layout_kwds: Mapping[str, Any] = MappingProxyType({}), init_pos: np.ndarray | None = None, root: int | str | Sequence[int] | None = 0, diff --git a/src/scanpy/plotting/_tools/scatterplots.py b/src/scanpy/plotting/_tools/scatterplots.py index ca44014459..4f2b208ef1 100644 --- a/src/scanpy/plotting/_tools/scatterplots.py +++ b/src/scanpy/plotting/_tools/scatterplots.py @@ -38,6 +38,7 @@ sanitize_anndata, ) from ...get import _check_mask +from ...tools._draw_graph import _Layout # noqa: TCH001 from .. import _utils from .._docs import ( doc_adata_color_etc, @@ -51,7 +52,6 @@ VBound, # noqa: TCH001 _FontSize, # noqa: TCH001 _FontWeight, # noqa: TCH001 - _IGraphLayout, # noqa: TCH001 _LegendLoc, # noqa: TCH001 check_colornorm, check_projection, @@ -779,7 +779,7 @@ def diffmap(adata: AnnData, **kwargs) -> Figure | Axes | list[Axes] | None: show_save_ax=doc_show_save_ax, ) def draw_graph( - adata: AnnData, *, layout: _IGraphLayout | None = None, **kwargs + adata: AnnData, *, layout: _Layout | None = None, **kwargs ) -> Figure | Axes | list[Axes] | None: """\ Scatter plot in graph-drawing basis. diff --git a/src/scanpy/plotting/_utils.py b/src/scanpy/plotting/_utils.py index c26cc121b1..44e85c5c68 100644 --- a/src/scanpy/plotting/_utils.py +++ b/src/scanpy/plotting/_utils.py @@ -3,7 +3,7 @@ import collections.abc as cabc import warnings from collections.abc import Sequence -from typing import TYPE_CHECKING, Callable, Literal, Union +from typing import TYPE_CHECKING, Callable, Literal, TypedDict, Union import matplotlib as mpl import numpy as np @@ -23,7 +23,7 @@ from . import palettes if TYPE_CHECKING: - from collections.abc import Collection + from collections.abc import Collection, Mapping from anndata import AnnData from matplotlib.colors import Colormap @@ -36,7 +36,6 @@ DensityNorm = Literal["area", "count", "width"] # These are needed by _wraps_plot_scatter -_IGraphLayout = Literal["fa", "fr", "rt", "rt_circular", "drl", "eq_tree"] VBound = Union[str, float, Callable[[Sequence[float]], float]] _FontWeight = Literal["light", "normal", "medium", "semibold", "bold", "heavy", "black"] _FontSize = Literal[ @@ -970,7 +969,14 @@ def scale_to_zero_one(x): return xscaled -def hierarchy_pos(G, root, levels=None, width=1.0, height=1.0): +class _Level(TypedDict): + total: int + current: int + + +def hierarchy_pos( + G, root: int, levels_: Mapping[int, int] | None = None, width=1.0, height=1.0 +) -> dict[int, tuple[float, float]]: """Tree layout for networkx graph. See https://stackoverflow.com/questions/29586520/can-one-get-hierarchical-graphs-from-networkx-with-python-3 @@ -989,37 +995,47 @@ def hierarchy_pos(G, root, levels=None, width=1.0, height=1.0): width: horizontal space allocated for drawing height: vertical space allocated for drawing """ - TOTAL = "total" - CURRENT = "current" - def make_levels(levels, node=root, currentLevel=0, parent=None): + def make_levels( + levels: dict[int, _Level], + node: int = root, + current_level: int = 0, + parent: int | None = None, + ) -> dict[int, _Level]: """Compute the number of nodes for each level""" - if currentLevel not in levels: - levels[currentLevel] = {TOTAL: 0, CURRENT: 0} - levels[currentLevel][TOTAL] += 1 - neighbors = list(G.neighbors(node)) + if current_level not in levels: + levels[current_level] = _Level(total=0, current=0) + levels[current_level]["total"] += 1 + neighbors: list[int] = list(G.neighbors(node)) if parent is not None: neighbors.remove(parent) for neighbor in neighbors: - levels = make_levels(levels, neighbor, currentLevel + 1, node) + levels = make_levels(levels, neighbor, current_level + 1, node) return levels - def make_pos(pos, node=root, currentLevel=0, parent=None, vert_loc=0): - dx = 1 / levels[currentLevel][TOTAL] + if levels_ is None: + levels = make_levels({}) + else: + levels = {k: _Level(total=0, current=0) for k, v in levels_.items()} + + def make_pos( + pos: dict[int, tuple[float, float]], + node: int = root, + current_level: int = 0, + parent: int | None = None, + vert_loc: float = 0.0, + ): + dx = 1 / levels[current_level]["total"] left = dx / 2 - pos[node] = ((left + dx * levels[currentLevel][CURRENT]) * width, vert_loc) - levels[currentLevel][CURRENT] += 1 - neighbors = list(G.neighbors(node)) + pos[node] = ((left + dx * levels[current_level]["current"]) * width, vert_loc) + levels[current_level]["current"] += 1 + neighbors: list[int] = list(G.neighbors(node)) if parent is not None: neighbors.remove(parent) for neighbor in neighbors: - pos = make_pos(pos, neighbor, currentLevel + 1, node, vert_loc - vert_gap) + pos = make_pos(pos, neighbor, current_level + 1, node, vert_loc - vert_gap) return pos - if levels is None: - levels = make_levels({}) - else: - levels = {k: {TOTAL: v, CURRENT: 0} for k, v in levels.items()} vert_gap = height / (max(levels.keys()) + 1) return make_pos({}) diff --git a/src/scanpy/tools/_draw_graph.py b/src/scanpy/tools/_draw_graph.py index 9d922fe49e..b36638b5b5 100644 --- a/src/scanpy/tools/_draw_graph.py +++ b/src/scanpy/tools/_draw_graph.py @@ -1,6 +1,7 @@ from __future__ import annotations import random +from importlib.util import find_spec from typing import TYPE_CHECKING, Literal, get_args import numpy as np @@ -12,11 +13,16 @@ from ._utils import get_init_pos_from_paga if TYPE_CHECKING: + from typing import LiteralString, TypeVar + from anndata import AnnData from scipy.sparse import spmatrix from .._utils import AnyRandom + S = TypeVar("S", bound=LiteralString) + + _Layout = Literal["fr", "drl", "kk", "grid_fr", "lgl", "rt", "rt_circular", "fa"] _LAYOUTS = get_args(_Layout) @@ -53,8 +59,8 @@ def draw_graph( An alternative to tSNE that often preserves the topology of the data better. This requires to run :func:`~scanpy.pp.neighbors`, first. - The default layout ('fa', `ForceAtlas2`, :cite:t:`Jacomy2014`) uses the package |fa2|_ - :cite:p:`Chippada2018`, which can be installed via `pip install fa2`. + The default layout ('fa', `ForceAtlas2`, :cite:t:`Jacomy2014`) uses the package |fa2-modified|_ + :cite:p:`Chippada2018`, which can be installed via `pip install fa2-modified`. `Force-directed graph drawing`_ describes a class of long-established algorithms for visualizing graphs. @@ -62,8 +68,8 @@ def draw_graph( Many other layouts as implemented in igraph :cite:p:`Csardi2006` are available. Similar approaches have been used by :cite:t:`Zunder2015` or :cite:t:`Weinreb2017`. - .. |fa2| replace:: `fa2` - .. _fa2: https://github.com/bhargavchippada/forceatlas2 + .. |fa2-modified| replace:: `fa2-modified` + .. _fa2-modified: https://github.com/AminAlam/fa2_modified .. _Force-directed graph drawing: https://en.wikipedia.org/wiki/Force-directed_graph_drawing Parameters @@ -137,47 +143,10 @@ def draw_graph( else: np.random.seed(random_state) init_coords = np.random.random((adjacency.shape[0], 2)) - # see whether fa2 is installed - if layout == "fa": - try: - from fa2 import ForceAtlas2 - except ImportError: - logg.warning( - "Package 'fa2' is not installed, falling back to layout 'fr'." - "To use the faster and better ForceAtlas2 layout, " - "install package 'fa2' (`pip install fa2`)." - ) - layout = "fr" + layout = coerce_fa2_layout(layout) # actual drawing if layout == "fa": - forceatlas2 = ForceAtlas2( - # Behavior alternatives - outboundAttractionDistribution=False, # Dissuade hubs - linLogMode=False, # NOT IMPLEMENTED - adjustSizes=False, # Prevent overlap (NOT IMPLEMENTED) - edgeWeightInfluence=1.0, - # Performance - jitterTolerance=1.0, # Tolerance - barnesHutOptimize=True, - barnesHutTheta=1.2, - multiThreaded=False, # NOT IMPLEMENTED - # Tuning - scalingRatio=2.0, - strongGravityMode=False, - gravity=1.0, - # Log - verbose=False, - ) - if "maxiter" in kwds: - iterations = kwds["maxiter"] - elif "iterations" in kwds: - iterations = kwds["iterations"] - else: - iterations = 500 - positions = forceatlas2.forceatlas2( - adjacency, pos=init_coords, iterations=iterations - ) - positions = np.array(positions) + positions = np.array(fa2_positions(adjacency, init_coords, **kwds)) else: # igraph doesn't use numpy seed random.seed(random_state) @@ -202,3 +171,51 @@ def draw_graph( deep=f"added\n {key_added!r}, graph_drawing coordinates (adata.obsm)", ) return adata if copy else None + + +def fa2_positions( + adjacency: spmatrix | np.ndarray, init_coords: np.ndarray, **kwds +) -> list[tuple[float, float]]: + from fa2_modified import ForceAtlas2 + + forceatlas2 = ForceAtlas2( + # Behavior alternatives + outboundAttractionDistribution=False, # Dissuade hubs + linLogMode=False, # NOT IMPLEMENTED + adjustSizes=False, # Prevent overlap (NOT IMPLEMENTED) + edgeWeightInfluence=1.0, + # Performance + jitterTolerance=1.0, # Tolerance + barnesHutOptimize=True, + barnesHutTheta=1.2, + multiThreaded=False, # NOT IMPLEMENTED + # Tuning + scalingRatio=2.0, + strongGravityMode=False, + gravity=1.0, + # Log + verbose=False, + ) + if "maxiter" in kwds: + iterations = kwds["maxiter"] + elif "iterations" in kwds: + iterations = kwds["iterations"] + else: + iterations = 500 + return forceatlas2.forceatlas2(adjacency, pos=init_coords, iterations=iterations) + + +def coerce_fa2_layout(layout: S) -> S | Literal["fa", "fr"]: + # see whether fa2 is installed + if layout != "fa": + return layout + + if find_spec("fa2_modified") is None: + logg.warning( + "Package 'fa2-modified' is not installed, falling back to layout 'fr'." + "To use the faster and better ForceAtlas2 layout, " + "install package 'fa2-modified' (`pip install fa2-modified`)." + ) + return "fr" + + return "fa" From 0d65925258013e4b74287415ba9e3d39c9c78513 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 11:55:53 +0200 Subject: [PATCH 037/118] [pre-commit.ci] pre-commit autoupdate (#3232) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ef3d2e951e..6ce8309e63 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.4 + rev: v0.6.5 hooks: - id: ruff types_or: [python, pyi, jupyter] From c62e4cb1ceb6fd1ece043ecf0ff25cdcdeae4d93 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Tue, 17 Sep 2024 13:35:41 +0200 Subject: [PATCH 038/118] Switch to towncrier (#3231) Co-authored-by: Ilan Gold --- .gitignore | 1 - .readthedocs.yml | 9 +- ci/scripts/min-deps.py | 2 +- ci/scripts/towncrier_automation.py | 109 ++++++++++++++++++ docs/conf.py | 1 + docs/dev/code.md | 17 ++- docs/dev/documentation.md | 46 ++++---- docs/dev/getting-set-up.md | 67 ++++++----- docs/dev/release.md | 41 +++---- docs/dev/testing.md | 35 ++++-- docs/dev/versioning.md | 21 ++-- docs/installation.md | 151 ++++++++++++------------ docs/release-notes/1.10.0.md | 4 +- docs/release-notes/1.10.1.md | 2 +- docs/release-notes/1.10.2.md | 4 +- docs/release-notes/1.10.3.md | 22 ---- docs/release-notes/1.11.0.md | 14 --- docs/release-notes/1.8.0.md | 2 +- docs/release-notes/1.8.2.md | 2 +- docs/release-notes/2875.bugfix.md | 1 + docs/release-notes/2921.feature.md | 1 + docs/release-notes/3042.bugfix.md | 1 + docs/release-notes/3115.bugfix.md | 1 + docs/release-notes/3155.feature.md | 1 + docs/release-notes/3163.bugfix.md | 1 + docs/release-notes/3176.bugfix.md | 1 + docs/release-notes/3184.feature.md | 1 + docs/release-notes/3196.bugfix.md | 1 + docs/release-notes/3217.bugfix.md | 1 + docs/release-notes/3220.bugfix.md | 4 + docs/release-notes/index.md | 178 +---------------------------- hatch.toml | 33 ++++++ pyproject.toml | 20 +++- 33 files changed, 393 insertions(+), 402 deletions(-) create mode 100755 ci/scripts/towncrier_automation.py delete mode 100644 docs/release-notes/1.10.3.md delete mode 100644 docs/release-notes/1.11.0.md create mode 100644 docs/release-notes/2875.bugfix.md create mode 100644 docs/release-notes/2921.feature.md create mode 100644 docs/release-notes/3042.bugfix.md create mode 100644 docs/release-notes/3115.bugfix.md create mode 100644 docs/release-notes/3155.feature.md create mode 100644 docs/release-notes/3163.bugfix.md create mode 100644 docs/release-notes/3176.bugfix.md create mode 100644 docs/release-notes/3184.feature.md create mode 100644 docs/release-notes/3196.bugfix.md create mode 100644 docs/release-notes/3217.bugfix.md create mode 100644 docs/release-notes/3220.bugfix.md create mode 100644 hatch.toml diff --git a/.gitignore b/.gitignore index 7aca652727..beafaf6171 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,6 @@ /tests/**/*failed-diff.png # Environment management -/hatch.toml /Pipfile /Pipfile.lock /requirements*.lock diff --git a/.readthedocs.yml b/.readthedocs.yml index 4a5d3e219f..4ffa520491 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -2,9 +2,16 @@ version: 2 submodules: include: all build: - os: ubuntu-20.04 + os: ubuntu-24.04 tools: python: '3.12' + jobs: + post_checkout: + # unshallow so version can be derived from tag + - git fetch --unshallow || true + pre_build: + # run towncrier to preview the next version’s release notes + - ( find docs/release-notes -regex '[^.]+[.][^.]+.md' | grep -q . ) && towncrier build --keep || true sphinx: fail_on_warning: true # do not change or you will be fired configuration: docs/conf.py diff --git a/ci/scripts/min-deps.py b/ci/scripts/min-deps.py index b3f393ea57..f1381580b4 100755 --- a/ci/scripts/min-deps.py +++ b/ci/scripts/min-deps.py @@ -1,4 +1,4 @@ -#!python3 +#!/usr/bin/env python3 from __future__ import annotations import argparse diff --git a/ci/scripts/towncrier_automation.py b/ci/scripts/towncrier_automation.py new file mode 100755 index 0000000000..7dcb3cb7bf --- /dev/null +++ b/ci/scripts/towncrier_automation.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 +from __future__ import annotations + +import argparse +import subprocess +from typing import TYPE_CHECKING + +from packaging.version import Version + +if TYPE_CHECKING: + from collections.abc import Sequence + + +class Args(argparse.Namespace): + version: str + dry_run: bool + + +def parse_args(argv: Sequence[str] | None = None) -> Args: + parser = argparse.ArgumentParser( + prog="towncrier-automation", + description=( + "This script runs towncrier for a given version, " + "creates a branch off of the current one, " + "and then creates a PR into the original branch with the changes. " + "The PR will be backported to main if the current branch is not main." + ), + ) + parser.add_argument( + "version", + type=str, + help=( + "The new version for the release must have at least three parts, like `major.minor.patch` and no `major.minor`. " + "It can have a suffix like `major.minor.patch.dev0` or `major.minor.0rc1`." + ), + ) + parser.add_argument( + "--dry-run", + help="Whether or not to dry-run the actual creation of the pull request", + action="store_true", + ) + args = parser.parse_args(argv, Args()) + # validate the version + if len(Version(args.version).release) != 3: + msg = f"Version argument {args.version} must contain major, minor, and patch version." + raise ValueError(msg) + return args + + +def main(argv: Sequence[str] | None = None) -> None: + args = parse_args(argv) + + # Run towncrier + subprocess.run( + ["towncrier", "build", f"--version={args.version}", "--yes"], check=True + ) + + # Check if we are on the main branch to know if we need to backport + base_branch = subprocess.run( + ["git", "rev-parse", "--abbrev-ref", "HEAD"], + capture_output=True, + text=True, + check=True, + ).stdout.strip() + pr_description = ( + "" if base_branch == "main" else "@meeseeksmachine backport to main" + ) + branch_name = f"release_notes_{args.version}" + + # Create a new branch + commit + subprocess.run(["git", "switch", "-c", branch_name], check=True) + subprocess.run(["git", "add", "docs/release-notes"], check=True) + pr_title = f"(chore): generate {args.version} release notes" + subprocess.run(["git", "commit", "-m", pr_title], check=True) + + # push + if not args.dry_run: + subprocess.run( + ["git", "push", "--set-upstream=origin", branch_name], check=True + ) + else: + print("Dry run, not pushing") + + # Create a PR + subprocess.run( + [ + "gh", + "pr", + "create", + f"--base={base_branch}", + f"--title={pr_title}", + f"--body={pr_description}", + *(["--label=no milestone"] if base_branch == "main" else []), + *(["--dry-run"] if args.dry_run else []), + ], + check=True, + ) + + # Enable auto-merge + if not args.dry_run: + subprocess.run( + ["gh", "pr", "merge", branch_name, "--auto", "--squash"], check=True + ) + else: + print("Dry run, not merging") + + +if __name__ == "__main__": + main() diff --git a/docs/conf.py b/docs/conf.py index 9a5626d6b0..2c79aa8d82 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -79,6 +79,7 @@ "scanpydoc", # needs to be before sphinx.ext.linkcode "sphinx.ext.linkcode", "sphinx_design", + "sphinx_tabs.tabs", "sphinx_search.extension", "sphinxext.opengraph", *[p.stem for p in (HERE / "extensions").glob("*.py") if p.stem not in {"git_ref"}], diff --git a/docs/dev/code.md b/docs/dev/code.md index 06c267951b..1e9d295725 100644 --- a/docs/dev/code.md +++ b/docs/dev/code.md @@ -12,13 +12,12 @@ ## Code style -New code should follow -[Black](https://black.readthedocs.io/en/stable/the_black_code_style.html) -and -[flake8](https://flake8.pycqa.org). -We ignore a couple of flake8 checks which are documented in the .flake8 file in the root of this repository. -To learn how to ignore checks per line please read -[flake8 violations](https://flake8.pycqa.org/en/latest/user/violations.html). -Additionally, we use Scanpy’s -[EditorConfig](https://github.com/scverse/scanpy/blob/main/.editorconfig), +Code contributions will be formatted and style checked using [Ruff][]. +Ignored checks are configured in the `tool.ruff.lint` section of {file}`pyproject.toml`. +To learn how to ignore checks per line please read about [ignoring errors][]. +Additionally, we use Scanpy’s [EditorConfig][], so using an editor/IDE with support for both is helpful. + +[Ruff]: https://docs.astral.sh/ruff/ +[ignoring errors]: https://docs.astral.sh/ruff/tutorial/#ignoring-errors +[EditorConfig]: https://github.com/scverse/scanpy/blob/main/.editorconfig diff --git a/docs/dev/documentation.md b/docs/dev/documentation.md index 159b533ee3..d9c3f6e034 100644 --- a/docs/dev/documentation.md +++ b/docs/dev/documentation.md @@ -4,38 +4,37 @@ ## Building the docs -Dependencies for building the documentation for scanpy can be installed with `pip install -e "scanpy[doc]"` - -To build the docs, enter the `docs` directory and run `make html`. After this process completes you can take a look at the docs by opening `scanpy/docs/_build/html/index.html`. +To build the docs, run `hatch run docs:build`. +Afterwards, you can run `hatch run docs:open` to open {file}`docs/_build/html/index.html`. Your browser and Sphinx cache docs which have been built previously. Sometimes these caches are not invalidated when you've updated the docs. If docs are not updating the way you expect, first try "force reloading" your browser page – e.g. reload the page without using the cache. -Next, if problems persist, clear the sphinx cache and try building them again (`make clean` from `docs` directory). - -```{note} -If you've cloned the repository pre 1.8.0, you may need to be more thorough in cleaning. -If you run into warnings try removing all untracked files in the docs directory. -``` +Next, if problems persist, clear the sphinx cache (`hatch run docs:clean`) and try building them again. ## Adding to the docs -For any user-visible changes, please make sure a note has been added to the release notes for the relevant version so we can credit you! -These files are found in the `docs/release-notes/` directory. +For any user-visible changes, please make sure a note has been added to the release notes using [`hatch run towncrier:create`][towncrier create]. We recommend waiting on this until your PR is close to done since this can often causes merge conflicts. Once you've added a new function to the documentation, you'll need to make sure there is a link somewhere in the documentation site pointing to it. This should be added to `docs/api.md` under a relevant heading. -For tutorials and more in depth examples, consider adding a notebook to [scanpy-tutorials](https://github.com/scverse/scanpy-tutorials/). +For tutorials and more in depth examples, consider adding a notebook to the [scanpy-tutorials][] repository. -The tutorials are tied to this repository via a submodule. To update the submodule, run `git submodule update --remote` from the root of the repository. Subsequently, commit and push the changes in a PR. This should be done before each release to ensure the tutorials are up to date. +The tutorials are tied to this repository via a submodule. +To update the submodule, run `git submodule update --remote` from the root of the repository. +Subsequently, commit and push the changes in a PR. +This should be done before each release to ensure the tutorials are up to date. + +[towncrier create]: https://towncrier.readthedocs.io/en/stable/tutorial.html#creating-news-fragments +[scanpy-tutorials]: https://github.com/scverse/scanpy-tutorials/ ## docstrings format We use the numpydoc style for writing docstrings. -We'd primarily suggest looking at existing docstrings for examples, but the [napolean guide to numpy style docstrings](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_numpy.html#example-numpy) is also a great source. -If you're unfamiliar with the reStructuredText (`rst`) markup format, [Sphinx has a useful primer](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html). +We'd primarily suggest looking at existing docstrings for examples, but the [napolean guide to numpy style docstrings][] is also a great source. +If you're unfamiliar with the reStructuredText (rST) markup format, check out the [Sphinx rST primer][]. Some key points: @@ -46,11 +45,14 @@ Some key points: Look at [sc.tl.louvain](https://github.com/scverse/scanpy/blob/a811fee0ef44fcaecbde0cad6336336bce649484/scanpy/tools/_louvain.py#L22-L90) as an example for everything mentioned here. +[napolean guide to numpy style docstrings]: https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_numpy.html#example-numpy +[sphinx rst primer]: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html + ### Plots in docstrings One of the most useful things you can include in a docstring is examples of how the function should be used. These are a great way to demonstrate intended usage and give users a template they can copy and modify. -We're able to include the plots produced by these snippets in the rendered docs using [matplotlib's plot directive](https://matplotlib.org/devel/plot_directive.html). +We're able to include the plots produced by these snippets in the rendered docs using [matplotlib's plot directive][]. For examples of this, see the `Examples` sections of {func}`~scanpy.pl.dotplot` or {func}`~scanpy.pp.calculate_qc_metrics`. Note that anything in these sections will need to be run when the docs are built, so please keep them computationally light. @@ -58,6 +60,8 @@ Note that anything in these sections will need to be run when the docs are built - If you need computed features (e.g. an embedding, differential expression results) load data that has this precomputed. - Try to re-use datasets, this reduces the amount of data that needs to be downloaded to the CI server. +[matplotlib's plot directive]: https://matplotlib.org/devel/plot_directive.html + ### `Params` section The `Params` abbreviation is a legit replacement for `Parameters`. @@ -65,7 +69,10 @@ The `Params` abbreviation is a legit replacement for `Parameters`. To document parameter types use type annotations on function parameters. These will automatically populate the docstrings on import, and when the documentation is built. -Use the python standard library types (defined in [collections.abc](https://docs.python.org/3/library/collections.abc.html) and [typing](https://docs.python.org/3/library/typing.html) modules) for containers, e.g. `Sequence`s (like `list`), `Iterable`s (like `set`), and `Mapping`s (like `dict`). +Use the python standard library types (defined in {mod}`collections.abc` and {mod}`typing` modules) for containers, e.g. +{class}`~collections.abc.Sequence`s (like `list`), +{class}`~collections.abc.Iterable`s (like `set`), and +{class}`~collections.abc.Mapping`s (like `dict`). Always specify what these contain, e.g. `{'a': (1, 2)}` → `Mapping[str, Tuple[int, int]]`. If you can’t use one of those, use a concrete class like `AnnData`. If your parameter only accepts an enumeration of strings, specify them like so: `Literal['elem-1', 'elem-2']`. @@ -80,8 +87,7 @@ There are three types of return sections – prose, tuple, and a mix of both. #### Examples -For simple cases, use prose as in -{func}`~scanpy.pp.normalize_total` +For simple cases, use prose as in {func}`~scanpy.pp.normalize_total`: ```rst Returns @@ -110,7 +116,7 @@ def myfunc(...) -> tuple[int, str]: ``` Many functions also just modify parts of the passed AnnData object, like e.g. {func}`~scanpy.tl.dpt`. -You can then combine prose and lists to best describe what happens. +You can then combine prose and lists to best describe what happens: ```rst Returns diff --git a/docs/dev/getting-set-up.md b/docs/dev/getting-set-up.md index 750af53e91..20c6cba63a 100644 --- a/docs/dev/getting-set-up.md +++ b/docs/dev/getting-set-up.md @@ -6,8 +6,11 @@ This section of the docs covers our practices for working with `git` on our code For a more complete git tutorials we recommend checking out: -- [Atlassian's git tutorial](https://www.atlassian.com/git/tutorials) -- Beginner friendly introductions to the git command line interface -- [Setting up git for GitHub](https://docs.github.com/en/free-pro-team@latest/github/getting-started-with-github/set-up-git) -- Configuring git to work with your GitHub user account +[Atlassian's git tutorial](https://www.atlassian.com/git/tutorials) +: Beginner friendly introductions to the git command line interface + +[Setting up git for GitHub](https://docs.github.com/en/free-pro-team@latest/github/getting-started-with-github/set-up-git) +: Configuring git to work with your GitHub user account (forking-and-cloning)= @@ -15,9 +18,9 @@ For a more complete git tutorials we recommend checking out: To get the code, and be able to push changes back to the main project, you'll need to (1) fork the repository on github and (2) clone the repository to your local machine. -This is very straight forward if you're using [GitHub's CLI](https://cli.github.com): +This is very straight forward if you're using [GitHub's CLI][]: -```shell +```console $ gh repo fork scverse/scanpy --clone --remote ``` @@ -25,37 +28,41 @@ This will fork the repo to your github account, create a clone of the repo on yo To do this manually, first make a fork of the repository by clicking the "fork" button on our main github package. Then, on your machine, run: -```shell -# Clone your fork of the repository (substitute in your username) -git clone https://github.com/{your-username}/scanpy.git -# Enter the cloned repository -cd scanpy -# Add our repository as a remote -git remote add upstream https://github.com/scverse/scanpy.git -# git branch --set-upstream-to "upstream/main" +```console +$ # Clone your fork of the repository (substitute in your username) +$ git clone https://github.com/{your-username}/scanpy.git +$ # Enter the cloned repository +$ cd scanpy +$ # Add our repository as a remote +$ git remote add upstream https://github.com/scverse/scanpy.git +$ # git branch --set-upstream-to "upstream/main" ``` +[GitHub's CLI]: https://cli.github.com + ### `pre-commit` -We use [precommit](https://pre-commit.com) to run some styling checks in an automated way. +We use [pre-commit][] to run some styling checks in an automated way. We also test against these checks, so make sure you follow them! You can install pre-commit with: -```shell -pip install pre-commit +```console +$ pip install pre-commit ``` You can then install it to run while developing here with: -```shell -pre-commit install +```console +$ pre-commit install ``` From the root of the repo. If you choose not to run the hooks on each commit, you can run them manually with `pre-commit run --files={your files}`. +[pre-commit]: https://pre-commit.com + (creating-a-branch)= ### Creating a branch for your feature @@ -64,10 +71,10 @@ All development should occur in branches dedicated to the particular work being Additionally, unless you are a maintainer, all changes should be directed at the `main` branch. You can create a branch with: -```shell -git checkout main # Starting from the main branch -git pull # Syncing with the repo -git checkout -b {your-branch-name} # Making and changing to the new branch +```console +$ git checkout main # Starting from the main branch +$ git pull # Syncing with the repo +$ git switch -c {your-branch-name} # Making and changing to the new branch ``` (open-a-pr)= @@ -76,11 +83,11 @@ git checkout -b {your-branch-name} # Making and changing to the new branch When you're ready to have your code reviewed, push your changes up to your fork: -```shell -# The first time you push the branch, you'll need to tell git where -git push --set-upstream origin {your-branch-name} -# After that, just use -git push +```console +$ # The first time you push the branch, you'll need to tell git where +$ git push --set-upstream origin {your-branch-name} +$ # After that, just use +$ git push ``` And open a pull request by going to the main repo and clicking *New pull request*. @@ -93,6 +100,10 @@ We'll try and get back to you soon! ## Development environments It's recommended to do development work in an isolated environment. -There are number of ways to do this, including conda environments, virtual environments, and virtual machines. +There are number of ways to do this, including virtual environments, conda environments, and virtual machines. + +We think the easiest is probably [Hatch environments][]. +Using one of the predefined environments in {file}`hatch.toml` is as simple as running `hatch test` or `hatch run docs:build` (they will be created on demand). +For an in-depth guide, refer to the {ref}`development install instructions ` of `scanpy`. -We think the easiest is probably conda environments. Simply create a new environment with a supported version of python and make a {ref}`development install ` of `scanpy`. +[hatch environments]: https://hatch.pypa.io/latest/tutorials/environment/basic-usage/ diff --git a/docs/dev/release.md b/docs/dev/release.md index e3ce2a31ab..f93b73eaa1 100644 --- a/docs/dev/release.md +++ b/docs/dev/release.md @@ -5,12 +5,9 @@ That page also explains concepts like *pre-releases* and applications thereof. ## Preparing the release -1. Make a new branch off of `main` to prepare the release notes, and create a PR from this branch back into `main`. - Add a milestone for the desired version to be released. -2. Update the date in the desired release’s notes and if applicable, delete empty headers in the notes. - Create a new blank note for the next desired release and update the `index.md` to include it. -3. Push the changes to the PR, and merge into `main`. - If it is a patch release, backport the updated notes (see [](#versioning-tooling)) into the major/minor version branch. +1. Switch to the `main` branch for a major/minor release and the respective release series branch for a *patch* release (e.g. `1.8.x` when releasing version 1.8.4). +2. Run `hatch towncrier:build` to generate a PR that creates a new release notes file. Wait for the PR to be auto-merged. +3. If it is a *patch* release, merge the backport PR (see {ref}`versioning-tooling`) into the `main` branch. ## Actually making the release @@ -28,8 +25,6 @@ That page also explains concepts like *pre-releases* and applications thereof. After *any* release has been made: -- Create a new release notes file for the next bugfix release. - This should be included in both dev and stable branches. - Create a milestone for the next release (in case you made a bugfix release) or releases (in case of a major/minor release). For bugfix releases, this should have `on-merge: backport to 0..x`, so the [meeseeksdev][] bot will create a backport PR. See {doc}`versioning` for more info. @@ -50,27 +45,20 @@ If you changed something about the build process (e.g. [Hatchling’s build conf or something about the package’s structure, you might want to manually check if the build and upload process behaves as expected: -```shell -# Clear out old distributions -rm -r dist - -# Build source distribution and wheel both -python -m build - -# Now check those build artifacts -twine check dist/* - -# List the wheel archive’s contents -bsdtar -tf dist/*.whl - +```console +$ # Clear out old distributions +$ rm -r dist +$ # Build source distribution and wheel both +$ python -m build +$ # Now check those build artifacts +$ twine check dist/* +$ # List the wheel archive’s contents +$ bsdtar -tf dist/*.whl ``` You can also upload the package to ([tutorial][testpypi tutorial]) - -[testpypi tutorial]: https://packaging.python.org/en/latest/tutorials/packaging-projects/#uploading-the-distribution-archives - -``` -twine upload --repository testpypi dist/* +```console +$ twine upload --repository testpypi dist/* ``` The above approximates what the [publish workflow][] does automatically for us. @@ -78,4 +66,5 @@ If you want to replicate the process more exactly, make sure you are careful, and create a version tag before building (make sure you delete it after uploading to TestPyPI!). [hatch-build]: https://hatch.pypa.io/latest/config/build/ +[testpypi tutorial]: https://packaging.python.org/en/latest/tutorials/packaging-projects/#uploading-the-distribution-archives [publish workflow]: https://github.com/scverse/scanpy/tree/main/.github/workflows/publish.yml diff --git a/docs/dev/testing.md b/docs/dev/testing.md index aeae4ee8da..81eae36c75 100644 --- a/docs/dev/testing.md +++ b/docs/dev/testing.md @@ -7,34 +7,43 @@ Implementations may change, but the only way we can know the code is working bef ## Running the tests -We use [pytest](https://docs.pytest.org/en/stable/) to test scanpy. -To run the tests first make sure you have the required dependencies (`pip install -e ".[test,dev]"`), then run `pytest` from the root of the repository. +We use [pytest][] to test scanpy. +To run the tests, simply run `hatch test`. It can take a while to run the whole test suite. There are a few ways to cut down on this while working on a PR: -1. Only run a subset of the tests. This can be done with the `-k` argument from pytest (e.g. `pytest -k test_plotting.py` or `pytest -k "test_umap*"` -2. Run the tests in parallel. If you install the pytest extension [pytest-xdist](https://github.com/pytest-dev/pytest-xdist) you can run tests in parallel with the `--numprocesses` argument to pytest (e.g. `pytest -n 8`). +1. Only run a subset of the tests. + This can be done by specifying paths or test name patterns using the `-k` argument (e.g. `hatch test test_plotting.py` or `hatch test -k "test_umap*"`) +2. Run the tests in parallel using the `-n` argument (e.g. `hatch test -n 8`). + +[pytest]: https://docs.pytest.org/en/stable/ ### Miscellaneous tips -- A lot of warnings can be thrown while running the test suite. It's often easier to read the test results with them hidden via the `--disable-pytest-warnings` argument. +- A lot of warnings can be thrown while running the test suite. + It's often easier to read the test results with them hidden via the `--disable-pytest-warnings` argument. ## Writing tests -You can refer to the [existing test suite](https://github.com/scverse/scanpy/tree/main/scanpy/tests) for examples. -If you haven't written tests before, Software Carpentry has an [in-depth guide](https://katyhuff.github.io/2016-07-11-scipy/testing/01-basics.html) on the topic. +You can refer to the [existing test suite][] for examples. +If you haven't written tests before, Software Carpentry has an [in-depth testing guide][]. -We highly recommend using [Test Driven Development](https://en.wikipedia.org/wiki/Test-driven_development) when contributing code. +We highly recommend using [Test-Driven Development][] when contributing code. This not only ensures you have tests written, it often makes implementation easier since you start out with a specification for your function. Consider parameterizing your tests using the `pytest.mark.parameterize` and `pytest.fixture` decorators. -Documentation on these can be found [here](https://docs.pytest.org/en/stable/fixture.html), but we'd also recommend searching our test suite for existing usage. +You can read more about [fixtures][] in pytest’s documentation, but we’d also recommend searching our test suite for existing usage. + +[existing test suite]: https://github.com/scverse/scanpy/tree/main/scanpy/tests +[in-depth testing guide]: https://katyhuff.github.io/2016-07-11-scipy/testing/ +[test-driven development]: https://en.wikipedia.org/wiki/Test-driven_development +[fixtures]: https://docs.pytest.org/en/stable/fixture.html ### What to test If you're not sure what to tests about your function, some ideas include: -- Are there arguments which conflict with each other? Check that if they are both passed, the function throws an error (see `pytest.raises` [in the pytest docs](https://docs.pytest.org/en/stable/assert.html#assertions-about-expected-exceptions). +- Are there arguments which conflict with each other? Check that if they are both passed, the function throws an error (see [`pytest.raises`][] docs). - Are there input values which should cause your function to error? - Did you add a helpful error message that recommends better outputs? Check that that error message is actually thrown. - Can you place bounds on the values returned by your function? @@ -42,6 +51,8 @@ If you're not sure what to tests about your function, some ideas include: - Do you have arguments which should have orthogonal effects on the output? Check that they are independent. For example, if there is a flag for extended output, the base output should remain the same either way. - Are you optimizing a method? Check that it's results are the same as a gold standard implementation. +[`pytest.raises`]: https://docs.pytest.org/en/stable/assert.html#assertions-about-expected-exceptions + ### Performance It's more important that you're accurately testing the code works than it is that test suite runs quickly. @@ -51,9 +62,11 @@ You can check how long tests take to run by passing `--durations=0` argument to Hopefully your new tests won't show up on top! Some approaches to this include: -- Is there a common setup/ computation happening in each test? Consider caching these in a [scoped test fixture](https://docs.pytest.org/en/stable/fixture.html#sharing-test-data). +- Is there a common setup/ computation happening in each test? Consider caching these in a [scoped test fixture][]. - Is the behaviour you're testing for dependent on the size of the data? If not, consider reducing it. +[scoped test fixture]: https://docs.pytest.org/en/stable/fixture.html#sharing-test-data + ### Plotting tests While computational functions will return arrays and values, it can be harder to work with the output of plotting functions. diff --git a/docs/dev/versioning.md b/docs/dev/versioning.md index e87b3d7a9f..748b3d2e2c 100644 --- a/docs/dev/versioning.md +++ b/docs/dev/versioning.md @@ -18,9 +18,10 @@ At a `point` release, there should be no changes beyond bug fixes. Valid version numbers are described in [PEP 440](https://peps.python.org/pep-0440/). [Pre-releases](https://peps.python.org/pep-0440/#pre-releases) -: should have versions like `1.7.0rc1` or `1.7.0rc2`. +: should have versions like `1.7.0rc1` or `1.7.0rc2`. + [Development versions](https://peps.python.org/pep-0440/#developmental-releases) -: should look like `1.8.0.dev0`, with a commit hash optionally appended as a local version identifier (e.g. `1.8.0.dev2+g00ad77b`). +: should look like `1.8.0.dev0`, with a commit hash optionally appended as a local version identifier (e.g. `1.8.0.dev2+g00ad77b`). (versioning-tooling)= ## Tooling @@ -29,12 +30,18 @@ To be sure we can follow this scheme and maintain some agility in development, w When a minor release is made, a release branch should be cut and pushed to the main repo (e.g. `1.7.x` for the `1.7` release series). For PRs which fix an bug in the most recent minor release, the changes will need to added to both the development and release branches. -To accomplish this, PRs which fix bugs must be labelled as such. -After approval, a developer will notify the [meeseeks bot](https://meeseeksbox.github.io) to open a backport PR onto the release branch via a comment saying: +To accomplish this, PRs which fix bugs are assigned a patch version milestone such as `1.7.4`. +Once the PR is approved and merged, the bot will attempt to make a backport and open a PR. +This will sometimes require manual intervention due to merge conflicts or test failures. + +### Technical details + +The [meeseeks bot][] reacts to commands like this, +given as a comment on the PR, or a label or milestone description: > @Meeseeksdev backport \ -Where "\" is the most recent release branch. +In our case, these commands are part of the milestone description, +which causes the merge of a PR assigned to a milestone to trigger the bot. -The bot will attempt to make a backport and open a PR. -This will sometimes require manual intervention due to merge conflicts or test failures. +[meseeks bot]: https://meeseeksbox.github.io diff --git a/docs/installation.md b/docs/installation.md index 815b2a3a15..c28a09d668 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -1,116 +1,113 @@ # Installation -## Anaconda +To use `scanpy` from another project, install it using your favourite environment manager: -If you do not have a working installation of Python 3.6 (or later), consider -installing [Miniconda] (see [Installing Miniconda]). Then run: +::::{tabs} -```shell -conda install -c conda-forge scanpy python-igraph leidenalg -``` +:::{group-tab} Hatch (recommended) +Adding `scanpy[leiden]` to your dependencies is enough. +See below for how to use Scanpy’s {ref}`dev-install-instructions`. +::: -Pull Scanpy from [PyPI](https://pypi.org/project/scanpy) (consider using `pip3` to access Python 3): +:::{group-tab} Pip/PyPI +If you prefer to exclusively use PyPI run: -```shell -pip install scanpy +```console +$ pip install 'scanpy[leiden]' ``` +::: -## PyPI only +:::{group-tab} Conda +After installing installing e.g. [Miniconda][], run: -If you prefer to exclusively use PyPI run: +```console +$ conda install -c conda-forge scanpy python-igraph leidenalg +``` + +Pull Scanpy [from PyPI][] (consider using `pip3` to access Python 3): -```shell -pip install 'scanpy[leiden]' +```console +$ pip install scanpy ``` -The extra `[leiden]` installs two packages that are needed for popular -parts of scanpy but aren't requirements: [igraph] {cite:p}`Csardi2006` and [leiden] {cite:p}`Traag2019`. +[miniconda]: https://docs.anaconda.com/miniconda/miniconda-install/ +[from pypi]: https://pypi.org/project/scanpy +::: + +:::: + +If you use Hatch or pip, the extra `[leiden]` installs two packages that are needed for popular +parts of scanpy but aren't requirements: [igraph][] {cite:p}`Csardi2006` and [leiden][] {cite:p}`Traag2019`. +If you use conda, you should to add these dependencies to your environment individually. + +[igraph]: https://python.igraph.org/en/stable/ +[leiden]: https://leidenalg.readthedocs.io (dev-install-instructions)= ## Development Version -To work with the latest version [on GitHub]: clone the repository and `cd` into its root directory. +To work with the latest version [on GitHub][]: clone the repository and `cd` into its root directory. -```shell -gh repo clone scverse/scanpy -cd scanpy +```console +$ gh repo clone scverse/scanpy +$ cd scanpy ``` -If you are using `pip>=21.3`, an editable install can be made: +::::{tabs} -```shell -pip install -e '.[dev,test]' -``` +:::{group-tab} Hatch (recommended) +To use one of the predefined [Hatch environments][] in {file}`hatch.toml`, +run either `hatch test [args]` or `hatch run [env:]command [...args]`, e.g.: -If you want to let [conda] handle the installations of dependencies, do: - -```shell -pipx install beni -beni pyproject.toml > environment.yml -conda env create -f environment.yml -conda activate scanpy -pip install -e '.[dev,doc,test]' +```console +$ hatch test -p # run tests in parallel +$ hatch run docs:build # build docs +$ hatch run towncrier:create # create changelog entry ``` -For instructions on how to work with the code, see the {ref}`contribution guide `. +[hatch environments]: https://hatch.pypa.io/latest/tutorials/environment/basic-usage/ +::: -## Docker - -If you're using [Docker], you can use e.g. the image [gcfntnu/scanpy] from Docker Hub. +:::{group-tab} Pip/PyPI +If you are using `pip>=21.3`, an editable install can be made: -## Troubleshooting +```console +$ python -m venv .venv +$ source .venv/bin/activate +$ pip install -e '.[dev,test]' +``` +::: -If you get a `Permission denied` error, never use `sudo pip`. Instead, use virtual environments or: +:::{group-tab} Conda +If you want to let `conda` handle the installations of dependencies, do: -```shell -pip install --user scanpy +```console +$ pipx install beni +$ beni pyproject.toml > environment.yml +$ conda env create -f environment.yml +$ conda activate scanpy +$ pip install -e '.[dev,doc,test]' ``` -**On MacOS**, if **not** using `conda`, you might need to install the C core of igraph via homebrew first - -- `brew install igraph` +For instructions on how to work with the code, see the {ref}`contribution guide `. +::: -- If igraph still fails to install, see the question on [compiling igraph]. - Alternatively consider installing gcc via `brew install gcc --without-multilib` - and exporting the required variables: +:::: - ```shell - export CC="/usr/local/Cellar/gcc/X.x.x/bin/gcc-X" - export CXX="/usr/local/Cellar/gcc/X.x.x/bin/gcc-X" - ``` +[on github]: https://github.com/scverse/scanpy - where `X` and `x` refers to the version of `gcc`; - in my case, the path reads `/usr/local/Cellar/gcc/6.3.0_1/bin/gcc-6`. +## Docker -**On Windows**, there also often problems installing compiled packages such as `igraph`, -but you can find precompiled packages on Christoph Gohlke’s [unofficial binaries]. -Download those and install them using `pip install ./path/to/file.whl` +If you're using [Docker][], you can use e.g. the image [gcfntnu/scanpy][] from Docker Hub. -(conda)= +[docker]: https://en.wikipedia.org/wiki/Docker_(software) +[gcfntnu/scanpy]: https://hub.docker.com/r/gcfntnu/scanpy -## Installing Miniconda +## Troubleshooting -After downloading [Miniconda], in a unix shell (Linux, Mac), run +If you get a `Permission denied` error, never use `sudo pip`. Instead, use virtual environments or: -```shell -cd DOWNLOAD_DIR -chmod +x Miniconda3-latest-VERSION.sh -./Miniconda3-latest-VERSION.sh +```console +$ pip install --user scanpy ``` - -and accept all suggestions. -Either reopen a new terminal or `source ~/.bashrc` on Linux/ `source ~/.bash_profile` on Mac. -The whole process takes just a couple of minutes. - -[bioconda]: https://bioconda.github.io/ -[compiling igraph]: https://stackoverflow.com/q/29589696/247482 -[create symbolic links]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/create-symbolic-links -[docker]: https://en.wikipedia.org/wiki/Docker_(software) -[from pypi]: https://pypi.org/project/scanpy -[gcfntnu/scanpy]: https://hub.docker.com/r/gcfntnu/scanpy -[leiden]: https://leidenalg.readthedocs.io -[miniconda]: https://docs.conda.io/projects/miniconda/en/latest/ -[on github]: https://github.com/scverse/scanpy -[igraph]: https://python.igraph.org/en/stable/ -[unofficial binaries]: https://www.lfd.uci.edu/~gohlke/pythonlibs/ diff --git a/docs/release-notes/1.10.0.md b/docs/release-notes/1.10.0.md index 0448d9fc5f..2e23d24426 100644 --- a/docs/release-notes/1.10.0.md +++ b/docs/release-notes/1.10.0.md @@ -32,7 +32,7 @@ Some highlights: * {func}`scanpy.pp.scale` now clips `np.ndarray` also at `- max_value` for zero-centering {pr}`2913` {smaller}`S Dicks` * Support sparse chunks in dask {func}`~scanpy.pp.scale`, {func}`~scanpy.pp.normalize_total` and {func}`~scanpy.pp.highly_variable_genes` (`seurat` and `cell-ranger` tested) {pr}`2856` {smaller}`ilan-gold` -#### Docs +#### Documentation * Doc style overhaul {pr}`2220` {smaller}`A Gayoso` * Re-add search-as-you-type, this time via `readthedocs-sphinx-search` {pr}`2805` {smaller}`P Angerer` @@ -59,7 +59,7 @@ Some highlights: * Fix pytest deprecation warning {pr}`2879` {smaller}`P Angerer` -#### Development +#### Development Process * Scanpy is now tested against python 3.12 {pr}`2863` {smaller}`ivirshup` * Fix testing package build {pr}`2468` {smaller}`P Angerer` diff --git a/docs/release-notes/1.10.1.md b/docs/release-notes/1.10.1.md index 35f631bdc0..859789af5b 100644 --- a/docs/release-notes/1.10.1.md +++ b/docs/release-notes/1.10.1.md @@ -1,7 +1,7 @@ (v1.10.1)= ### 1.10.1 {small}`2024-04-09` -#### Docs +#### Documentation * Added {doc}`how-to example ` on plotting with [Marsilea](https://marsilea.readthedocs.io) {pr}`2974` {smaller}`Y Zheng` diff --git a/docs/release-notes/1.10.2.md b/docs/release-notes/1.10.2.md index 8e0342054b..947da0be29 100644 --- a/docs/release-notes/1.10.2.md +++ b/docs/release-notes/1.10.2.md @@ -1,11 +1,11 @@ (v1.10.2)= ### 1.10.2 {small}`2024-06-25` -#### Development features +#### Development Process * Add performance benchmarking {pr}`2977` {smaller}`R Shrestha`, {smaller}`P Angerer` -#### Docs +#### Documentation * Document several missing parameters in docstring {pr}`2888` {smaller}`S Cheney` * Fixed incorrect instructions in "testing" dev docs {pr}`2994` {smaller}`I Virshup` diff --git a/docs/release-notes/1.10.3.md b/docs/release-notes/1.10.3.md deleted file mode 100644 index 6ba996730c..0000000000 --- a/docs/release-notes/1.10.3.md +++ /dev/null @@ -1,22 +0,0 @@ -(v1.10.3)= -### 1.10.3 {small}`the future` - -#### Development features - -#### Docs - -#### Bug fixes - -* Prevent empty control gene set in {func}`~scanpy.tl.score_genes` {pr}`2875` {smaller}`M Müller` -* Fix `subset=True` of {func}`~scanpy.pp.highly_variable_genes` when `flavor` is `seurat` or `cell_ranger`, and `batch_key!=None` {pr}`3042` {smaller}`E Roellin` -* Add compatibility with {mod}`numpy` 2.0 {pr}`3065` and {pr}`3115` {smaller}`P Angerer` -* Fix `legend_loc` argument in {func}`scanpy.pl.embedding` not accepting matplotlib parameters {pr}`3163` {smaller}`P Angerer` -* Fix dispersion cutoff in {func}`~scanpy.pp.highly_variable_genes` in presence of `NaN`s {pr}`3176` {smaller}`P Angerer` -* Fix axis labeling for swapped axes in {func}`~scanpy.pl.rank_genes_groups_stacked_violin` {pr}`3196` {smaller}`Ilan Gold` -* Upper bound dask on account of {issue}`scverse/anndata#1579` {pr}`3217` {smaller}`Ilan Gold` -* The [fa2-modified][] package replaces [forceatlas2][] for the latter’s lack of maintenance. {pr}`3220` {smaller}`A Alam` - -[fa2-modified]: https://github.com/AminAlam/fa2_modified -[forceatlas2]: https://github.com/bhargavchippada/forceatlas2 - -#### Performance diff --git a/docs/release-notes/1.11.0.md b/docs/release-notes/1.11.0.md deleted file mode 100644 index c948f8068a..0000000000 --- a/docs/release-notes/1.11.0.md +++ /dev/null @@ -1,14 +0,0 @@ -(v1.11.0)= -### 1.11.0 {small}`the future` - -#### Features - -* Add `layer` argument to {func}`scanpy.tl.score_genes` and {func}`scanpy.tl.score_genes_cell_cycle` {pr}`2921` {smaller}`L Zappia` -* Prevent `raw` conflict with `layer` in {func}`~scanpy.tl.score_genes` {pr}`3155` {smaller}`S Dicks` -* Add `key_added` argument to {func}`~scanpy.pp.pca`, {func}`~scanpy.tl.tsne` and {func}`~scanpy.tl.umap` {pr}`3184` {smaller}`P Angerer` - -#### Docs - -#### Bug fixes - -#### Deprecations diff --git a/docs/release-notes/1.8.0.md b/docs/release-notes/1.8.0.md index f2e06e8371..8bf2c36895 100644 --- a/docs/release-notes/1.8.0.md +++ b/docs/release-notes/1.8.0.md @@ -47,7 +47,7 @@ - {func}`scanpy.pl.rank_genes_groups_violin` now works for `raw=False` {pr}`1669` {smaller}`M van den Beek` - {func}`scanpy.pl.dotplot` now uses `smallest_dot` argument correctly {pr}`1771` {smaller}`S Flemming` -#### Development processes +#### Development Process - Switched to [flit] for building and deploying the package, a simple tool with an easy to understand command line interface and metadata {pr}`1527` {smaller}`P Angerer` - Use [pre-commit](https://pre-commit.com) for style checks {pr}`1684` {pr}`1848` {smaller}`L Heumos` {smaller}`I Virshup` diff --git a/docs/release-notes/1.8.2.md b/docs/release-notes/1.8.2.md index 418cae9944..d26e2e4ac2 100644 --- a/docs/release-notes/1.8.2.md +++ b/docs/release-notes/1.8.2.md @@ -1,7 +1,7 @@ (v1.8.2)= ### 1.8.2 {small}`2021-11-3` -#### Docs +#### Documentation - Update conda installation instructions {pr}`1974` {smaller}`L Heumos` diff --git a/docs/release-notes/2875.bugfix.md b/docs/release-notes/2875.bugfix.md new file mode 100644 index 0000000000..0a4866f175 --- /dev/null +++ b/docs/release-notes/2875.bugfix.md @@ -0,0 +1 @@ +Prevent empty control gene set in {func}`~scanpy.tl.score_genes` {smaller}`M Müller` diff --git a/docs/release-notes/2921.feature.md b/docs/release-notes/2921.feature.md new file mode 100644 index 0000000000..e3c964abb2 --- /dev/null +++ b/docs/release-notes/2921.feature.md @@ -0,0 +1 @@ +Add `layer` argument to {func}`scanpy.tl.score_genes` and {func}`scanpy.tl.score_genes_cell_cycle` {smaller}`L Zappia` diff --git a/docs/release-notes/3042.bugfix.md b/docs/release-notes/3042.bugfix.md new file mode 100644 index 0000000000..8317856177 --- /dev/null +++ b/docs/release-notes/3042.bugfix.md @@ -0,0 +1 @@ +Fix `subset=True` of {func}`~scanpy.pp.highly_variable_genes` when `flavor` is `seurat` or `cell_ranger`, and `batch_key!=None` {smaller}`E Roellin` diff --git a/docs/release-notes/3115.bugfix.md b/docs/release-notes/3115.bugfix.md new file mode 100644 index 0000000000..2e31f4f691 --- /dev/null +++ b/docs/release-notes/3115.bugfix.md @@ -0,0 +1 @@ +Add compatibility with {mod}`numpy` 2.0 {smaller}`P Angerer` {pr}`3065` and diff --git a/docs/release-notes/3155.feature.md b/docs/release-notes/3155.feature.md new file mode 100644 index 0000000000..770c504348 --- /dev/null +++ b/docs/release-notes/3155.feature.md @@ -0,0 +1 @@ +Prevent `raw` conflict with `layer` in {func}`~scanpy.tl.score_genes` {smaller}`S Dicks` diff --git a/docs/release-notes/3163.bugfix.md b/docs/release-notes/3163.bugfix.md new file mode 100644 index 0000000000..7e82799ee8 --- /dev/null +++ b/docs/release-notes/3163.bugfix.md @@ -0,0 +1 @@ +Fix `legend_loc` argument in {func}`scanpy.pl.embedding` not accepting matplotlib parameters {smaller}`P Angerer` diff --git a/docs/release-notes/3176.bugfix.md b/docs/release-notes/3176.bugfix.md new file mode 100644 index 0000000000..bd22b88f8e --- /dev/null +++ b/docs/release-notes/3176.bugfix.md @@ -0,0 +1 @@ +Fix dispersion cutoff in {func}`~scanpy.pp.highly_variable_genes` in presence of `NaN`s {smaller}`P Angerer` diff --git a/docs/release-notes/3184.feature.md b/docs/release-notes/3184.feature.md new file mode 100644 index 0000000000..3cc976b141 --- /dev/null +++ b/docs/release-notes/3184.feature.md @@ -0,0 +1 @@ +Add `key_added` argument to {func}`~scanpy.pp.pca`, {func}`~scanpy.tl.tsne` and {func}`~scanpy.tl.umap` {smaller}`P Angerer` diff --git a/docs/release-notes/3196.bugfix.md b/docs/release-notes/3196.bugfix.md new file mode 100644 index 0000000000..8b701aa42f --- /dev/null +++ b/docs/release-notes/3196.bugfix.md @@ -0,0 +1 @@ +Fix axis labeling for swapped axes in {func}`~scanpy.pl.rank_genes_groups_stacked_violin` {smaller}`Ilan Gold` diff --git a/docs/release-notes/3217.bugfix.md b/docs/release-notes/3217.bugfix.md new file mode 100644 index 0000000000..9054c4c8f6 --- /dev/null +++ b/docs/release-notes/3217.bugfix.md @@ -0,0 +1 @@ +Upper bound dask on account of {issue}`scverse/anndata#1579` {smaller}`Ilan Gold` diff --git a/docs/release-notes/3220.bugfix.md b/docs/release-notes/3220.bugfix.md new file mode 100644 index 0000000000..81437fc4cf --- /dev/null +++ b/docs/release-notes/3220.bugfix.md @@ -0,0 +1,4 @@ +The [fa2-modified][] package replaces [forceatlas2][] for the latter’s lack of maintenance {smaller}`A Alam` + +[fa2-modified]: https://github.com/AminAlam/fa2_modified +[forceatlas2]: https://github.com/bhargavchippada/forceatlas2 diff --git a/docs/release-notes/index.md b/docs/release-notes/index.md index 3dc461d0b4..ae08bf99cb 100644 --- a/docs/release-notes/index.md +++ b/docs/release-notes/index.md @@ -2,181 +2,5 @@ # Release notes -## Version 1.11 - -```{include} /release-notes/1.11.0.md -``` - -## Version 1.10 - -```{include} /release-notes/1.10.3.md -``` - -```{include} /release-notes/1.10.2.md -``` - -```{include} /release-notes/1.10.1.md -``` - -```{include} /release-notes/1.10.0.md -``` - -## Version 1.9 - -```{include} /release-notes/1.9.8.md -``` - -```{include} /release-notes/1.9.7.md -``` - -```{include} /release-notes/1.9.6.md -``` - -```{include} /release-notes/1.9.5.md -``` - -```{include} /release-notes/1.9.4.md -``` - -```{include} /release-notes/1.9.3.md -``` - -```{include} /release-notes/1.9.2.md -``` - -```{include} /release-notes/1.9.1.md -``` - -```{include} /release-notes/1.9.0.md -``` - -## Version 1.8 - -```{include} /release-notes/1.8.2.md -``` - -```{include} /release-notes/1.8.1.md -``` - -```{include} /release-notes/1.8.0.md -``` - -## Version 1.7 - -```{include} /release-notes/1.7.2.md -``` - -```{include} /release-notes/1.7.1.md -``` - -```{include} /release-notes/1.7.0.md -``` - -## Version 1.6 - -```{include} 1.6.0.md -``` - -## Version 1.5 - -```{include} 1.5.1.md -``` - -```{include} 1.5.0.md -``` - -## Version 1.4 - -```{include} 1.4.6.md -``` - -```{include} 1.4.5.md -``` - -```{include} 1.4.4.md -``` - -```{include} 1.4.3.md -``` - -```{include} 1.4.2.md -``` - -```{include} 1.4.1.md -``` - -## Version 1.3 - -```{include} 1.3.8.md -``` - -```{include} 1.3.7.md -``` - -```{include} 1.3.6.md -``` - -```{include} 1.3.5.md -``` - -```{include} 1.3.4.md -``` - -```{include} 1.3.3.md -``` - -```{include} 1.3.1.md -``` - -## Version 1.2 - -```{include} 1.2.1.md -``` - -```{include} 1.2.0.md -``` - -## Version 1.1 - -```{include} 1.1.0.md -``` - -## Version 1.0 - -```{include} 1.0.0.md -``` - -## Version 0.4 - -```{include} 0.4.4.md -``` - -```{include} 0.4.3.md -``` - -```{include} 0.4.2.md -``` - -```{include} 0.4.0.md -``` - -## Version 0.3 - -```{include} 0.3.2.md -``` - -```{include} 0.3.0.md -``` - -## Version 0.2 - -```{include} 0.2.9.md -``` - -```{include} 0.2.1.md -``` - -## Version 0.1 - -```{include} 0.1.0.md +```{release-notes} . ``` diff --git a/hatch.toml b/hatch.toml new file mode 100644 index 0000000000..77c1c92b1f --- /dev/null +++ b/hatch.toml @@ -0,0 +1,33 @@ +[envs.default] +installer = "uv" +features = ["dev"] + +[envs.docs] +features = ["doc"] +scripts.build = "sphinx-build -M html docs docs/_build -W --keep-going {args}" +scripts.open = "python3 -m webbrowser -t docs/_build/html/index.html" +scripts.clean = "git clean -fdX -- {args:docs}" + +[envs.towncrier] +scripts.create = "towncrier create {args}" +scripts.build = "python3 ci/scripts/towncrier_automation.py {args}" +scripts.clean = "git restore --source=HEAD --staged --worktree -- docs/release-notes" + +[envs.hatch-test] +default-args = [] +features = ["test"] +extra-dependencies = ["ipykernel"] +overrides.matrix.deps.env-vars = [ + { if = ["pre"], key = "UV_PRERELEASE", value = "allow" }, + { if = ["min"], key = "UV_RESOLUTION", value = "lowest-direct" }, +] +overrides.matrix.deps.python = [ + { if = ["min"] , value = "3.9" }, + { if = ["stable", "full", "pre"], value = "3.12" }, +] +overrides.matrix.deps.features = [ + { if = ["full"] , value = "test-full" }, +] + +[[envs.hatch-test.matrix]] +deps = ["stable", "full", "pre", "min"] diff --git a/pyproject.toml b/pyproject.toml index cde2ce89fb..d4e85bf676 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -112,11 +112,12 @@ test-full = [ doc = [ "sphinx>=7", "sphinx-book-theme>=1.1.0", - "scanpydoc>=0.13.4", + "scanpydoc>=0.14.1", "sphinx-autodoc-typehints>=1.25.2", "myst-parser>=2", "myst-nb>=1", "sphinx-design", + "sphinx-tabs", "readthedocs-sphinx-search", "sphinxext-opengraph", # for nice cards when sharing on social "sphinx-copybutton", @@ -135,6 +136,7 @@ dev = [ "setuptools_scm", # static checking "pre-commit", + "towncrier", ] # Algorithms paga = ["igraph"] @@ -258,3 +260,19 @@ required-imports = ["from __future__ import annotations"] [tool.ruff.lint.flake8-type-checking] exempt-modules = [] strict = true + +[tool.towncrier] +package = "scanpy" +directory = "docs/release-notes" +filename = "docs/release-notes/{version}.md" +single_file = false +package_dir = "src" +issue_format = "{{pr}}`{issue}`" +title_format = "(v{version})=\n### {version} {{small}}`{project_date}`" +fragment.bugfix.name = "Bug fixes" +fragment.doc.name = "Documentation" +fragment.feature.name = "Features" +fragment.misc.name = "Miscellaneous improvements" +fragment.performance.name = "Performance" +fragment.breaking.name = "Breaking changes" +fragment.dev.name = "Development Process" From 531703b49a8e2ac9d8c9661f79f106f5539f3cc4 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Tue, 17 Sep 2024 14:37:55 +0200 Subject: [PATCH 039/118] Fix towncrier git CLI call (#3236) --- ci/scripts/towncrier_automation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/scripts/towncrier_automation.py b/ci/scripts/towncrier_automation.py index 7dcb3cb7bf..57a093a305 100755 --- a/ci/scripts/towncrier_automation.py +++ b/ci/scripts/towncrier_automation.py @@ -76,7 +76,7 @@ def main(argv: Sequence[str] | None = None) -> None: # push if not args.dry_run: subprocess.run( - ["git", "push", "--set-upstream=origin", branch_name], check=True + ["git", "push", "--set-upstream", "origin", branch_name], check=True ) else: print("Dry run, not pushing") From 3ba6c0c7502b18a842a3b5aee7f610973c9d60be Mon Sep 17 00:00:00 2001 From: "Lumberbot (aka Jack)" <39504233+meeseeksmachine@users.noreply.github.com> Date: Tue, 17 Sep 2024 06:36:26 -0700 Subject: [PATCH 040/118] Backport PR #3235 on branch main ((chore): generate 1.10.3 release notes) (#3238) Co-authored-by: Philipp A --- docs/release-notes/1.10.3.md | 16 ++++++++++++++++ docs/release-notes/2875.bugfix.md | 1 - docs/release-notes/3042.bugfix.md | 1 - docs/release-notes/3115.bugfix.md | 1 - docs/release-notes/3163.bugfix.md | 1 - docs/release-notes/3176.bugfix.md | 1 - docs/release-notes/3196.bugfix.md | 1 - docs/release-notes/3217.bugfix.md | 1 - docs/release-notes/3220.bugfix.md | 4 ---- 9 files changed, 16 insertions(+), 11 deletions(-) create mode 100644 docs/release-notes/1.10.3.md delete mode 100644 docs/release-notes/2875.bugfix.md delete mode 100644 docs/release-notes/3042.bugfix.md delete mode 100644 docs/release-notes/3115.bugfix.md delete mode 100644 docs/release-notes/3163.bugfix.md delete mode 100644 docs/release-notes/3176.bugfix.md delete mode 100644 docs/release-notes/3196.bugfix.md delete mode 100644 docs/release-notes/3217.bugfix.md delete mode 100644 docs/release-notes/3220.bugfix.md diff --git a/docs/release-notes/1.10.3.md b/docs/release-notes/1.10.3.md new file mode 100644 index 0000000000..f2f06ca94b --- /dev/null +++ b/docs/release-notes/1.10.3.md @@ -0,0 +1,16 @@ +(v1.10.3)= +### 1.10.3 {small}`2024-09-17` + +#### Bug fixes + +- Prevent empty control gene set in {func}`~scanpy.tl.score_genes` {smaller}`M Müller` ({pr}`2875`) +- Fix `subset=True` of {func}`~scanpy.pp.highly_variable_genes` when `flavor` is `seurat` or `cell_ranger`, and `batch_key!=None` {smaller}`E Roellin` ({pr}`3042`) +- Add compatibility with {mod}`numpy` 2.0 {smaller}`P Angerer` {pr}`3065` and ({pr}`3115`) +- Fix `legend_loc` argument in {func}`scanpy.pl.embedding` not accepting matplotlib parameters {smaller}`P Angerer` ({pr}`3163`) +- Fix dispersion cutoff in {func}`~scanpy.pp.highly_variable_genes` in presence of `NaN`s {smaller}`P Angerer` ({pr}`3176`) +- Fix axis labeling for swapped axes in {func}`~scanpy.pl.rank_genes_groups_stacked_violin` {smaller}`Ilan Gold` ({pr}`3196`) +- Upper bound dask on account of {issue}`scverse/anndata#1579` {smaller}`Ilan Gold` ({pr}`3217`) +- The [fa2-modified][] package replaces [forceatlas2][] for the latter’s lack of maintenance {smaller}`A Alam` ({pr}`3220`) + + [fa2-modified]: https://github.com/AminAlam/fa2_modified + [forceatlas2]: https://github.com/bhargavchippada/forceatlas2 diff --git a/docs/release-notes/2875.bugfix.md b/docs/release-notes/2875.bugfix.md deleted file mode 100644 index 0a4866f175..0000000000 --- a/docs/release-notes/2875.bugfix.md +++ /dev/null @@ -1 +0,0 @@ -Prevent empty control gene set in {func}`~scanpy.tl.score_genes` {smaller}`M Müller` diff --git a/docs/release-notes/3042.bugfix.md b/docs/release-notes/3042.bugfix.md deleted file mode 100644 index 8317856177..0000000000 --- a/docs/release-notes/3042.bugfix.md +++ /dev/null @@ -1 +0,0 @@ -Fix `subset=True` of {func}`~scanpy.pp.highly_variable_genes` when `flavor` is `seurat` or `cell_ranger`, and `batch_key!=None` {smaller}`E Roellin` diff --git a/docs/release-notes/3115.bugfix.md b/docs/release-notes/3115.bugfix.md deleted file mode 100644 index 2e31f4f691..0000000000 --- a/docs/release-notes/3115.bugfix.md +++ /dev/null @@ -1 +0,0 @@ -Add compatibility with {mod}`numpy` 2.0 {smaller}`P Angerer` {pr}`3065` and diff --git a/docs/release-notes/3163.bugfix.md b/docs/release-notes/3163.bugfix.md deleted file mode 100644 index 7e82799ee8..0000000000 --- a/docs/release-notes/3163.bugfix.md +++ /dev/null @@ -1 +0,0 @@ -Fix `legend_loc` argument in {func}`scanpy.pl.embedding` not accepting matplotlib parameters {smaller}`P Angerer` diff --git a/docs/release-notes/3176.bugfix.md b/docs/release-notes/3176.bugfix.md deleted file mode 100644 index bd22b88f8e..0000000000 --- a/docs/release-notes/3176.bugfix.md +++ /dev/null @@ -1 +0,0 @@ -Fix dispersion cutoff in {func}`~scanpy.pp.highly_variable_genes` in presence of `NaN`s {smaller}`P Angerer` diff --git a/docs/release-notes/3196.bugfix.md b/docs/release-notes/3196.bugfix.md deleted file mode 100644 index 8b701aa42f..0000000000 --- a/docs/release-notes/3196.bugfix.md +++ /dev/null @@ -1 +0,0 @@ -Fix axis labeling for swapped axes in {func}`~scanpy.pl.rank_genes_groups_stacked_violin` {smaller}`Ilan Gold` diff --git a/docs/release-notes/3217.bugfix.md b/docs/release-notes/3217.bugfix.md deleted file mode 100644 index 9054c4c8f6..0000000000 --- a/docs/release-notes/3217.bugfix.md +++ /dev/null @@ -1 +0,0 @@ -Upper bound dask on account of {issue}`scverse/anndata#1579` {smaller}`Ilan Gold` diff --git a/docs/release-notes/3220.bugfix.md b/docs/release-notes/3220.bugfix.md deleted file mode 100644 index 81437fc4cf..0000000000 --- a/docs/release-notes/3220.bugfix.md +++ /dev/null @@ -1,4 +0,0 @@ -The [fa2-modified][] package replaces [forceatlas2][] for the latter’s lack of maintenance {smaller}`A Alam` - -[fa2-modified]: https://github.com/AminAlam/fa2_modified -[forceatlas2]: https://github.com/bhargavchippada/forceatlas2 From c9685a52b664c0eda92de93b7e2945af4fbb9ed9 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Tue, 17 Sep 2024 17:02:46 +0200 Subject: [PATCH 041/118] Fix release note building and check (#3239) --- .github/workflows/check-pr.yml | 8 ++++---- .readthedocs.yml | 1 + pyproject.toml | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index 88d78c9b43..5eaa4dacb3 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -49,13 +49,13 @@ jobs: with: fetch-depth: 0 filter: blob:none - - name: Find out if relevant release notes are modified - uses: dorny/paths-filter@v2 + - name: Find out if a relevant release fragment is added + uses: dorny/paths-filter@v3 id: changes with: filters: | # this is intentionally a string - relnotes: 'docs/release-notes/${{ github.event.pull_request.milestone.title }}.md' - - name: Check if relevant release notes are modified + relnotes: 'docs/release-notes/${{ github.event.pull_request.number }}.*.md' + - name: Check if a relevant release fragment is added uses: flying-sheep/check@v1 with: success: ${{ steps.changes.outputs.relnotes }} diff --git a/.readthedocs.yml b/.readthedocs.yml index 4ffa520491..adcdfb80d7 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -21,4 +21,5 @@ python: path: . extra_requirements: - doc + - dev # for towncrier - leiden diff --git a/pyproject.toml b/pyproject.toml index d4e85bf676..ec5c6e0541 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -157,6 +157,7 @@ dask-ml = ["dask-ml", "scanpy[dask]"] # Dask-ML for sklearn-like API packages = ["src/testing", "src/scanpy"] [tool.hatch.version] source = "vcs" +raw-options.version_scheme = "release-branch-semver" [tool.hatch.build.hooks.vcs] version-file = "src/scanpy/_version.py" From 0bd71d09043295cec067de420b60cdedb414c08a Mon Sep 17 00:00:00 2001 From: farhadmd7 <56954508+farhadmd7@users.noreply.github.com> Date: Tue, 17 Sep 2024 18:21:51 +0200 Subject: [PATCH 042/118] impl median function for aggregation (#3180) Co-authored-by: Philipp A. Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- docs/release-notes/3180.feature.md | 1 + src/scanpy/get/_aggregated.py | 28 ++++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 docs/release-notes/3180.feature.md diff --git a/docs/release-notes/3180.feature.md b/docs/release-notes/3180.feature.md new file mode 100644 index 0000000000..ab73dfe18e --- /dev/null +++ b/docs/release-notes/3180.feature.md @@ -0,0 +1 @@ +Add support for `median` as an aggregation function to the `Aggregation` class in `scanpy.get._aggregated.py`. This allows for median-based aggregation of data (e.g., pseudobulk), complementing existing methods like mean- and sum-based aggregation {smaller}`M Dehkordi (Farhad)` diff --git a/src/scanpy/get/_aggregated.py b/src/scanpy/get/_aggregated.py index eceaa40fe2..5318244af2 100644 --- a/src/scanpy/get/_aggregated.py +++ b/src/scanpy/get/_aggregated.py @@ -7,6 +7,7 @@ import pandas as pd from anndata import AnnData, utils from scipy import sparse +from sklearn.utils.sparsefuncs import csc_median_axis_0 from .._utils import _resolve_axis from .get import _check_mask @@ -20,7 +21,7 @@ Array = Union[np.ndarray, sparse.csc_matrix, sparse.csr_matrix] # Used with get_args -AggType = Literal["count_nonzero", "mean", "sum", "var"] +AggType = Literal["count_nonzero", "mean", "sum", "var", "median"] class Aggregate: @@ -138,6 +139,27 @@ def mean_var(self, dof: int = 1) -> tuple[np.ndarray, np.ndarray]: var_ *= (group_counts / (group_counts - dof))[:, np.newaxis] return mean_, var_ + def median(self) -> Array: + """\ + Compute the median per feature per group of observations. + + Returns + ------- + Array of median. + """ + + medians = [] + for group in np.unique(self.groupby.codes): + group_mask = self.groupby.codes == group + group_data = self.data[group_mask] + if sparse.issparse(group_data): + if group_data.format != "csc": + group_data = group_data.tocsc() + medians.append(csc_median_axis_0(group_data)) + else: + medians.append(np.median(group_data, axis=0)) + return np.array(medians) + def _power(X: Array, power: float | int) -> Array: """\ @@ -343,7 +365,9 @@ def aggregate_array( result["var"] = var_ if "mean" in funcs: result["mean"] = mean_ - + if "median" in funcs: + agg = groupby.median() + result["median"] = agg return result From 7fef08fdf0964f2befa3a9759f377bd693480f90 Mon Sep 17 00:00:00 2001 From: Ilan Gold Date: Thu, 19 Sep 2024 10:47:10 +0200 Subject: [PATCH 043/118] Upload scrublet scores on test failure (#3069) Co-authored-by: Phil Schaf --- .azure-pipelines.yml | 6 +++++ src/testing/scanpy/_pytest/__init__.py | 2 ++ tests/test_scrublet.py | 36 +++++++++++++++++++------- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index 2086c20aa4..e0e8faefd6 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -103,6 +103,12 @@ jobs: testResultsFormat: NUnit testRunTitle: 'Publish test results for $(Agent.JobName)' + - task: PublishBuildArtifacts@1 + inputs: + pathToPublish: '.pytest_cache/d/debug' + artifactName: debug-data + condition: eq(variables['TEST_TYPE'], 'coverage') + - script: bash <(curl -s https://codecov.io/bash) displayName: 'Upload to codecov.io' condition: eq(variables['TEST_TYPE'], 'coverage') diff --git a/src/testing/scanpy/_pytest/__init__.py b/src/testing/scanpy/_pytest/__init__.py index d989b4080c..318baac1aa 100644 --- a/src/testing/scanpy/_pytest/__init__.py +++ b/src/testing/scanpy/_pytest/__init__.py @@ -34,6 +34,8 @@ def _global_test_context( sc.settings.logfile = sys.stderr sc.settings.verbosity = "hint" sc.settings.autoshow = True + # create directory for debug data + cache.mkdir("debug") # reuse data files between test runs (unless overwritten in the test) sc.settings.datasetdir = cache.mkdir("scanpy-data") # create new writedir for each test run diff --git a/tests/test_scrublet.py b/tests/test_scrublet.py index dc08d24837..246ffa4027 100644 --- a/tests/test_scrublet.py +++ b/tests/test_scrublet.py @@ -117,7 +117,7 @@ def _create_sim_from_parents(adata: AnnData, parents: np.ndarray) -> AnnData: ) -def test_scrublet_data(): +def test_scrublet_data(cache: pytest.Cache): """ Test that Scrublet processing is arranged correctly. @@ -156,14 +156,32 @@ def test_scrublet_data(): random_state=random_state, ) - # Require that the doublet scores are the same whether simulation is via - # the main function or manually provided - assert_allclose( - adata_scrublet_manual_sim.obs["doublet_score"], - adata_scrublet_auto_sim.obs["doublet_score"], - atol=1e-15, - rtol=1e-15, - ) + try: + # Require that the doublet scores are the same whether simulation is via + # the main function or manually provided + assert_allclose( + adata_scrublet_manual_sim.obs["doublet_score"], + adata_scrublet_auto_sim.obs["doublet_score"], + atol=1e-15, + rtol=1e-15, + ) + except AssertionError: + import zarr + + # try debugging https://github.com/scverse/scanpy/issues/3068 + cache_path = cache.mkdir("debug") + store_manual = zarr.ZipStore(cache_path / "scrublet-manual.zip", mode="w") + store_auto = zarr.ZipStore(cache_path / "scrublet-auto.zip", mode="w") + z_manual = zarr.zeros( + adata_scrublet_manual_sim.shape[0], chunks=10, store=store_manual + ) + z_auto = zarr.zeros( + adata_scrublet_auto_sim.shape[0], chunks=10, store=store_auto + ) + z_manual[...] = adata_scrublet_manual_sim.obs["doublet_score"].values + z_auto[...] = adata_scrublet_auto_sim.obs["doublet_score"].values + + raise @pytest.fixture(scope="module") From ab6547f5c579cba05b927419d3482f36723b16d6 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Fri, 20 Sep 2024 12:06:48 +0200 Subject: [PATCH 044/118] =?UTF-8?q?Fix=20stacked=5Fviolin=E2=80=99s=20`sta?= =?UTF-8?q?ndard=5Fscale`=20parameter=20(#3243)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/release-notes/3243.bugfix.md | 1 + src/scanpy/plotting/_stacked_violin.py | 6 +++++- tests/_images/dotplot/expected.png | Bin 13522 -> 13581 bytes tests/_images/dotplot_dict/expected.png | Bin 14613 -> 14753 bytes tests/_images/matrixplot/expected.png | Bin 5623 -> 5577 bytes tests/_images/matrixplot2/expected.png | Bin 7482 -> 7465 bytes .../matrixplot_std_scale_group/expected.png | Bin 6888 -> 6878 bytes tests/_images/stacked_violin/expected.png | Bin 8000 -> 8043 bytes .../stacked_violin_no_cat_obs/expected.png | Bin 13374 -> 13343 bytes .../expected.png | Bin 8440 -> 9009 bytes .../expected.png | Bin 9478 -> 9526 bytes tests/test_plotting.py | 15 +++++++++------ 12 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 docs/release-notes/3243.bugfix.md diff --git a/docs/release-notes/3243.bugfix.md b/docs/release-notes/3243.bugfix.md new file mode 100644 index 0000000000..5aa6063b1e --- /dev/null +++ b/docs/release-notes/3243.bugfix.md @@ -0,0 +1 @@ +Accept `'group'` instead of `'obs'` for `standard_scale` parameter in {func}`~scanpy.pl.stacked_violin` {smaller}`P Angerer` diff --git a/src/scanpy/plotting/_stacked_violin.py b/src/scanpy/plotting/_stacked_violin.py index 862bf76098..f2b4a1696b 100644 --- a/src/scanpy/plotting/_stacked_violin.py +++ b/src/scanpy/plotting/_stacked_violin.py @@ -222,6 +222,10 @@ def __init__( ) if standard_scale == "obs": + standard_scale = "group" + msg = "`standard_scale='obs'` is deprecated, use `standard_scale='group'` instead" + warnings.warn(msg, FutureWarning) + if standard_scale == "group": self.obs_tidy = self.obs_tidy.sub(self.obs_tidy.min(1), axis=0) self.obs_tidy = self.obs_tidy.div(self.obs_tidy.max(1), axis=0).fillna(0) elif standard_scale == "var": @@ -680,7 +684,7 @@ def stacked_violin( gene_symbols: str | None = None, var_group_positions: Sequence[tuple[int, int]] | None = None, var_group_labels: Sequence[str] | None = None, - standard_scale: Literal["var", "obs"] | None = None, + standard_scale: Literal["var", "group"] | None = None, var_group_rotation: float | None = None, layer: str | None = None, stripplot: bool = StackedViolin.DEFAULT_STRIPPLOT, diff --git a/tests/_images/dotplot/expected.png b/tests/_images/dotplot/expected.png index ea54ae3447b9bc422597bef934aa4f1daf849bda..9c4b822369debbebeefbb566ea834406e5a24026 100644 GIT binary patch literal 13581 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 literal 13522 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 E0R%UY2mk;8 literal 14613 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 PQG}BclNT)$*7y5gpGZJ6 diff --git a/tests/_images/matrixplot/expected.png b/tests/_images/matrixplot/expected.png index 216626af46924a32906da451345f493007051cd0..cb2421ba028572646bac2d775ab1a4d5dead7451 100644 GIT binary patch literal 5577 zcmcgwhc{en*Owv@T;*!fuM+M=3t@(d7K9Kz(R=SRTJ#`S5Q&l~QD*cOy+s`i(R)Oc z!4O@HE_!<(_gn9`zQ5pGYtEdtX3lxeKF{92vUh~0y3!w{Or%6aM1LqhRnP|K3veJv zZh`OH+ogYklZ59Jeb47eTTgEbcN-!#3r|;Pq^Glk^(hQ zJ>Wt@F8_OhAky7Vh(rAb4lHuV^{Ige5z#H)tK*v5i-|5GB08wD!s8b{=ncHTYy5sw z*UsULcNMBH_9j(5@3dTbJ4W}EmJ+mu%3zWJ|fc1-)U4-yQ!$mppH zh#hRi4QZ($w`uRmhPl_VaK15@m6N-^sJMy3zdDczYIknCH+S2*%HrTO#e!t6YG`jN zHNZQ460hKR-KV^ z{mBpO@CZ@0?8Zj4MO)a%j~^d z9xo*t)VXqC&o_{6^~S~xo)NGaAFjHxmxM95#cpa(la){g)4v`)LfQ0v+UYa9h@F_2 zc+gCm#rIL;OkLB!pr<{8rl+@;lb1KVxR{@mlr%}ihP0=r=WGKRWVQXXHIhv#<;i<` zEhD48&sy2~U+k%Kb93!eI){QTJo3~~of(fqTrqfBdiqMwU)r{V=$_>PRLJSc>Fnho zp$x08qC)EH>wC3Gf4?fk&y5&zrate5shHZR!*BjP)GamciDZ1}3Qr}vOCI*~@*WS5 z>5flGYw$RsW6Ay6Pgn5=cge+5)tQ)?LnPvQZc?2E5?n}!e0DgA zw6wGukLKTxFN&%ybTF7%cSWYCk}E1nayf$ zmiD3LXy5N%G`(xU|H&wDz1W~?GNA2476Xhk{YXyXFNrP&&g;r^WYn*7wnN{_YG3{K ze`>_+EeUt1kiyN_um8W7SyLPmMS4B5^)A+~Nw2yU(pnZTfK<(xVbJV_7xSc$o8}ge zA{8*7KM}8rWhndhCoCbD2x7U#1GZTOrOFVe3e=8RLDaPtdl9N_g5%WYa*pzIW{=1b zb$J&$F)^`TE9y+@gRd}*)vtZC%Yt~k*zpbLF)|h0y;G6nbh#L9ud{D=qftYD+uSyF z)jnq@Rxt>!#zb4ze&Vw+3%XFISbxz+!JPbb^T0|4CmrIi9WbAzP2WPdl~Ggt7&3J@ z%e%K9>X^HZR^~F;+kM!(K$XcAej=xk@gZP7==ZQvd}89mfFoBC5fQlxGLCi^66Lvc z=~pR?4{ghB`sjQ6P?RPkBO?$2fqPO?tifnBT65iyB=axs&@u<6j*gDihCu*4g9=OH zL_w4Joi29Dj?H$~<>Qs~{L)eiqVTrIy1KeaO0>Rm+DC!d^f+D(%i5`H-QC^h3!PCD z&Nb%C&8M4W9i<(t=D)t@ww9#>%s+_cb`QF<9y>m ze-N}Vsx5FylVm4Vy&lc`L`Y%$&x3bgnACFWe!vgcm`+33%HpG74&?76w0hz9&68m2 z5JDl$A{{CVA#<(IBuz~F93Qo5ku%$kiLb1&=eqITkI%;Bj+XwqZZ3Z?&XzN?%rM`K zmP!6kV->^~~G z#n6l)u~|MoK0^5&>3X>g!SzrfP9sZ8&a$Qh!*J(krBt8eKACWEYIc(bfo)q{TKbrn z*wq=uEMLvc(JnxO%M5gIfQ*igCJopEWOw)Ua6qA-;^S#$4ZT81@;{_4Fq7YkROD(X ztwPR92c8qm!ri^+DcoN6m97SG2%Lqp`H_UQwiN0Vt@ELHevRHdfwL70Lu{)rUl?_dZ0$YV_$Z$1JZf{}R7Op^_qsWG z24Crb#C-FfnGToT3_K&gWR32bP6T*L+h$CrId(EDsemSI zdq4451!vmkr@1@pSW-zuCzVyu{CNz1Hgl=#=3N$|f`gmEwdkwIHwc%^t!qNr@s&h_ z`efBM`zko4N>3L2WoCR-RpI&O8xkprAOEEn_?K;%^F+(9k$hZ*m68%dmt?pV{+k8+ zotOf!hD46*EBbSnh&$ju&##9$z<9`esaCDpj;N~bru2(0&EqY?_0fdB4 zP8x1D5Cl&SHu~y4R^aY>^AuwZHiwS8kM>iu+wAt)eHW?e1q>C`)c(j;jLHhSya4U57X0 zoGAn=Ay=T_Ox%0(R@P!`x(Z%Qj`9AWJ!TIZ_K@|?b$$V3ZtJ|qXTv(IyHq@C!!cG; zQ^+4YY@4I!E(*tj~MJghc! z!|W6i^Z1SK1ljD=Di`w7A-DL{*3hf#UYs|L0H*NYjKt;#mK{%^>~Sxl zM!u;zZZtussOIN?m|6uJnvv^1OVF}|Neb(_eGMum7$dcJ=0cekqXy2IkYEYJOw@mpfne|v1ob$pk ziaFA5HJ=I&4-ZS8tY%;3!Jx{v!et72i~MeIhvnS&+-IsOq7fR>$8SI++FDwVK_%dD zIBs5E58zgSY%)p*h|}<>k{s_*{tr08zl)2Dn)>?PM#!cP5OBz4dR!cr3x>1UkUoTX zqQ-?eA|e7rs%2mhF}t<0I-K3!-u}RCUSW3+73AXI_ep@8hsS;G2V{O>;dr-C$PJ## z&CUJ5x|^!Eua8mGo(cs+=GhIU1)Ofw68-q`gNo$l=MtB+Ey(@*^HoFARx^#hEO5`a zm6amPL+L{xZ1_^W_vC#H*bckn-6e8%K^n=An`@u&uGPP4_-|pnHVnha8Rg{VZ)7XQ z*b>G{>{G&Kx4LYrETE`6H&e>`b8>Ptjf|c-I^M^4Z}CV-BzJZyQm}~2YH3lQpC0nw zzyD6ys?&A#8;7>G_Jd?qQ86(sef_7{!1JRnnUry%yCCEuy)qs+94?;s36`Zv_@d)A z>$}1lM#0K-CgXsMGS;hI56f1o-M1_k=xZJyA7AiQhY?36=0zHm}fss-{N#(|`7qjs86`V6``QXvz&sM4?bqVTQRKpYo|oU!hL3 zvv~#%zfQe1@X)frf8;#H)bnYG;tJ01O=V@38V~#}C>YItdDJyNP0_qR_(gdcWHX4Hsm7vxC_igMq# zp=4(pv^!@BcRSv-$x~15?P3p#EF~PB2M(q_3h%JA7%MgafZ*vL zT2ukFjHUmnouCA9+F5&%z$duGg3N2wFKMdn3RYMu7VFJI6TjWu$ZaURvO)eW0j7{C z+6UT(1vMt9Q90!(L;98#F|Cn|14XymJ{4bs5N+L&GHj%uoe2iZ3PlNsFCc2CAbfn; zb#+OAGykNcdjhI02*}rtUlTct_y;;ZUDt~+ayn%LYuZjS9=YIDr+y` zz@nx;@{UEL`=t)2Z?t#}Nim>1*dKZE>lP*G6zT39EyQ@&b0t#CI7&OOo{6r5nc^l|35X-5&}(s1lUe@g8_PR$>&M=U|_rSc|}eeaft?jLlE; zdsjOfh&nm(qvzLe!E80ZZ<{keJK9;FtR~AJQ8qMWQqPYYEz+y9?)ekyJRy6yiFd=` z(K12OKKk4W;=lvC9c|CKQf8|iPJ2*-_s%)3%iDhc?j7*j)<8WZciL$hPu7Y8E>CCe zHYTgdS>f?jc0=xGM{a;=3d+jzb87)t3U=yh7$B}{YP`&Y&g01%V9SbP zvy6;tPhoOnOnEEpK%4gCwF?K*6_d9u#YX8gUYcuEi?|!5SXfv%QE5Y_A#*Our(2u> zq6ZrL+{|pK`y-c|IE$WY0Pr!pySqse9z2BcvMz#4GXpx{`+NFvC)|d!pgg}@-saun z=;bW$iD4J|>l9=u18;0$nYbu>U9J>-ur2Yx0e)7OB;Zh~O0Ff3rhIj^hUivNSPxT+ z<-S$b$=gcs@rkH_&WXUN?Hsr}r{7L#YoH5WBY3!Wc-}sggT=8kIO;t|jEjZN0Sb@mBHS$pFLlCmChI;5! zTDj@Qa=l8NHFpJSQo_{uIZ>SQ#yDA47CHCt2%TQIrE@PX$>+9d2fyqK*dzL)$v&2E zma@+Y&@ag@zg>%(5W?zwQsiqZ(TFnYa5a~HEhyO?DYTsL`-Zy)-Pj`HL z9C=qbOTH!%g(CZAF-6w5)Hvw1Px-jdMtZadi|X+Xb=G54(qr@x2Ro}6d3ShjflxSf z=y#?2Z&m{;8*8rS17-@5W!Q_9akHRQAp02v_*F|flBZVNRI;|_XzKUtUJY_~rj?6= z6%s%#?6o=F^A9oEM5FIRrDzroF|mZNU*!->&b9kBpcRHdAROShnN1NT`1}Y2*tpZl z{9|m){b$RyrLK)x>}42ZOqV?HVE~!MMzy8*^^<+Vm5c(D&}&6B(eSd!-D|4GMWsGA z_D|`fpEqWLE?+IVY~iX_!jebwHTG6yE|U*u{52d9jZM!sS8Fa1_lPOfL9H%=wH?}WP z=*sh_`7S3ztFXrdNI(yi(N>_Hcd=z=V%qkR1Pevb@E*-k22E@xWgh2o152Bi$8-I) zEb5t1?eyK~5yca+*zz9XCdvGu>GxIzb{r&s*i6(y-$aiLD z=If=t#9EZb)2BbZv8SvJrO!1rTYk2N_-@v(l%mA$lDBGn4Y^G@Q@$O;CZz%-Sr+po zK0SR%Bk1HgXxf5KM$#u)kz_GlZNN50#Ka(B;|*?$C}eZJ#oXb>6ij@XIa$gdY8J3V z44!ufy8LActPcA6+aAEr>P#xxIX3Al`fvP#VM-nqtY(tYNsFfY^W3|aNr0#1Rr~*K zsHvHO4qXc**zV$rE4+?>BjYi9}vu;X5#?%ELF768Md3 rB4sXiVicY{$t0YxzMNrJzF?Q7nZfAzlc#{ODv|ONb%jzn^MC#WOffFg literal 5623 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 diff --git a/tests/_images/matrixplot2/expected.png b/tests/_images/matrixplot2/expected.png index b4cdc8dc02a18ff39d5879512576bec60214dd9c..58990e2526363224f2691b3eeb3279cd2db50422 100644 GIT binary patch literal 7465 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 KWZ@IT!2bXZuc_n! diff --git a/tests/_images/matrixplot_std_scale_group/expected.png b/tests/_images/matrixplot_std_scale_group/expected.png index 6d1970b3bb972f9aec1d1e09e63ee2060f043000..05fe80da7daadf6a428588a38e2c2871a4d9ac4e 100644 GIT binary patch literal 6878 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 BLG=It diff --git a/tests/_images/stacked_violin/expected.png b/tests/_images/stacked_violin/expected.png index 8130c0e8d829530332121cd8143bae436f338785..1cadbe8ad7a22ec5155661c09406433f1dd29358 100644 GIT binary patch literal 8043 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 CiS?5J literal 8000 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 F{{u}{c2xiX literal 13374 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 TH4c2%2TD>*PPANDKk)wmRp?DP diff --git a/tests/_images/stacked_violin_std_scale_group/expected.png b/tests/_images/stacked_violin_std_scale_group/expected.png index 963cab263ab1316ff8b0aa67ebea11da277fe98e..af4bf8948b7332bfb45e071465f9519213a6a10e 100644 GIT binary patch literal 9009 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

!QJ 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 rrP8IfzZ;C_1PWDA3_*Spe zeb%WuRkcyOHakj1Ng4?r5B|%SFG#X75^7(*fJ=Se|AdA9{NAmu`TqIC3y{VFrQqQ=VTmoKr^vJ#>i-nr+SUb%*rd5_mKwCx#LonF2Llcm;bGGgd* zG)3~*sFXLrmnS)99e80wnrU_{J1s|Go3sfXw#)ch_WPPbdYd1yG7o#cHGZD4MYFSxs}pssnYA z6jjQJ1dF-f-ai=lLM~PsLpIOqDm=UX&d!|PTYk6JZL$D?sxv_rd`wmj%DGuMSqj!2 zSqqE|dViJ(OXFS9?akS;lrY%as7F2lE@#iRvY`p*vRdz9$y6W?_3%0yn4RLAKJJ$8jB>-n)FQQmK(R6}XVOB`ssr@6{D~)QwcHn?UOaa~PT94chWkw}|0O1R)v&h{h*>9){tD^Oq^K5fl{iIMN1SpL%29;> z-?HprX~J3lzY73Ba)kb``LUBYv!-2OF6oBF>%F?F2?z;)Uyl+~C&{Q78_yWO-(Uka z3Eu75@~TF@u3H%pgZ=|>u*6|QMlfLUjVuZFY`Nar+dFgn!<%;Bn1A5G|yhq zlsH^k`lMVk>kB6rSJSsAx2~?P1|5cPSAN_3YxebTh1K?-6WIRu1pjCc{1F~$CS%@~ zV71m_%V6C1I_pW5GGN!*clDP&OW`Yf{tDOrv&{bxj?8?_ylr$}q2D`Op`t75A8`NG zbPbTW1CE#;A7&z^oV1wyUrMPXB~9`Wm3{6O6zu;;l;}`5Z}*q(c-hYxh_U`L%O`&c zsYFSDYieHm_ELA#m4|4E`|86e-tO75R!&bdS7_#EwgF{4g z7TUl&uC;;gac<*mA8jA0?6Ej`795H!g}yT(e}Df`ea;2Qe++wA!tqHs?k%5Kg^G4= zXM@YmqkQuB3k2gw@XpT8QZ?G~iHX%FO9bJ!6J=X_d!Sk4pG9@$xuqp3O-)ShEpPJe zw@WY3%*>Iz@iY2*o8$gCef>eT@f+Rh>M8&L_%kZ}o}_K$6P97*3l{+#NT!tUxE{e* z9_$wC{jceD**-ZFZx4+*<-{dO&wzp${4+;W%zu10{8;-$N|77Ws1fg-khYjF-nLHdM zIQ0`@e*QlU-!fzgvAn&#z3#vW@1$uP?K%g(tb^*}Pe?Fb72Lb+jIb1(Q&LhOzHd5F zQ&YoqZz}QS3Ef=@e>~0L;^OY6>pSh9H_sg2uR9;X2tR^VYt`}C*V_+}*_n z9uod-RUtWcf0O9w=*NYEcR*9MsW1M8PCQ+@9l`?Oupb`zF>~>x4p0X@0;Aj z{ZDTJTuvKf^z}W#<+fLR&v()EbvysC`9mZ6c1HN4ZR}u>xWJzO1T17Gx!BbX1tLEPQtGl~9k_oo{ zw+rXaPuyp5J8!{gZn6h|j%nTYPwep!f)Scdww+9R&ImrRu(5&v42DAJcs{M(_6U?s zMy8bf*>Om#juB>E;Gb?ek)9fOZxhR@bK_lIt@NqnreZTlqiASd<1c4 zXAJWV$m=#7d+{*(`gA+$;Jnds?Jqd}qWPY642Zf&If>H9rx64$hh;3`* z`W)zcyVa=RqUfzS$8r?zI@N+sg}g(7g0)0U(!}rLwzj2jb#`oo!x27pU)kFf%f0SR z-Ni=gd4>h4E0OV#}5ZOMa+A-Gbyb`z(KG00atTD#Ii96T} zxr;>QFdNXcy@r#`R7A8Ss=hE409(G0lWq`Sq-3i9(A=?auNppIDTP>(EHaOHkKY+< zF^|Jb+XaDKQ-=X3Nlv>KIYCqtZ%|4`ExN6ndax-cU!2d&Td}oo@IS(;eU|QLkNf(xLStVHzLX?LyyVb*cJ<%xT$&Q14OC~Z$>;_DLg0yR!J$XuazJtHqszOMZlW2DaMSYv`?tdQ$`+} zE7B)AQ~w>&Fu38O{yVy-4V%iXj~S$*A%2?&3p6gu;Jfr)EkB+_xo3iBE6jtBXm-2a<#zma8B6OIu9JHw>p+!t^Cd ziSDwTR>p)HQmxC7p3ah5?k3oK$Aq(VUEn-Vz`k&^u(-2_vG@DQ4RK~R3aVC&R9Lg+ zNdSNN1BSU&G7-&fzadK!6j{wmx&KJ9&6AzCv>gH?M(ZY2!~jLfIDn?Di~>{VexSi; zHyw|AsOF-pB4tI&4+$Pqa?ws7_{AA{n<-$xR) zLsOw-(ISr`D$m;*J2wQO8lpLEq44Fb30P){{w*pJsT+;wGs!2h zn3H#nRae5a&Xv@dMv8&sG2~XWT04csph8)iKG%O3PHW#4Xg?D5e~iEUVmFGPC(Su5R?%Q{OY3(39IV+y7fitzAH?lx<3VHA;cr@H0S=b_ z71G0!u5@Z@pkEi~_$?KyC;Pi)_U}VMarLRJAol<0HK-*(wBQoeF1~QtiqsTC!od@) z{Htfm+p|+!^axnQCm9=03+-@Ope?jr;kWj%AY3|m80q7O6&g;mg9>)Y+rm=N^rc?Z z-I5zwirFHxInO!m`8@{jo9DgOxWf8naiHmUA4XJWInq%F1l?%l{^<5Nu~(8dYmx=1B`iBs7R~$0L1Z`*jr+%;P4uQ8!?vihGfDB0{Ps`y06hzU)}V6AXD4S z+^{h+BsbA_Xhfx&lA1KS74b=QZx8D3LS7SqY3G2SaI9PqA3uFT-c%&&b7bqq7gsEF zc;tgT{SLt>srP}`5`WZ?dn*sQ`V_Q8T?CjT_D?(L%aAQMPXw@^dL|O8$aJcgnkiAN z{&YlR0l@vr8^BCIp1{h)Lz&yXV^xF&M{Qqepr8;V0(1Qtk;JZ`IY>gnufne77Rv$F zotIlEu~DyrjuF}AQNv1IwnT%aI-HTD;szkdbCR+C>FS0~{@=&=RgMbD$o7@rmujw1 zr>|%lV1|&qMTK+_uYX7TcW%0!EJrWFqN4?Ix&~C7Q#)^?y)V+R>iVpp>lvKQ-d8OF zUeHMnY(AYzc%JvJyJaap?=$+HHz~KPJ$)(BpnzoBurZNX+h%y3=AxK{fW2=7PBWQ& zxZz4&_Vl5CG%n?6>|{P_v6-i03zSWHWcReoi8qglv0|wJl>4??9f(>UNKA3;6V4`9 z$Rsh|*rdk2j6IrYBtkUF4ArEulw#PbSZReKTQb$Dpiz~ds9APMWYy?C#bSCcX2)c* z($Q^W@KqPf{yPN=Id7=Q+d|ppkmWX57AZvOrhFSQ*EGE$nxhLZ0q*8{dfq z-*RE-%O5#h3d2H~_+%9VM7q_36$Wps+>mt5D3gx4WH1|j*^)uMBapii=^_SOCxrwO0wf zzc=kY( z32$8qY=N0nedAzDiOY&lOMr3s04uc(6M(E?wnPQRAJ!5p( zkms}GQa4HH&B|7tOB}wKh4I~+2BjMQq!Qt?En}Ye$!StiGA3qOFGI3iIH=~SCRAO* z*}nYi7g(%r?%%)5#@6qzPpKIhfjb@?d18o|y+@iORFV-?PMs9WFh#{ zQllqvq);^yw`>P-V-|VcknLCdBs@uy*rL|LZ*JdnH~CDJ>F?3-{k2e@qzDAbn8aoDt?Qc1|E8HU`{AN?q$Vl>AiEC+RQYiJQ@4b4{U$oVN)Rf^d* zx&DUc-bej6J^vZ zbD$%n#f)?UAIM9W#Gsh6O*#K*oH0M#dSAF-ua)n#q^j&0h@OAw0=?O;TAsbNk6woksgUTT#Vir zZ2@J`^J`P#WP-d%$ae_$85r0vah8w#{yPUHMX7YFJ^pMz%8|V;!Gh}Z*q5X#x%mUs z?=XoL+fO83bq40qt8gcdhQ);Y02VZyItvTZYFjmC=qXZ}s2oyN4YP*vJr*8U(#QhW zc`_^~HqI~eVwmYV}>p!3v_MR3mrq)}xW6ttIILg!)Lxe(g|<%6;{7gu!>pr6 zVxv8*xRDuqcxDf0Ou2i=F@Lp9-eLJq_ZR&m=318*9O~Pt3gW^_b57yMf`XJw zT%KKQ)r%bp7w0$ww949A!Ua7@my6cro0Njr(4wNEufE?FB4TZzv`_dyx`&b8d3OpP z>X-+FQC{6iy_m$dK6Nqc#;RS0@-!arT2ric1M-{WKKD+W#l*uIMq0TO-owC{9As6rsmuvmciSUeAH^~5Wrq&$8cnLxJenol9=dU- zv{5zDjO8d*h(=cor`v{Q>E48S0Sb!09)H=Njr~Y^+?_yiT|K69>UvnF=ziX+$jN_* z|1ZAy^ak}ZJ8&UvKfQarZhu(mXf#Ln6+)2zV6PziiQrfDbk`(xx$Qw|{65avb2sZt z#heveche_`Io0xTxHx*tkY!XMu@!KzJoxtkK zfq&t?l0%zcm9N>RrNylz|0i89r`|LRAUqlWME(+3LMx++un9$`*^S_B+LkflMTMJ< zU)BQ*&SoFFw1D%;d*V=#XR%ilBF6^oZ>fx!C?=nZK`aTei-()Z!-cL1!GWaJ?g}BwFr5Q$>q)V?)Wjxxyaw;-P|Qf#_9-|!*)5MDZWmq z(wu%5T*%XK!hD*#!|E%E-)T9B<4rHVzqZ>UvbqZEqlMoJfC0<-`F(S$lqqP}2h7Uh zPolxR+|)gu=aIE~wk+AGgqkM#V>?#U?^hn|I(IZXtBM+xpT~V6H_jI`imll|q zFe9RHB-_WCA?eGekNmmvYAzZaPR{3%Q$-{{hZHwiu^d>oE^~Lwwnf77rK)J~uwp;O z%Cf=@t_<<_;eyZJK%7Ki`PGHEo{NFmM-1*VGl5^3UMtY*M9JNPa^s-MHE}O(dj6`Oju%qrV$Y zc+l39SIhHuFuLF$@faA}Lu@qqx+jtHJQl=|_Z4Wp`)?tyeXw8=c`bIpyd{?d=?0HZ z@7j*<36Lds1zx!7?pGA+zJ)T6!Q+R?VdYnI@^#-*Lo)AR&!N3vE>6WMes+;qkS*KHxg*>cMSr^F?*$A8^6`>4Ed zN1eqjkc=8$@qZqujrWU{4F?xDdLFzV_Sv^SLqxs||Mc_{6FN}JRCiG~q4?DoFbrwl zmoB>w$2o93$Tim3`P?E=*P8+i) z4dY^^rJ&Ytc^~fYoc?*KjuJb~`X3&4id^(22NL+%?F|_^e^8WcEb1%@{z!Gs1a$5_ zB4fx_Kc2Y>1P-*=uG!FDOuVg|lql-YJ*ly*YoVn(L;LS`3RF%>QNwu_6SRnmKdUWg z&!Jc0;!G=2HYy2q*AiMNCxvD_-5hL(OoEFvlGz5NhA2sf9dVMsbbU`slGTM8|7z>$ z3u#4V4oQgotty^GOa>ip#Gl6yu8IsdTW}|yM+U^V8=G@u0Ji+JkhR-Q6mbq^;!QF+ z9+6LuOCXX6We`4HX+yf5Ry=A-Ia7<)6r3vc*E7x@ok^%%I;q8c}uw}r|A?HB~YoQ^vfeuGXjSWNI6mLtH!m$-^ zr$AdkZpx!er+Ca$6{97tV%WjZpdg8k`^Kr5Paleb*~rg^6AcA9mcBo?Nop$q^AG$r5QP>Zw9f5+hR_ZHAU; z&N?qHS}DM4J@%jA_JXReWRk5MIe!GX#wyzoVwS>)SQ6!c(ytMpXV1Q7vhj*?WphPo zVo4ulf~Lv7Y1Cz<`U7tM)5noy-i_^!1bO(0V_4}qj1b$-)t;{AnC|I<>5txy2!5u5 zfeA*##RH2<$9qmzV ztf{@MXHPqNe~C22kR*(wbPN@JRtVA5FETcwY!pdNF=$d|5_#xlqDd}M;T8HOvoP@u zG9z@!mI?dut2lqFyldH@B*vfVh5XpsTWyeU|bW?c#eyNPLh~$GL ztAg-TIMA%fkc2ReJw^Lg3l)2aAY+QA*tC~(MsB?}jA3DzKtcdJ5N?>a=xisl+Lq;@ zY06`1sYfDiE}xCdbQ~4^D1jsyR!XW`MfZC0sWvY3r|-ED8doPd!5*7uuTOQ4FQl2` z*f0hX=3o#$WRSo*f;1SPr{{wDmNbLXH<$f=QEN)Y8ZDMLoo9SbW1kz zV+s#cwn+LkZIz+y=!|Fjptb|Hz^xTo2I|58;U~%k+w?2ko#ZTgS<2u1__UnBC2KB+qBGB^Ui z4i3d^BLkoGISZ~iZ_X;HUE>443vMz=K*$|H_OEBoAn`hWI~uUv(3>4ozZhQB368Zx ze=$=!?0$Y6sH5GuT$>8~@S(zf(pz0Q1&ZSJC+!R@%Riou3M)%aef#3(_a3fd?UQc3@U?8N~@d;{AhI zycvXT{_5+F%k6#kc)xFb&1#FHe8pHng?aEJbWjnSFf&gVg97WNzSvri`qu0FLQXL` zrC9=;MRc-8d$fcV6m9*4X{iD^zs&&IS?MO8U4KTpTM#W0dgCe>!BjwUr)#n+c3X#p zblp%3vJN{CH2fFqlp0O}S8a?(9dOL+?dLyK5v$gbB>!@hT1gY?beEfcP$ zs(mjCZ$sJxEid|hg6ydZ`coe|6%Yfd42_c|i<5N_%b@vN%A?r;(Yt=mz~9vihpQR# z7(^uuPslfe-}d|1Ct2TE17QO3bH~A5zi(yc6jG?}6CTp`hR=Anxhj8{Io)3##_2#o zoxrM%7m9++e>7*+*Zal|90$#@Y5nuzv|2D2JyQiHP5q`k;NV+jnFwj07I%-rWVI1( zsXR}=N%9rAn^I6|1xjw~n%=CPJN$i)q(?3-4J~tvgqnh{pKNuTBMK|RH9ZU`Kk$*7 zHGp3-Lb>+wH|SF*{bovCW|$Ibq#@xuM~JhUrZCkjl1cRi!2%!RV;|E+?rij3Rq+t7V8EePRSN%bJ9H>`C~RrKBDXEqA`@ zX(EuqPBd{g7Dd20%Q4Ft+y3@(cJbE%0n4?vIcR%mdRKl#DnELWP5Y`$*==E^Jq{ZW zAH{=!+4Gm$?hC=oAyd(6rh<;^LjHw>lUK7}c-+Q?QMeTqYWL=O%Rxx#F6>0C24$uZ z^Y!34!$$Y*Nv%Q(_Ai=7nB(iQ#k*6$41((ua@yn`GF5xb-Qz&;2nJ=OhaR(Lo+e&;cWdm-|DB04Al_LSV`#Y9d9H3#;434lh4;+A|@eI%4qE%}D5D zmUXfOQ^-m>1@K!BCu!c{_)LhExcxKqY4({_5l;dO{^4_B`TClqR5!CaH7!H5x`mOF zhH(Zh|J3A6{6WYQQ?Ci--Q-S%Kv#TceG^$K$uueV=jec-Pn~zNUivf7q}X&Rj7l{< zPYNBe4f^)c!XvUYaY zRqz^?v1h{j8n&?q|K}wr=J9!vi^xfDyh+x7v4Uz>6T{AtR*TO1*3$l~vG22Pe#br+ zq^JnG~&qB#!*FE=>_pbV{LlW@(;=xYW(a{rze z5)}2RP)L}FnMfzAZjBtsQmxyv0yY7Jf9sdeYSrx^9qtT}XeAe$D3by+U}&2I6W;BY z8Vh%vAVr6MieMmbB(%UtJxy7E3>vDVJFH-uB^y%a0%}fXZvv0!g8wq+ac@>L>;{oWSI=3QZ_Dz+OR}LB!1hbgz1pyZS$Dk z$}=G#0JA=Zg^tjRKz6`~(N6(D8XleGvrRL}{t-Ju?^9hJs3*^G&*+cSoLklKHN%Mt z;JS4F^qEKKhQTB!f*%Pa3&rKHO<71qjBWLY6pag6T`b`kpq80fBlo7LG2q1oOOj`m z?5$pzZaaikds66f0;gWz*a)HUwo*q@HNdx9z;3)Sntf!Gb?vK8s^Zk=%}Fnk8Z)~8 zU>VQs)Ce+wUMM|d3iu5_+-T||_E_Ivfz}XBvV9tamcug0*s-CwGGoV0L+J9M zoN(C2Gl;i)Adjp(bxOzh`LLakr8f=og@CT_xkrT-Vz-t5uG4uPbX; zMOwjYSS&+}u65AJC880*Lh&^$gs(TD3GI5^O8{XI?TyTsCr&^Mkw=hxA2oZo)x@&}=! zu`b7$v;MFu+0^LgU@%*rQwEeYyqh4jbEcDimv(Na#&0goR%i z%Ih9jH1L=E1X<n{Ea5qaM^E*5NZ`aBK}Vk2d4-=P{0_EOZ?zgI^<2rPEw z$YWz(yO<+*F=maNK64#1GL;MCiY`i6@os7y9>hNN$~}M!45G?LDDZ5{+HQ<19r>2G zbscA=QdAgQjgjvzX&9L1i6n_>rlf4L1FSBWZ5Ug2QD8%BptFG@_VgvzY>SsktGo+? zH5N#qX2FhIs@>bA*$g`~xuu5&{nsxM$;IzmUr?Nl#rsw!CxXW)E#cm^k|!{Kp!&HB z9wdVqniTAr6`>wEYYNrLNBA&q1A7K2-XygMQhLrW@eg`rsf!bmKE;=*(jObXDsL*_ z%yLadu#?zDPSS;|L)A15k=!`etPJgkGsuj{zGgr7)$N&_b-rr6<<-FG(q?yh_4e_t z-0|BtBS!l!K3aE6(3#BEE*z?}ob05dEX6 z!#+m+4*Mp0wFIUl-g~O z&bV#ZQ479d$@$}wiK0aqiffaak99b*2vF=)&qlQzTVR7I)J*0)EFjTEz}{I(>gPfWI0^!Ma5h_s|>~9u8&^+Jcwm3{PnS|pTa(_G;~rRoedxl zcDd2R%wN@=DK#LjerR<++gsge_n>c|$(q1dbkz9$GK-j3r;=IrD^20%CI0cPZ)Mwc zEUa|?4AvIYX57=j4(@FL8MYKH1&D#?kHZ=w6d|G{Q973{sj5b9;<}SgLEwphFm}*E z59>3ilN%!&1^0UY6q-hY@a-s;*GeG8R9qQbUBJkw_d~bk&}z>Xw_e}8L7Jl9fPB7a zpDszY1pJu94{@)TPZtUu0*L&Zm ziBgoWN1Y)fLQ05Aiw@F{R^D$+inviKovliwidG3qf8d`Tw~$pFG)YGKEuUhZ8PSwK!eT_knryjaOQ5 z%MaK6`rC!_3QD(kd3LwA*=of8p6zEwFHSg^93uIWj|maEGOtb#@ybCgap*;fG8_Gw z8uZ@GeuJTcxdpkWDj0-YC@Pm)sYeJHCw4+jGV8fa@@HmTr3*vVKTU1B4Q2S<#;8odeeY~-Py zE8 z!-7yJR~LO+YHp#l6-P*)_heEE{sKEG{-Sh)H*XGr;t2}U1ne}X?>1`1(;i(Q0(UCv zdqxhzt-8#6F)F^68fXDjf7Tw;IMV4BD|HzD%u!**V_Ugk>p~o<48_j7XGqc&hZl#y zI;W#qee&L*cDm93pPY!QpBLpj4JUi{ukR^3IVe)CM-E@CtO$?ocfE`}clt31*QnR| z`u@g-?|{b)mCEo7)uUC6CP7jThB~PG-Bevv43*+j(WCW4Oww>5IIf5o-t4G|R+f@Yy&frs3zlbuQm)SVrHg3Ptt9hQCL zRbb4`y>Q{`SZYl}h_nNGCrM# zB709)L#xa#ryv8-(W+y>{a~k5sE`vyUT>l1@{CyC^zyTz z>ia>zruc}P!@Vi8ftFBYNZwD6iq^!gJu(8E*W=lZ zf~5ay13m$GZqD&>(9gCnHO(gXykVym@Xel9%`1DSn7QwM@^($thETG~_*v;7scg5% z!@>2#$*E1+yJd4Hn=GiSP{xN%X<(k$AYj6b;-q#~lQT~;oNmucl!fB6#q9V(b=tQwSA`I8&f#L(VC_y=W z1F{L)q!6hWm2As^yb3A84Jt_;XV7nc;TIg_mlYq7UU&G@J##@>v%N)dE2p_1nNrS> z&32zZBskcYwY4=RH%A33@7JO@1J@T`2YG8&P&!%Nr>m>>KvQRx(uYTwdum*Q3*m-C z4~bvMaM&yZcWB%pxn^m@KwuSgm>LHPfIF!w+xWAYK!nHJQrj2*b zKS6w`y)vHoc)Ru}pR6(kNE3RB53H3WHLd(uOl}#Ku+k|3l;vW`*v@Bvr_3UiPsh=a zsOrVNx8+K99yy$Ila432SQ^cT9m+(l8kn(v-pzqk5&{hYy zm~K4)j-75AF4RMD*UQzX6x*2&udUnI94|4lm#&J|%2+n4)r!k!7ohd@sENav2qsnb zTOzsW)X)Ztk-963z(hsM8T3o--wFEOHt~^%J>*AG?H^i95r%QUd4AW(9RJC+UwntrBHm8BR`roic@Kb~J4 zm1rvu_}qgdRzLu)fW;>k8Vwe!GPq=1t0L-92QBcyk>QaCiL!E^FAXRg&Y}mnA_4_H$I|p4HCY zUfC^9p&TNY312$^09Mb~j{abkVrw(RwK5Y49_AUwHK3GM#FjjJtp^1VCy9#f7bxh< z6|*u_n<&fZ`}@#iW==k!lN)r848QzqfpSb?y7CSI{XJGn3S%}|c5f4mW&&TE5Xw-5 z$Dt+K1wPJz)qEXL)%Bb%*^~aeRH;D~{n)g_9)}t)x$Y|(<0Dkubi*_S%3T!KjYX1% zC{z5}kB%yMT~A#`r>mgOu`ZYphV2%V(VwWGzaFKUAr6KWhRHvsY3}T>ZlqHnbHYsq zQeBs?HR3PSS8bDUY7M*76?3@avRZ#RIC1CE^%%iSFx6WQkMkYO8%T9YWm5%L~JErLkOcD&4e; zy>p#tF`0kbPmBC}<#rYF=-;Up(k4L=?F2A6_M6?RveL=={8X)Yn%uyMq%hDwIEDaZi9WwWo$z z5a(^vx&xbo^*^4d0v>+a3Eiep_T1bMl`AomeU)`zrOs&J$tPXDlHx{`fNWdzYVy%1 zulw~fMhMp=ou(@l3OrY-%`HCA)!XHpQ~chh}K+T5HpCM$ zJrw-*>(kebHNm0hOPn-4=wGO|ck4O?iZ{iZQ=>290?ZvcHMBh)^(plX{NY*)>O5`A zmKBm_kT6RTx_#exlPS>P!#Yl@s+By`6v|l*nDD&#YnuUTt~yp!wF)wyQm+LJ3>dE*kQB*NPWKc$6zO+2L(7aH{}?T*sT+x4?v z`-w*{c~~%n@#L?KKiYHUXR7wzw;7J&he%K?{W^z|iiYh*%W)KBEp&1k{zOSc3S&KW zmN1XeD{*i0SU)#vUScF%sQzn;yjDkqO)P@P6yGS(iH_kH$Bl3F6TnTV0}9`Lk9i$6om~h z_PSkqncd$zv?Ab%W4RJSz|O<{LM4<6D3@QiJ5sp$S?@&X}+v;MiUm?VKO;y2CnG5(Z|?l!_s;9zb`MeQ!`X}$|ZPw zKDJ;o1C)ILt7@~{@)YO{4zawjn zNMd!cFJkLuEfyswOFp|<+703^9d>uva15ONR+_exWj|;#<3_Zbc%95L7JP>&*qgez z^7`D$go+m-k4**#Pa9Xgw-FM2B~5PPDOafD%9SYG8mn`dTD3{xhZ3H2L&cPq#N(WCc2PFrMR|CR6=84)q}`~i2_ z>AZ?ME?mWgo5O-n{)(YXXg4ZUJePrQIb*^}=VC>SD6qQZ5w1o8w2gqRq!_%3hq&sHX&B!3Akx8@~T#2P{fmTDsDCO3ez z>gqBF(su%c)YxERcp4J|^>>i0e6brG50LQq^IFO=7AwQ;U@fSTm;m|W>Hzjz{|qwt zukr@(eQqe&x!h^3>ksUHYH0RLTuDhDY_w3)y=fu>lG=fZ^3ypZ@rOiAS)Wync=lS0 ztVidvH9kJv#GM}3MNz-Da)J_+VwHY-$?Mgk+R6{pJ;}R)U1+$BOIhpE3h>4)P;zC;>(g`)8iV_5>G2*}& zMK~AGZPl-EAwmFIWT;XkN>nv8B{3v(m8hNC@nw_a&qfZW%qy$ps8U21I2f8@hwbuI zR!0V0m$J)?s_3e!iqH74VxX#jMbku&8g91}Q>V#&KL6Zlt$K~C4zR&4g9*2XFKCiU zZFQz?l3g9IJtsA*>(d@b(*zGwGw=TXG|_S{G=m3OWe1p+31<(*13di8Txwjsp%M&= zY}v&QYD7?FeNlbAtZKGleL*Dg9{jR@A%C*C=tDh2Wvw#ec0nQxN6U#}gXE5Fl0`Pi z)K)9zLnJJvij32<{HJToqwRTG&0jP;^(dq=j01S}+ns(BzwZ*$(9!KBNfYs2vcX7` z^>oz5_o)yI+T-KKNzX0dvUwsj)fLNQ-LEiU9AT)k*Fq!ZwY>oiT;4TauUy+xmNYKc z+k@z%%m4gb;y!k`Ai*FaO;SbMBYA`}(D7c%8%@o2E1tv9s*aO$Ms9XXF!1qNP=Tqc zo7>=(F#iZ3^8Jg;Ho&r58Ch9Ai-|i&x8ugUqSu6ZiYz+ z7~z8pmDX*4@YwSQR-TZyap^Y7;npNel~0e9=P9eC8Y>yvMs}BPx=muwM;NU^!=-h9 zbS3MUWJ(j`QxHZcrfS@khBJJpTL0sF;jr40VtZTO#8&6FI*)s$WA&ErM79f=G)ME2 z!|$_KggrLxd7Y#`x+#e(&aKn;jebrib@{!Is9LeK-#l{W^_Fw=?tLq&G9+K7WN2`# zILO;&3r&`lr8LC7m6XK9B*tb3t3e705dso3QH1H5e1>O)ViR?X%kB4~t&{LvqazM< zba8{vt(B2(XL4N~)BH*MQf3N8RBkST)l3$!$#SByvQi|u)SON@1=L`_%%oLsr0A!Q zf9*|RxSV8(n=mT=SsQ$m>&MjE+RBqR?G=XtWPybQKmV-3&*S%;U04toAfiqInczTw zGG+hv%wQNor}rwGo4Y%8D&R+zTwtKEpXZg8vLRuwpx`I3b0~_VLNZ_>`1trR=rnwf zVd{$9=;?tYlwRQQ_4Qrp^XEtU`xg-zIaz_~^KS`ck|n^2wXC_i+b&ISUVm(SjQPIr zrX2N~XI<+=W9M&;^fZs_UJqKWJzS0c2Hd3Kdc}4db=57*&W@bcddNhF!yX)Axoln> z?KAVdV|jw1Cd13IL|Q@cy6PCjzyPmy+z8dwU~nxozaW*y#+za$A-E+{V-md#DDSQa zrR8BosX99|_rL$Gzy3coomEs^UDK_T;I6^lEx5b8ySvl4dw}2;Jh;2NyE_DTX`pd} zJDh&Mf1JC%+iUdLRjYQ@oKL;JKfQmLb^In&ph-C>)icTu+(L$q;ZD?&YB(v1rr5NH z3oGsT$3b;W>xPQR(P*_3z>NU0hv27Q+iW@dft` z$#6KN`+v4|aG)AAQA!7X+bsEnU&c7vro3NEldAHWUn>_NACVij)`x}{uo6!f+gnVR zRVE(~J9IuL6t}(JHTL@v6V*t!fPu4*0d0Hp+*|(L?Ci~CCvZ)FvS+zZ z=c}iC{E zIV@GvlW|tlc^RQ8H^_W^e7qYuN^Au-ep_ce#NA(MCN$1C=YFotT>OK5Uw(p6`WQ(@N+``)~y^s`|Do%xn zMF3pAaPr%J)?*dEFl%u`ZF}@Xzvi5{Ix)H{RCpH6UcjQkIO@Rb0$F>QiN|HS~< zn)A35C@(8(;A~M z^kBuE@^%oStf}{8PHOaDyjmUX+a-xoqN2`{%rqEUN><55vHET~ z&(AyHwDTo0NX68HX>E(V%BjU!g{J=zGbop_`<(DhPitpzf$7TBXqHGh_?N0TrjN!8 z23varZzk5-I6-f0e-940@+!jUMucue3v=rT{%(%%t6kINGzj(i8aKMy(w+VA9&#ro zxoXfFDbD8wA1r=v8U=wykgTGc6Th`bhAs=ND_KLwCuuECl4n5C^Nnc!kr{zZb$kOaN@}=lhjTmlw<9wl7of%TjIJE3`SkqWXVfp{Iv0^ggZxt~Fz zTfYvtd%OoDUE;(RaLie8a{^v$z|r{pCiDU93=r(7X|zAn{CEQi5$lF4qC$cp73qAQ zj20Fa+EtpO{Un_pS0w>g+hWz~>GEONIe|GfGm1Ue(~doMF5ph4@5A}ti z^P`;anqo*`+inanHI91EKp4|7H(fQX5xVWcl6eKd70Ib~J zpXm#gYfatRR{?IgjdF6@f7b^WlAq&MF-} zxmwh6o2(hL@vYq>C|C@91wGyU-2kEwtuR$({c6+4;{(`G25mZ(!w+tz(2t>BY(JRR zX<4hM+K9!vABgU=l5!k@j!p%qxHM^rT2jB9!NV1yw3sjYb$V1m^?6sNM=J@RR_lLZC!ft}FW-wh$ozCHB_vCNx?7BGG<0#TtbTW?MhqsXtT)>| zPa1s$*POuy3o9xj8$F+DrL$U0pdFrd%#4k}+AUY@CCV}KobKe(MCtoabBL3n)wCbs z&147>r=9iXg|WDIpHP9398bMFAF0YTZe@%~6_x)rVd8Z?7_fjnJMVG!8{qJTZeVbI zD3I9n0>)x~|4uk>bnhvzK5 zpZ`OsSzJO2(EM6r>3ppLX)R%B4)WUt8t=nBtN-2;Gzp@6++1S~giK5Uc|oZ~$t-&V1uVpb*3z)LzQRH| z%ohx!b8QFi51V5jIvHsESYgPCWFQ_Z0coVEzTQJ%qp2iZA9A-_&m?=kC%&uCBVPKQ zGO2TVEa<2yDsanBr(pl91sTHp^!pdAel&i>1lkE@h%k4HeaZUT!+gtsP-uP=I^!C_ zV@`){%}y!VF6fD@)-d6HTH(U59|SfedG`l_UKg-#p)%v1_H{Er$;zrLqX=O$Ky1JJ z2p2Wm7|=#Qf0$M^O)*wOGDTwrHhGG)JkuM0Xq<~+?yDHZUSICqL6_232CvE}^p=}mku(TgB1PPyum6hL*2JPvnwMRlhVHz#>GgC(1!GW=L z#~CK?+vT8~2y~+P@To_K2ZUFAq`<>44 z?bJ(%qC)2Asm-R98VnN~vi&yNk?<=D-fw=dT5XDa4Y*Dr51=NHue0@LOZ6lCaRD{n z$0d+T4(EQtP=ta;Sq`4wp1s{8b`6#dkl&vv!% z-SzS2AP5SE(PP;BP1#s6HQ7W!+>$}&gHD$#7)Z5HN??`98n-H_ zn6O#@OIN>##$17;BG|lQ|A^jhWvQhwk$qjkMi_gqSC{tg7k+US?qtkvnN&(~m0b)j zru`^6+nxJw9YX8_o?3#60U*@w;$n5ghu@x;q933){5om$)K-Hx@C$z-H(7GiyoOD{ zK^qK#oupTR?fjbT`n0!c_XkKXboc6r4)s+AvtE`pui{A$k_lltHn=?c&nVvP$DiAVvd47p5hm#K+_4!9)4Xv-ujmft(#axDzjt+;(Lo zDCr!4>=|Hzn;yCb%L&y#2N!Gpben5Lm81d=qlW^S2oK!x{DRPG?e4;J9c+Hvz$kEo zS_7h{;+xxWY&DGnt7ackZm#y^fp3CEjS%Lyq)aU6$TGI$pM5xX{Pmiyp8Fn|ru4d17=as0iu<*%`+Hz>dD=T7k zyDs28f3~BbAQ((+dzANr6!8L6q`+?8J_r5Bn%yo#g zcql0;_5JUc!XIKsflbXVMDCwlNf}%k$!YOt(EXN;*XgqX9#gZT`Ka~U=Vh;z8Jw1# z9VJHs#0!2OBd+aE+vYvDvG|c$T0aK`g!N}bhnRaiuPDP{Mh#2(b&yl_S-xwylfv7G zE0D5gl$d?)`u5~>owxNlmDLgRWX3^cqHH;dJc*zuuVb}1bJ;+DR23+xe z`#Ogs!-ioSb`eA&3(^Ug)GvRWex|wfk*n%LGIR^8$L(o_FZCKG#rE&RH50 z)F1{PQZb|WP!d>u6(`bOTKv8ReCiyaaD34k*ahMItQT*JDWK3dKkL+rP^m{=Z5ttp zMKt-u`!F-v8&$IQIKKi={*z0V(8T&1Q1YvOdP5>Hd|Y5{@sSuO#YB6-4QVK1NcCyk zOt46tPHZccbVkLhQD-Nv$QCCR5r6sos3e}Tuy zre%}!vS<%F_^wQb10oo3ee6n>ZEI>Q70 z5;hi%9KYt?UR`$2?$6H`+X(3W{55Q#rGuTD$bF-1MV!?nRXy=tz zq*rwbruAMKCCe%la(D&;|J;wJS`q^h?V>E6^`GDYcgT8Z6i_me3roaQs1a&j-z19( zr-clBchTMg{jP-lJ||mInu>Bc9-n$0k-2jIf6CE~0Vm70_lJ$=ev|-V3k%BijZ4ju z!X}FF7%DRs)w1A}U+9*42GpI89>iK(VX7*;dV0$CWSjyre@(0`=fCk5fK^VO1sw}; z0F}^~tuO-x45gBBjBYc}zdvHm%O$`6i1DyQyL|kOC~JOKxI@@uAbdiZO-pX+$&Bur zfLEV%D%fD=#9xl8M32LYQxHcd=VgFZmHIfdCcwz&x!DD4WJucJvU|Hs5ech;US5Ac z<-C!ANl2SL5>Y;8n>c3uVm;h*>x&mf0>>LhMP{it$A&d=BLHr9MBd2D2?Uu3!?a#; zmuS`&{*Ax!fuRQOdy|>II(2tVQwd6eqt z_1B{wbP1${YN(KeRal7QqAi2GHE1K$>oxfSEhu*lUFGRL(sxe?1Xh4dnR)F}1@OSi zXJs~5DA&>dOz-WkRH(SJ^6XE*jzgodYbP2a(jY3_=)gH(b@1U`;2dz0?bL0`l5!ar zpe`o9h{RyXrzSVq<~s5Qm*&l%*b$s}dW@bIToR$Z%_)=rh5H9y@yr*URPOc`8fWvr zz%IBLTV7<9ya|D*lIXI;2*2d-I~-!va+7$Gu0GJ9fZsy$h z8t0uPJDK7gU0%_|VThz~V-oEP5&ez!F@|5nP6yiD~lCEyXZGd?S?jCZglRN~IMXrl%mE;dk75>iqm z6s8l%$&|Q=7t_kD$GEdNRduk$xB8TkH0^6jdzwGz1cPZvCdtB(gBgMtOi1!E2%>S8kprfYQ*xDFBbDmX>*8&{SpTaa-Q{AsuR?M7z zMjKb9Y+Xs!V)2a?pBx^s=Lgp_y~;M>JdM!K!{}v(2$~{AKk#tWQb{fUO#vjOE2hd$ z`cu*CS1o%SL7d?go)*N7X6!AMq3UtiHRV-*SsM0m# zRZkQ68Tmp5nUE`CRG{XSRowASdD*GZ@K2G03-ZlG>dvgmd7q2p%zO@1^!KC`>|o93 zAb1RoV94-q_8KrfA`hp zJjvo?$_0@WzcN*Pp&B+!(%3qpE31_#s5A)|`XQb~huv-b8}0YXsw8(rxu`Y)WPL;2 zztEzxB6FCMzM@0qt7qblNNe>eMm@)NP0D*F!kmJ^&sMgr`Ss53$01Tg1U1%Yw>jBnp?jZDF|gx8;aLT_wZjt zyhB3|+_i)X|3&*U?4+u8M7hD&Gmoa&nIbovJ7ZVdJ7aAQX`|k^kG!BwOqH#gU;xAG ztC*`clIre@Dgng-9MDBAu(020lO*gecQ8ZH%>4P6s9%#V5&6jV1c|x@Wwg_~K0orq z!2YgwXD|kAgfKeYT~>f2>YSQf@`Zk`O_{xB($Wt+hsxbQqa}0%fHUNpRqk|fD8gEc z`&s_XXf`3?8@P)!diCf!UYzFg@eBgqK99UV&iQLsrjWqO3-u=f!N@`06w}d}Y`|t) z0=SWc9y!EE)YY>_*aIo`(s~ zMhig1#RjJ!^jJ9fuZUl}eOuWi%9+!kXl&*!&x5~2qqas)ziS=+;y%5up@?24=>j?%aNVuw`QQyO zTioWfvto<6?H*r^gOC+2qVfE#R6+q6ml7A0U)egAnw8XlM9t9i&O)sHq4+vx>& z{e^@zW^*ZXi@j3mS18Uc>E;&)M)CXLPvCBynoYlakUvybj1`yg!;q3D)axc3;B2&@ zpu&!f`V&2Xf236%2S?;ovZ?D!$1(lf`q13&y=d+(tEZ?q74{I9abHjObYEj>#>w_P zBq$&p)OH~?sU9-K+^y~P^55(gQVBDub2flb=+z1NH`y$|fp?H{qA6HUJI=-elj}o1 zQR5IBUxTQ09DS|cTgi`B|3d~Hj73i4dE9gz^*aL7AX!-l%)n4tA#msA?c7Sp%+X-W zSJ09T3?c{$VtGwYPR^=RTme7CY!tcYI@a-DrqO3cwO$J|H@7r99wk;ZTJ&(lDA3F> zoXOsWSD7Q5u#k+=>`&RKQiV3vkvxmn^!5o90= zzMpS1_uj8Z_5TSjz)FRJCjrKQ`>psJFdR5r&mjwp>9wcKfHhgcFi%|by4Z?2wJ^WG z1SX7zjgO-}$rwkRZ;Bo%FaZZblSUcnd;&x`W{0%Qv{WH)8^*S9cTu2X{ltYH+qA-J zA6~|ZWN-e~Ot)pjy_v)w%cHRIE!-KZPg>oU)-|&asn>=#<)g7CPBmcPY#tCM_bf`! zCX3#5O2MU+w)X&L{xn<^WVpVzZMM;6`p0pv}KfV+8EET!kA$RjBlj8^ISHii;Y=^P%iL*t(N);xX)0tfe(sL|N6m$KA7ts zLpZS00_f{>@A+VETm$%B%Ngx&-p&B$!L#c{rITr_B6+I8OM}kUZaeIDZ*Tp;_j_EC%{I=cUoQy^H%@EYlo(RH8}t5R~TE< z@*|6X7J1YwpVYBk9C=y?^FD4&Q-5$~rP48EycF9i#_p$mV9so`GZFvfAmwWT`-TL= zadPr0zt-`7Nj6--0pT7O`PYeCD&<@@iWVhyHWuEfECOt!rxy$U_5c*4xAPwWN4sJh zJ&ZzGn1qCH0G;k4Uw`e1U`SI&PA))U5kquS!xzfQ-M{5($dm$n5C+-+x(c-s{5V$K zQ=r~=Hq`jr8P$1?j|P82rmO8RJ%s{F$iy5#4ULiXtT}!lA4oJ{;|}_h8))i*{IHi? zo$S+9b!vZD(%||m;hg-ILpqSdU}<^YwY)VkS~4S8^#*C;NbcK;xjR1jvts|d%fGb| zuFUi5VXd3&cl!FfHdtua`nZx+0gIofGG?z~$wyXdf*j#UTj;?>Ceh++mNBe}F-cbh zMlR~aIHq~4Bxq=L6lz62jn_N_W|Aq3_BIl-7T}DKN{64W81$?a|5*>$7mQGH{W9Sm zu?C+mkK7W4I{WEOA3c+OyWPwG6`U7Jnp0u}HwV@r2xHFU_Y;s@EYb;Y_4Ruxr;V^X z+C7Z2s*5=*VE$HF1CB7F=Ls6j+m=ecf9QO|SkhfwTN@7vd|AjZ8gpoMeI@j)b36I#nY}W0 z;gPEusUo@Hr4c2p^T)V7DT^0LX7P{V?Xqdbo^V!nEvIP$xwQ+{H|GXF*25)lprE3m z3UVk1(TnHUZwnE(Q}z`U=2iTnCx6+vQz;nl=j|mwfc5W{4s?CWO1FEugO@66=q4*2 z?q2%gq-I5jEh11WKG$udT`lheM7Bu1KUsR@JYU(^>>fUs{ug0}mEA4`yEQCpDjn>- z=6RokyDulExV+ynGsp6{Bi4I@7TFO%OX_=ADDs|0r(+Ux7h@Ho6DGqLarF*GA(=6h z(imO8Ps93?kbJ#8ZY8S{*k$_Tte4u4tA=4e2m<(BS-g?4g#^xgzRWQC*vURe(@|Y# zbLEio5mBU`4dBKmp>tS*{my#Qa~CmyoaiIJ5a~ks2}d&$G7J^ydO1h@^+3$(>-%I7 zEd{)4k#3=OH{PLCx}G^ZCiP}!AJHNUBx<52RXNdS>UF#y?Y)=tDEquG1yG)PILAQ^JHPIy4pLZYQ-yS#g?EREbz*QQzTZ-g%Unk0+|WJQHw z5-{64iCU=y4B0nll`$|NWa_;`|MBC;aYq1+jIE8$Ua8PC+~)_7n3#pWZi&-FVMv_J zdDDHtJv*E@z)N0k9=rFB5{ps)DQGsGOwq1qXyB4PbD~<`&>IkfwCz?h{19nMB?)x0pAN#! zOv6mORo?L+>OOV(Ff|Y}7&Lql6Bujw$zn>LM?G%171VTGE!6v~Vz+iY?48M~uq5S1ijs&4%ZlbK#q9MZ2KmvxWW9Dm0dEEcsV!N)y6riO zTeh1zsh<2C#;img{&5siGWU;|f^!F=^EohJJVe zGK96&wi~C&v-&+#f=PDWcy*er(Gaj1!La)@DPr$mgnS+ZvTS$Y_@_0FH1go;7Degn`6( zjHCIv_|w8Sh0cs|1d%>cAd;}`H#^ax-$<%hUwacs51JB*!-MW1lP=k~TjED;7M@>1 zTsACj$H!f+Pm~OYz=*@4CZ0x=ss6%aa{&5QcJ=1_Zbhr*z&*B$^AaXxWe~u+3@dW3 z5B0PDBNlE&1d}}#t2-i>Ia+RG%y}eTfIPaAu0-uL;3@$#pffwu%6^!ff|dzZHT`=L z^Q-;fjK%kzzk-OBK~|QCwA3NHU!$34hQ>0cn=Gc=e!xwXpqS1onKI!EnhI4)44h)3 z0>HqRpT@sYzpI=1p#kcpwW~FQ_t?Xbej};tka2M#JlFLYmOBxUW{60KWGxFPINOXq zfUa7!(f09FMF*8B4vHkXIX}wrB}r)}lj|x*KI)6#8eMq&4X(p~(;4{fI4>EPqK2a+wO@Gm?-$X{*NFmyAl7dODI_`@SAaG?w4RkLa8Y@I}w{JD@x4H_mdB zBCw+7_C=J|DQDLAVrVH$_9>F4=@;HYoe;*MB{QX{ZWFUf^cpAdFrhDJ>=U#$MzO4G zU8`GX9mU<1}I^r z%Hs)K7Uc2tVbDLuw7YgyS<=l6kR2F?KACfQ6B@kvz1m^)bgH{$8@1q@BZVJN%oHyY zk;oC7ba?uSsXI;>^x1wgyakzjdo~}Jl9@`GnX^{g^8%~C0x{7;iEH| zUo*fN*;~V5vFI0LWQ1-;Nk@QWm||Zdfg{`1=D1t&OZsN6rF(G*K3A!?ZAPX=tPS3l zCVxlNQo+0`X+x33-pMm^&+pgm!k;_;nXtjvp%hwV>9#Mm@Pga+>S_$wGaCjGO)me3 zwa4Z4FN;yztjBU=nFnvs06~}UK$B8MUu$V>r=d5vt=nTZoPs#fPvucbaXq~zcU(== zx1C$0FlnZt7NymhIX~)*_CCABN4v8jb#?cx>Vg*f5OYNdcY|wyl&3sSG2hq&-a=hC z8A&phv;!j+SaEfeV5IEp01y0@@HfK&GEF%2er#AXbATKWi9)7>DXtzIN|b7OsLDKp zX5-#3m~*}r6%E-SMXI}N97X4RlBHuN7y^YYFQLv3DVI?*dGovS+qogWg&V~iV{xy< zcv;uWod}7 zAtQL&>%aF7t?n&YkU^D# zHwi59n?%0nEb3s9uG-D*Xh6Q>PRqrwsG%&x|8 zr0fJI1nP)1Q|H!^ZntSMuM=A$zy#6Rh;kWbEj06@Wbt0#k|< zXp@uxnb1Y+h_q9W`hr5-3qoGT$04yI_R!i~w)hzxN=!~fjH&4o@rE1It5rCnB;7<_ zE9&=7120!L=?um8^Wse&Z+*};*`(*csqOGW(zrr(YP9CLKfDdY)-G|m&+X4;i8035 zV{oB57*`e>(l8w+b6DP>(GWfrvvqk=pr zq)fR57o>NVDC#KJ-HvaeExVn8%jr!6m9qe9G$k}#cr&HDq_|gS@7L!u$CcPKKZ59; z^R+%HI(Y9q^+S660e;@;>0x`BmqrQ-6)V}=nHMtZT%Dxd965u{d)=^D?1S4YkdZ(> zFdGg`5hsokBC6MpIXXHL+mIL@Zqt`Sw*A9tkEfxb5#H0r%g3klaWe@NT;4cK$;_1N zH#zILe|Ttc2k*N`@#L>u>m}Yc1g&yoH(x|SJ&(MUUfbIiTKT}O`H~H}Y%-*CMt?Uj zOZyHFwOFCT;4Slk-^xn76f>G}ILS9|awpUB75WS#8m12PJ_EalqVhJ>z$ z&b;dE%nLFev}Xb)ThRq4ya(lYi~L@YoFg~c;OEi)Z5h86(KCb!H2uwWE3|jJ1$Aly zN&Ll*f+zdbOunFLI{VoxuS_|-9<&cm)Ua2TGxqgA*vt;RlL+WKS@cJJuOByAHaHN_ z9U9`;5E?V5 zMjBS!;=bH59Mz)YB$l4}U4N&#GjsQckvgB=w-wmgA6S@C3tG9PfgfKBt}*pmTb-|R z+-c}DVK=I|U)`!yz8Xmo?X+9te%CR(dPp_oM7VlxSJ&59G_F9%XBTyJ|2kL>{o#2? z-^70RcY)BjPH3p7x|+g_*2BS;GJE3R%cT3c1SjE-9ElMBij3g5-(mAymgh+3-`h2|3UOVG*J*nrwSJOE`Zdi&o z$ZTzEyAReVN-^X3&Ei(8f#qMFkK1DYQII0LV9BsB|HQAVM2hRRS$|~khNkzA|2AHA zxSws`a)Skr;ID(Z)m1NRBbmgu%Z{^=Cee3rpV<8Ktgy#&iCPsD^UAcF=9 z3e+kB|0XH%_uqn-Kh;cTG_@c(f5stEXkHe!GDjyW6pD8VmP|TODg8KFwrLza&%JPU z2K5?6z6aB>9^ysHeCvm&&c5#6Y;}de=VDKix3n%hGbyu5&UuFb|5<2A)T{07DZL+; z9CyK(?)Kynf(W8?Avp=@{EffCbj_U91MR7ngM@CjU(_~pCv{E^Mu{N1Z2ea1{&iZc z63@zC*X@em+-oR@NVAC*|SKI~^c z$<~YX+Vp~OUcS(lvoS#>ug-`4*6I6dqXcC`KvY1FNwUl%?XQP%Eg#cGfW0Qi2t%^6 zcVv{d-N)78E8`9&!X6<5ZO^B9+qA9ZX#RUIX2$T0BoRlH`7b0GCDdLC#eqqlenF+D z!1BJ?_&jzlA+@N%!AcWHN-&Q}W z{A=~`bEEU|nC6sy54clt>g)MehL==<5fxopltdp4hr-;qR~A?Iuo7`vTuYzdN_Rgx zZyVJD30Q3tg7({H=F^=W_|9H^+4*?jM%9N*@P*yWu`9hY(6}N#5hu}K zr$SBS&viW|KdXOFUs5UM_$^bIt=5?^=(qg_<@h2mu**=Ozg@QWT3l^+gGVkfwJRI-v22_~bPk4ylLaC;Nr%l4>P!cYWeaTifGkW7#6TonM_JGq?N6ZouCD z&jYumXyIX~JAbah>`djz@4jHIpkF2EOGu{m%zB*mpw)Vap?y580r8t`97Se(Dk-tA z--4KtSD+{;OL+p?pj-ploGXK7`C%1E2_`))VT`XcRm_7uGiTyvh#@-P|bTqv^nIZ^TOw~ zBg#%h;jn$kF2*zl7DpBQtE^?*_s!@pQEEk()0Tlm65P4w>GU}7znB>+=ZVlovfU8- zRcMm@E6#>vPCcb+6M%KKIpD96biGcv$^oNBJ$2B%>}id_4s4QQmS64khjHKV*mr6t zaiCsUmS;dOqCF+SYBkkWe{09xWInOAOf%}gEMeQKQDt$1$r$c48G%dpK>sOX>+dq) z6Y)@npVWle!*Tm8ifw;;^`^{ddZG2eMT(5V6^ zN`?VT%5^AGyt*x1Y90u`?8o=G^Wv%RniI*-2Ja6RzutE>zWo>oixWlMs;dk96g>5~ z8mK7Kc4^$jh~R{tPk|K2*lo(wX0L(^`3WDDF5GI%-Qe2;r+*HQk`MIQL_%$#|uV*&Z78e)( z;m6*9V=eu^Ne0+22H?a8N7vDjrJKQ(>^@kf|2*pG7gA7AFnMZ==Egsa9Vu=Njvufv zok6b!v2!bKaIcRU5v(2i5sJKSfDCBoEh*14vM`yM%53u-SORT&NYoY zq8n4qVc;Q2oq7XPy0tZs^ujO(9mtolC=w#f!Z2twk%mo%@tRRtF!HSPf>TYT8nfO% zy?O6M`SubR7Zu>)z7t%)qm>5Jo1-`Xgn&>}W7dFLxwkkjyk%zmhprSDe-SN#UYL~p zeB<@-adi{!xnp^;(}Kz#FQP8S0vt-#jA=vKL_3$t(uOCq{(;OdfjpuWYqn?4#)AsG zyEwyNt4gh*@f^>0b(H?brBi?Czdx!w#}N^pFR&Ma+6Z4@o#aX*2#Luswvc<&8BcZCG<)hL8Ucz*;3e@ZE+`V zl=IKp$}g6zR@Tm~Md6fQkA+j(1;)JrRBAr{I z0##CkP+^aTHq+R2kYF&639ydlMbzF9JZK^ zR8(qP8~pM4DXlCLDXDS~ zIZD-m>mp1Yu;6s$Q@L7oez>qAM75{NOh8vdz~|vR`@!#Xf$ZWp{40)-L?4?%XlHyr zj2lW!J>#({!Qhk>ecox4A5TdFj!PqM#7?Q&adYkNakWRAf`wN`!CA_+>uTGLtq>u+ zvC9O10-QzS2#YDPC<`fv=J)kSEGr1`G^VOU=xt_#I-{sm{-h7rO)WC|>T<-w)bu1I znhFsw`b!=kJAYHKCy1^@p~D>kdEoo(9x1~=)_uG zSLgtOY26wA-1-oVD@4;It_Cl&wlXS7tFIs=pOjG46fA^yX>(uIfW+|quco!2#A8`i z(;HaCMXB?*%3_F@ESL|m^0NK$m2Qipin~5mk6M4W=iSo^X97*$ z*zqXMn{+xq{6(M3lXV87y-NF)3fJsr6@%v&cyWnBkOv?+)r+T%eC!RMsy^^SL_$!4d#!`6wVhlfrnF4ie?bkuJ9%gV2ib6min zJ=-%dGm86cu?0HkJk?9J1EF1Dk#@oe4y){f?rV8b-Y~V&)c@ z94aLt0fj-OSX5MWkae4w9a%sVQ&j*mG<9svRD zP5^E8ESwzJfp_3$Z8(_S9!;OGwTMRNkO{bj^Qw`e zmnQlX5hao6@^~i4ceG+a>;2@aFJL2e`T?a~aDeh5FhwA6n2k5-Ug{J#BO%Ww5J#yV zKXW>CuujcG0rz#8=5sO$`0kRXpiqUWGY-uILvN2hrsE}rGvMOEc zrj$Q>^RRR6w>5C&=u53;M;k}QziX|xWUZKyF%K8lC7OnFP)_ znpmIrsno)gS>B{Rg*|%GmUT=36;UN%ATvvY z>n1xP%J0mp;(9V+Lk}vZ^X&-1b;ZUbs+DEY_qKk19an$dSHWB~jnKC|FD#|E51pRp zZ0{;nA=7gjAu#Z!{c)NEH8$buTK}KN16;;)5bME-E8cQ|wV%Tna zsw#EsfEYZ1j0%;)nU@SO8Vr2<+uGWem6x~Y*}LEPbbEE54967EZ0W)mH6nqRCcC?H z6iRs#MDsctagK_%F>q!SqCt25wR6x(;D~S(bb}G>O{-mo9GkwL^CSC7KNwVlPhrZ7 zYe+q<1vx%BTU67Xejg`U@EvZS5y3e#X+n=~jA^1hZ`PYC09`3i!sF>JgJh z=7(^o)g-o7kgbs*?Wwuij{_dwhwE+?4sDHC{AfC7ZQd4x-BWG|7hTmhPbfqe4}hJu zC1-EO6B5Drh7a;&8WYL+AA}0C&z`Egk95Qb_bwqW(D{yvPJR3hz3b{+jcJp%6ZFQj z;|AJMIK-1dy0&_XpVla-!*K?aUBO~`sG{adXsf7fA@897>VTz#jTc!q1lsEB?=)~x zeDqZLw5CS9zq29xmKTzcKZw}Ql^b15Lmr*W^vucGnZiOYSEsFxI5=e6xLaSmjLZK$ z%BBG4i1zH=0EALA>~f79B%lLyZC^sTPfh~mK>VXrV$HT8XjDwqno}X#C0=y)8@sh~ z_npo=C|VZV)RA95JF1Sw!laBkQe?jEcVWNS=Wn`jZF_q7?19MKnizunzDlTBF_LED zd8eQ6SsH}1As~WYh^bvo_;}6-QG6@aPVGK(0hDHe<0T&Tw#{b5ensX~Z7qh<>JF+I zB|SIwVbASi(+_Rb;p-uv-sUr)67)J_J7@e}xE9sTEXu4LQSkr>Iy&J+NqsQKzKX8r zDi=eASlfG{@^BCgvy3&y!HW`zet*pvBMLO3HUPQ!=o`fp!BVs=Q2NJ+*WQ3ESiQ`l zBl(lGTY}RGEi;Q_OWdrIdLkrae;hsSNwQ1DcnyhNlMrTBJ5uC<$ZlyPgBbW$Lbks5 z%WDg(jd|$c=w|6|EgmYG@(Cp3L>ew(MWI_O=C#nS4nQB{1uW&XZlt7qJQ91#nM1npcto@opBJqRpj4^`eAYu}J|~N{h<0{#BB+IG zS9SnuWT_CEm69$0^2iyJLth2XVoxWQSaTj79AFx{SS&0%5W+vm#>42>F(}}D!Qu&_ zyX!G+i3S;CLD~6?ZY?$DzcVL*&rBg%phaj8@6=X9C{-AF|4Wo?zvS;e)yCfWlC!_> zG(LfYBQVgvCu@_|FbAO~|Ho#WD8Zl;8)!RooG5vz((Ig;b-oCPCg&A^QHgxMKOZ|u zlg=5D3%yOTZ!LntTgPoY(5$7##(l{y&C@sC(fkE|OuNxqUqVMj~bL=-&+O>87 zLV(b)B-XDxeR?YI(g8ZX(I}dJq5<_NN+n53%U4G=5*W{WJMXFaT;~4<97}Sc)u1E4=$QOeDueodgXR`g{oiGu5 z93qEhEQfOJ>x=JlD9oWTr*Ao>@GXa8Og3y~Vq_>X5guEu?}#)xG&zU$cv??thFL6M;< zeO(F8Sh2spEe$Uh6Qrb@mV~;WAXZK4_MOf*W^S=O#6V=T z1;Dk$S?r$lXdeti_~`nUwmP!;sKeKup}@6eJITYH17e=>J3NTTUKOk zxs9t5b;2eU>w%ZQ%}F|jhXIYp@Ri2SqC^rW=gPBt?U#{C+DDuqV^xD+yJ}lm1go^^ z$<~w12utJ~6mz(V&3;Sp5IuUdH!(3$C{-nc#o$oS00qsqn+pCof>^3#kD;lERA7~OTjx3BXN~{(n4DVm+?{c{K zv~R}apQ*_zpZ=gLXYH~oM2WD|NsUIOUP~cbiysu_naXCoSN-G;1;5(r!7rHPvE{Kw zBHrl3+H0h(FDv2baoVeoDE-_@V9R3zLqoj*;$0~9%Y3h%-ER<7hv}Jc(>Pty(C~RR z^W}r;p(hc)&ha-HV0xV}pe-5LOwP=fr z6XmzxV$_UqqHC4b8?yK;xr)@jT({F2Do*u+#PzlzJd^CN@r_+*j2K_dX=vav6_Cc$`Zg_$w(-xUBR@2X0?iXO|JqH@Mz6Y=P(X41 zcSWN>>+nOU&e_d;7cjz)?L~O>N0#)EK7IUXO}U)__%tq#j08Tx+81OzHtIQjZ4aBv zf!4jTYM!c=caQ$}fdgZcZqVl~fnj0$0p|<=$m}!Zt;Uc^9W-Sg;34 z7`%(SMBvvx3-&l`e8p=)3!PN#wX{P`SYbt-U-F7Z5V`MWhcd($gF{+lwg5==mEK-h zgfO%tWrwak7NK(vEC;FD8Z{^nQnhV-Y3YlqPMX!<`W8nV1IF>&bNJ+7R-$^K8j*R zw{b=^V_%TnQqkFolmWm_RC9usRk?PGHNoJqP662qH}& z`zOJvMml7%HKSy;o1#PxPX;J5TeStSE5a|kFg_%Rv$^*}={T$zIDt4B}1%Dd# zLSzp(PvYE?Fb1hhDcf*Ndh7UU0_qdFMju1ZE~H z{m_v^ry3fb6S_J;$QBcCM&{(07$`ivPl=|7m6^#^F=<@dx}>ND9=+XU4mik+zWfH$s~XC z`UnqK<<#1Y;{mmLj=7TU;Csc8dI7qzhMi_^(xe2JI{)Z6?p_l-#C6F}Z8H7>*DL=F z<_(l0Vf^pvj4*YFpsG8Hd@C@7K-U0KrW|gl>{Fq;0+Py~_Y7NOuDg}w)InFX!5fTD z!?K{vib~_!_*9Gfad?8LCAWPhv+KmFxZ=pmK~az(~IvxPaadtPgXhTRya>y$#7 z3QO(@s@&TLeS(M-B^!U#)c|MN=UFT{^R8xaWcws3%H1`e4iv)~=oi!#0xx}mI}HbC v`G~&@fLeiaidQMu3ml+^-k>Z0Z!eIpZPsI2-ZD7qxejdJD2zMXH8T4zEvNkR diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_right-vbounds.norm]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_right-vbounds.norm]/expected.png deleted file mode 100644 index 3696ba3d28c8381876a1181a12fd6d8502194a7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35595 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 YWDu8!6XHMlN63K7$IIWd5{k(B8 diff --git a/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_right-vbounds.numbers]/expected.png b/tests/_images/embedding-missing-values/test_missing_values_continuous[spatial-na_color.default-legend.on_right-vbounds.numbers]/expected.png deleted file mode 100644 index 96352358d166003b205a3c34ce91b884d150b3d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35595 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