Skip to content

Commit

Permalink
Merge pull request #157 from saezlab/circle
Browse files Browse the repository at this point in the history
add Circle plot, address issues with AnnData, and scipy sparse
  • Loading branch information
dbdimitrov authored Jan 17, 2025
2 parents 3be9589 + 0c0f128 commit 2d84646
Show file tree
Hide file tree
Showing 23 changed files with 1,457 additions and 905 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 1.4.0
current_version = 1.5.0
commit = True
tag = True
files = pyproject.toml liana/__init__.py
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.10"]
python-version: ["3.9", "3.10"]

steps:
- uses: actions/checkout@v3
Expand Down Expand Up @@ -43,14 +43,14 @@ jobs:
build-macOS:

runs-on: macOS-12
runs-on: macOS-13

steps:
- uses: actions/checkout@v2
- name: Set up Python 3.8
- name: Set up Python 3.9
uses: actions/setup-python@v2
with:
python-version: 3.8
python-version: 3.9
- name: Install Poetry
run: |
python -m pip install --upgrade pip
Expand Down
145 changes: 82 additions & 63 deletions docs/source/notebooks/basic_usage.ipynb

Large diffs are not rendered by default.

506 changes: 245 additions & 261 deletions docs/source/notebooks/bivariate.ipynb

Large diffs are not rendered by default.

560 changes: 299 additions & 261 deletions docs/source/notebooks/sma.ipynb

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions docs/source/release_notes.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Changelog
=============

1.5.0 (17.01.2025)
- New ``circle_plot`` is now available (Merged #139). Thanks to @WeipengMO.

- Update bivariate metrics to no longer save in place but rather return the AnnData

- Issue related to .A for a csr_matrix after a certain scipy version #155, #135

1.4.0 (02.09.2024)
-------------------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion liana/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = '1.4.0'
__version__ = '1.5.0'

from liana import method as mt, plotting as pl, resource as rs, multi as mu, utils as ut, testing

Expand Down
6 changes: 3 additions & 3 deletions liana/method/sc/_liana_pipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,8 @@ def _assign_min_or_max(x, x_ascending):


def _trimean(a, axis=0):
quantiles = np.quantile(a.A, q=[0.25, 0.75], axis=axis)
median = np.median(a.A, axis=axis)
quantiles = np.quantile(a.toarray(), q=[0.25, 0.75], axis=axis)
median = np.median(a.toarray(), axis=axis)
return (quantiles[0] + 2 * median + quantiles[1]) / 4

def _cluster_stats(adata):
Expand All @@ -471,7 +471,7 @@ def _cluster_stats(adata):
temp = adata[adata.obs['@label'].isin([label])]

cluster_stats.loc[label, 'mean'] = temp.X.mean()
cluster_stats.loc[label, 'std'] = np.std(temp.X.A)
cluster_stats.loc[label, 'std'] = np.std(temp.X.toarray())

return cluster_stats

Expand Down
9 changes: 5 additions & 4 deletions liana/method/sp/_bivariate/_local_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ def __call__(self,
weight = _spatialdm_weight_norm(weight)
else:
if issparse(x_mat):
x_mat = x_mat.A
x_mat = x_mat.toarray()
if issparse(y_mat):
y_mat = y_mat.A
y_mat = y_mat.toarray()

if self.name.__contains__("masked") or weight.shape[0] < 10000:
weight = weight.todense().A
if issparse(weight):
weight = weight.todense().A

local_scores = self.fun(x_mat, y_mat, weight)

Expand Down Expand Up @@ -180,7 +181,7 @@ def _get_local_var(self, x_sigma, y_sigma, weight, spot_n):
return std

def _norm_max(self, X, axis=0):
X = X / X.max(axis=axis).A
X = X / X.max(axis=axis).toarray()
X = _zscore(X, axis=axis)
X = np.where(np.isnan(X), 0, X)

Expand Down
30 changes: 5 additions & 25 deletions liana/method/sp/_bivariate/_spatial_bivariate.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ def __call__(self,
remove_self_interactions: bool = True,
complex_sep: (None | str) = "_",
xy_sep: str = V.lr_sep,
inplace: bool = V.inplace,
key_added: str = "local_scores",
verbose: bool = V.verbose,
**kwargs
) -> Union[AnnData, pd.DataFrame] | None:
Expand Down Expand Up @@ -76,9 +74,6 @@ def __call__(self,
Separator to use for interaction names.
remove_self_interactions: bool
Whether to remove self-interactions. `True` by default.
%(inplace)s
key_added: str
Key in `mdata.mod` (if MuData) or `adata.obsm` (if AnnData) where the local scores will be stored.
%(verbose)s
**kwargs : dict, optional
Expand Down Expand Up @@ -107,14 +102,8 @@ def __call__(self,
Returns
-------
If `inplace` is `True`, the results are added to `mdata` and `None` is returned.
Note that `var`, `obs`, `obsm`, `uns` and `obsp` attributes are copied to the output object.
When `mdata` is an `AnnData` object, the results are stored in `mdata.obsm[key_added]`
When `mdata` is an `MuData` object, the results are stored in `mdata.mod[key_added]`
`AnnData` objects in `obsm` will not be copied to the output object.
If `inplace` is `False`, the results are returned.
An AnnData object, (optionally) with multiple layers which correspond categories/p-values, and the
actual scores are stored in `.X`. Moreover, global stats are stored in ``.var``.
"""

Expand Down Expand Up @@ -251,7 +240,7 @@ def __call__(self,
if local_pvals is not None:
local_scores.layers['pvals'] = csr_matrix(local_pvals)

return self._handle_return(mdata, xy_stats, local_scores, key_added, inplace)
return local_scores

def _process_anndata(self,
adata,
Expand Down Expand Up @@ -331,15 +320,6 @@ def _rename_means(self, lr_stats, entity):
df.columns = df.columns.map(lambda x: entity + '_' + str(x) if x != 'gene' else 'gene')
return df.rename(columns={'gene': entity})

def _handle_return(self, data, stats, local_scores, key_added, inplace=False):
if not inplace:
return stats, local_scores

if isinstance(data, MuData):
data.mod[key_added] = local_scores
else:
data.obsm[key_added] = local_scores

def _handle_connectivity(self, adata, connectivity_key):
if connectivity_key not in adata.obsp.keys():
raise ValueError(f'No connectivity matrix founds in mdata.obsp[{connectivity_key}]')
Expand All @@ -358,8 +338,8 @@ def _encode_cats(self, a, weight):
return a

def _categorize(self, x_mat, y_mat, weight):
x_cats = self._encode_cats(x_mat.A, weight)
y_cats = self._encode_cats(y_mat.A, weight)
x_cats = self._encode_cats(x_mat.toarray(), weight)
y_cats = self._encode_cats(y_mat.toarray(), weight)
cats = x_cats + y_cats
cats = np.where(cats == 2, 1, np.where(cats == 0, -1, 0))

Expand Down
1 change: 1 addition & 0 deletions liana/plotting/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
from ._dotplot import dotplot, dotplot_by_sample
from ._misty_plots import target_metrics, contributions, interactions
from ._tileplot import tileplot
from ._circle_plot import circle_plot
Loading

0 comments on commit 2d84646

Please sign in to comment.