Skip to content

Commit

Permalink
remove napari from install (#877)
Browse files Browse the repository at this point in the history
* remove napari from install

* fix tox

* remove qt

* update pre-commit

* fix mypy

* cleanup pre-commit

* add napari warning and release note

* fix pre-commit

* fixes to docs

* fix mypy

* fix release note

* update
  • Loading branch information
giovp authored Aug 30, 2024
1 parent 787b90e commit 89ea7d2
Show file tree
Hide file tree
Showing 44 changed files with 256 additions and 127 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ jobs:
tox -vv
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3.1.1
uses: codecov/codecov-action@v4
with:
name: coverage
verbose: true
token: ${{ secrets.CODECOV_TOKEN }} # required
58 changes: 10 additions & 48 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,59 +6,21 @@ default_stages:
- push
minimum_pre_commit_version: 2.9.3
repos:
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.11.0
hooks:
- id: mypy
additional_dependencies: [numpy, pandas, types-requests]
exclude: .scripts/ci/download_data.py|squidpy/datasets/_(dataset|image).py # See https://github.com/pre-commit/mirrors-mypy/issues/33
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v4.0.0-alpha.8
hooks:
- id: prettier
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: detect-private-key
- id: check-merge-conflict
- id: check-ast
- id: check-symlinks
- id: check-added-large-files
- id: check-executables-have-shebangs
- id: fix-encoding-pragma
args: [--remove]
- id: end-of-file-fixer
- id: mixed-line-ending
args: [--fix=lf]
- id: trailing-whitespace
exclude: ^.bumpversion.cfg$
- id: name-tests-test
args: [--django]
- id: check-case-conflict
- id: check-docstring-first
- id: check-yaml
- id: check-toml
- id: requirements-txt-fixer
- repo: https://github.com/jumanjihouse/pre-commit-hooks
rev: 3.0.0
hooks:
- id: script-must-have-extension
name: Check executable files use .sh extension
types: [shell, executable]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.5.4
rev: v0.6.2
hooks:
- id: ruff
types_or: [python, pyi, jupyter]
args: [--fix, --exit-non-zero-on-fix]
- id: ruff-format
types_or: [python, pyi, jupyter]
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.10.0
- repo: https://github.com/asottile/blacken-docs
rev: 1.18.0
hooks:
- id: blacken-docs
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.11.1
hooks:
- id: python-no-eval
- id: python-use-type-annotations
- id: python-check-blanket-noqa
- id: rst-backticks
- id: rst-directive-colons
- id: rst-inline-touching-normal
- id: mypy
additional_dependencies: [numpy, pandas, types-requests]
exclude: .scripts/ci/download_data.py|squidpy/datasets/_(dataset|image).py # See https://github.com/
1 change: 0 additions & 1 deletion .prettierignore

This file was deleted.

3 changes: 2 additions & 1 deletion .scripts/ci/download_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ def _maybe_download_data(func_name: str, path: Path) -> Any:


def main(args: argparse.Namespace) -> None:
import squidpy as sq
from anndata import AnnData

import squidpy as sq

all_datasets = sq.datasets._dataset.__all__ + sq.datasets._image.__all__
all_extensions = ["h5ad"] * len(sq.datasets._dataset.__all__) + ["tiff"] * len(sq.datasets._image.__all__)

Expand Down
2 changes: 1 addition & 1 deletion docs/classes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ Classes
:toctree: classes

im.ImageContainer
pl.Interactive
im.SegmentationWatershed
im.SegmentationCustom
.. pl.Interactive
11 changes: 11 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@ tissue images if available.
:align: center
:target: https://doi.org/10.1038/s41592-021-01358-2

.. warning::
🚨🚨🚨 **Warning!** 🚨🚨🚨

The original napari-plugin of Squidpy has been moved to `napari-spatialdata <https://github.com/scverse/napari-spatialdata>`_.

All the functionalities previously available are also implemented in the new plugin, which also has many additional new features.

You can find a rich set of `documentation and examples <https://spatialdata.scverse.org/projects/napari/en/latest/index.html>`_, and we suggest starting with this `tutorial <https://spatialdata.scverse.org/projects/napari/en/latest/notebooks/spatialdata.html>`_.

If you are new to SpatialData, we invite you to take a look at the documentation `here <https://spatialdata.scverse.org/en/latest/tutorials/notebooks/notebooks.html>`_.

Manuscript
----------
Please see our manuscript :cite:`palla:22` in **Nature Methods** to learn more.
Expand Down
9 changes: 9 additions & 0 deletions docs/release/notes-1.6.1.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Squidpy 1.6.1 (2024-08-23)
==========================

Maintenance
-----------

- The Squidpy `interactive` module has been removed. Please use the ``napari-spatialdata`` plugin instead. You can find it `here <https://spatialdata.scverse.org/projects/napari/en/latest/index.html>`__ `@giovp <https://github.com/giovp>`__
`#877 <https://github.com/scverse/squidpy/pull/877>`__

13 changes: 5 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,6 @@ dependencies = [
]

[project.optional-dependencies]
interactive = [
"napari[pyqt5]==0.4.15",
"pydantic==1.10.13"
]
dev = [
"pre-commit>=3.0.0",
"tox>=4.0.0",
Expand Down Expand Up @@ -214,10 +210,11 @@ required-imports = ["from __future__ import annotations"]
"*/__init__.py" = ["D104", "F401"]
"tests/*"= ["D"]
"docs/*"= ["D","B"]
"squidpy/pl/_ligrec.py"= ["D","B"]
"squidpy/_constants/_pkg_constants.py"= ["D101","D102","D106"]
"squidpy/_constants/_constants.py"= ["D101"]
"squidpy/pl/_interactive/_widgets.py"= ["D"]
"src/squidpy/pl/_ligrec.py"= ["D","B"]
"src/squidpy/_constants/_pkg_constants.py"= ["D101","D102","D106"]
"src/squidpy/_constants/_constants.py"= ["D101"]
"src/squidpy/pl/_interactive/_widgets.py"= ["D"]
"src/squidpy/pl/_interactive/interactive.py"= ["F","E"]
".scripts/ci/download_data.py"= ["D","B"]
# "squidpy/*.py"= ["RST303"]

Expand Down
34 changes: 23 additions & 11 deletions src/squidpy/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,18 @@ def wrapper(*args: Any, **kw: Any) -> Any:
return wrapper


try:
from numpy.typing import NDArray
from numpy.typing import NDArray

NDArrayA = NDArray[Any]
except (ImportError, TypeError):
NDArray = np.ndarray # type: ignore[misc]
NDArrayA = np.ndarray # type: ignore[misc]
NDArrayA = NDArray[Any]


class SigQueue(Queue["Signal"] if TYPE_CHECKING else Queue): # type: ignore[misc]
"""Signalling queue."""


def _unique_order_preserving(iterable: Iterable[Hashable]) -> tuple[list[Hashable], set[Hashable]]:
def _unique_order_preserving(
iterable: Iterable[Hashable],
) -> tuple[list[Hashable], set[Hashable]]:
"""Remove items from an iterable while preserving the order."""
seen: set[Hashable] = set()
seen_add = seen.add
Expand Down Expand Up @@ -124,7 +122,12 @@ def parallelize(
else:
tqdm = None

def runner(iterable: Iterable[Any], *args: Any, queue: SigQueue | None = None, **kwargs: Any) -> list[Any]:
def runner(
iterable: Iterable[Any],
*args: Any,
queue: SigQueue | None = None,
**kwargs: Any,
) -> list[Any]:
result: list[Any] = []

for it in iterable:
Expand Down Expand Up @@ -200,7 +203,10 @@ def wrapper(*args: Any, **kwargs: Any) -> Any:
col_len = len(collection)
step = int(np.ceil(len(collection) / n_split))
collections = list(
filter(len, (collection[i * step : (i + 1) * step] for i in range(int(np.ceil(col_len / step)))))
filter(
len,
(collection[i * step : (i + 1) * step] for i in range(int(np.ceil(col_len / step)))),
)
)

if use_runner:
Expand Down Expand Up @@ -289,7 +295,9 @@ def decorator(func1: Callable[..., Any]) -> Callable[..., Any]:
def new_func1(*args: Any, **kwargs: Any) -> Any:
warnings.simplefilter("always", DeprecationWarning)
warnings.warn(
fmt1.format(name=func1.__name__, reason=reason), category=DeprecationWarning, stacklevel=2
fmt1.format(name=func1.__name__, reason=reason),
category=DeprecationWarning,
stacklevel=2,
)
warnings.simplefilter("default", DeprecationWarning)
return func1(*args, **kwargs)
Expand Down Expand Up @@ -317,7 +325,11 @@ def new_func1(*args: Any, **kwargs: Any) -> Any:
@functools.wraps(func2)
def new_func2(*args: Any, **kwargs: Any) -> Any:
warnings.simplefilter("always", DeprecationWarning)
warnings.warn(fmt2.format(name=func2.__name__), category=DeprecationWarning, stacklevel=2)
warnings.warn(
fmt2.format(name=func2.__name__),
category=DeprecationWarning,
stacklevel=2,
)
warnings.simplefilter("default", DeprecationWarning)
return func2(*args, **kwargs)

Expand Down
4 changes: 2 additions & 2 deletions src/squidpy/gr/_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,11 +233,11 @@ def spatial_neighbors(

if library_key is not None:
mats: list[tuple[spmatrix, spmatrix]] = []
ixs = [] # type: ignore[var-annotated]
ixs: list[int] = []
for lib in libs:
ixs.extend(np.where(adata.obs[library_key] == lib)[0])
mats.append(_build_fun(adata[adata.obs[library_key] == lib]))
ixs = np.argsort(ixs) # type: ignore[assignment] # invert
ixs = np.argsort(ixs) # type: ignore[assignment] # invert
Adj = block_diag([m[0] for m in mats], format="csr")[ixs, :][:, ixs]
Dst = block_diag([m[1] for m in mats], format="csr")[ixs, :][:, ixs]
else:
Expand Down
26 changes: 22 additions & 4 deletions src/squidpy/gr/_nhood.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,15 @@ def nhood_enrichment(
n_jobs=n_jobs,
backend=backend,
show_progress_bar=show_progress_bar,
)(callback=_test, indices=indices, indptr=indptr, int_clust=int_clust, libraries=libraries, n_cls=n_cls, seed=seed)
)(
callback=_test,
indices=indices,
indptr=indptr,
int_clust=int_clust,
libraries=libraries,
n_cls=n_cls,
seed=seed,
)
zscore = (count - perms.mean(axis=0)) / perms.std(axis=0)

if copy:
Expand Down Expand Up @@ -293,7 +301,13 @@ def centrality_scores(

if copy:
return df
_save_data(adata, attr="uns", key=Key.uns.centrality_scores(cluster_key), data=df, time=start)
_save_data(
adata,
attr="uns",
key=Key.uns.centrality_scores(cluster_key),
data=df,
time=start,
)


@d.dedent
Expand Down Expand Up @@ -345,7 +359,7 @@ def interaction_matrix(

g_data = g.data if weights else np.broadcast_to(1, shape=len(g.data))
dtype = int if pd.api.types.is_bool_dtype(g.dtype) or pd.api.types.is_integer_dtype(g.dtype) else float
output = np.zeros((n_cats, n_cats), dtype=dtype) # type: ignore[var-annotated]
output: NDArrayA = np.zeros((n_cats, n_cats), dtype=dtype)

_interaction_matrix(g_data, g.indices, g.indptr, cats.cat.codes.to_numpy(), output)

Expand All @@ -360,7 +374,11 @@ def interaction_matrix(

@njit
def _interaction_matrix(
data: NDArrayA, indices: NDArrayA, indptr: NDArrayA, cats: NDArrayA, output: NDArrayA
data: NDArrayA,
indices: NDArrayA,
indptr: NDArrayA,
cats: NDArrayA,
output: NDArrayA,
) -> NDArrayA:
indices_list = np.split(indices, indptr[1:-1])
data_list = np.split(data, indptr[1:-1])
Expand Down
22 changes: 15 additions & 7 deletions src/squidpy/gr/_ppatterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ def extract_obsm(adata: AnnData, ixs: int | Sequence[int] | None) -> tuple[NDArr
if layer not in adata.obsm:
raise KeyError(f"Key `{layer!r}` not found in `adata.obsm`.")
if ixs is None:
ixs = np.arange(adata.obsm[layer].shape[1]) # type: ignore[assignment]
ixs = np.arange(adata.obsm[layer].shape[1]) # type:ignore[assignment]
ixs = list(np.ravel([ixs]))
return adata.obsm[layer][:, ixs].T, ixs

Expand All @@ -180,7 +180,11 @@ def extract_obsm(adata: AnnData, ixs: int | Sequence[int] | None) -> tuple[NDArr
mode = SpatialAutocorr(mode) # type: ignore[assignment]
if TYPE_CHECKING:
assert isinstance(mode, SpatialAutocorr)
params = {"mode": mode.s, "transformation": transformation, "two_tailed": two_tailed}
params = {
"mode": mode.s,
"transformation": transformation,
"two_tailed": two_tailed,
}

if mode == SpatialAutocorr.MORAN:
params["func"] = _morans_i
Expand Down Expand Up @@ -425,10 +429,10 @@ def co_occurrence(
n_splits = max(min(n_splits, n_obs), 1)

# split array and labels
spatial_splits = tuple(s for s in np.array_split(spatial, n_splits, axis=0) if len(s)) # type: ignore[arg-type]
labs_splits = tuple(s for s in np.array_split(labs, n_splits, axis=0) if len(s)) # type: ignore[arg-type]
spatial_splits = tuple(s for s in np.array_split(spatial, n_splits, axis=0) if len(s)) # type:ignore[arg-type]
labs_splits = tuple(s for s in np.array_split(labs, n_splits, axis=0) if len(s)) # type:ignore[arg-type]
# create idx array including unique combinations and self-comparison
x, y = np.triu_indices_from(np.empty((n_splits, n_splits))) # type: ignore[arg-type]
x, y = np.triu_indices_from(np.empty((n_splits, n_splits))) # type:ignore[arg-type]
idx_splits = list(zip(x, y))

n_jobs = _get_n_cores(n_jobs)
Expand Down Expand Up @@ -457,7 +461,11 @@ def co_occurrence(
return out, interval

_save_data(
adata, attr="uns", key=Key.uns.co_occurrence(cluster_key), data={"occ": out, "interval": interval}, time=start
adata,
attr="uns",
key=Key.uns.co_occurrence(cluster_key),
data={"occ": out, "interval": interval},
time=start,
)


Expand Down Expand Up @@ -570,7 +578,7 @@ def _g_moments(w: spmatrix | NDArrayA) -> tuple[float, float, float]:

# s1
t = w.transpose() + w
t2 = t.multiply(t) # type: ignore[union-attr]
t2 = t.multiply(t) # type:ignore[union-attr]
s1 = t2.sum() / 2.0

# s2
Expand Down
6 changes: 3 additions & 3 deletions src/squidpy/gr/_sepal.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,8 @@ def _score_helper(

score, sparse = [], issparse(vals)
for i in ixs:
conc = vals[:, i].toarray().flatten() if sparse else vals[:, i].copy() # type: ignore[union-attr]
conc = vals[:, i].toarray().flatten() if sparse else vals[:, i].copy() # type: ignore[union-attr]
conc = vals[:, i].toarray().flatten() if sparse else vals[:, i].copy() # type:ignore[union-attr]
conc = vals[:, i].toarray().flatten() if sparse else vals[:, i].copy() # type:ignore[union-attr]
time_iter = _diffusion(conc, fun, n_iter, sat, sat_idx, unsat, unsat_idx, dt=dt, thresh=thresh)
score.append(dt * time_iter)

Expand Down Expand Up @@ -286,7 +286,7 @@ def _entropy(
) -> float:
"""Get entropy of an array."""
xnz = xx[xx > 0]
xs = np.sum(xnz)
xs: np.float64 = np.sum(xnz)
xn = xnz / xs
xl = np.log(xn)
return float((-xl * xn).sum())
Expand Down
Loading

0 comments on commit 89ea7d2

Please sign in to comment.