Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix matplotlib version issues and a circular import issue #686

Merged
merged 38 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
35b22e6
chore: Update matplotlib colormap registration
chansigit Jul 2, 2024
bb7885c
Merge branch 'master' of https://github.com/chansigit/dynamo-release
chansigit Jul 2, 2024
bd2e9bf
fix format issues
chansigit Jul 3, 2024
4025eea
reformat with isort==5.12.0 black==22.6.0
chansigit Jul 3, 2024
97ed400
update requirements to accomodate python3.8
chansigit Jul 3, 2024
674f013
chore: fix the circular import issue
chansigit Jul 3, 2024
bd9d7e7
chore: Import log1p_ function in cell_cycle.py
chansigit Jul 3, 2024
bd82f3b
Update python-package.yml
chansigit Jul 3, 2024
b3acc5d
fix log1p_ importing
chansigit Jul 3, 2024
d77e7f9
Merge branch 'master' of https://github.com/chansigit/dynamo-release
chansigit Jul 3, 2024
52f9542
chore: Import 'update_dict' inside function to fix circular import issue
chansigit Jul 3, 2024
2fffc20
fixing more circular imports
chansigit Jul 3, 2024
84d956b
Update node version to 22.x and 24.x in GitHub Actions workflow file
chansigit Jul 4, 2024
d2b8c53
change import order in init since dynamo relies on init order to work
chansigit Jul 4, 2024
facac04
chore: Update resource data URLs from dropbox to figshare
chansigit Jul 5, 2024
6b8840c
chore: update register_cmap to register
chansigit Jul 5, 2024
e31a5f4
chore: Update scipy.sparse import in normalization and transform modules
chansigit Jul 5, 2024
9a5833f
update deprecated functions in matplotlib and numpy
chansigit Jul 5, 2024
2e15f82
chore: check if cmap exists before registering
chansigit Jul 5, 2024
e79aed1
fix: SettingWithCopyWarning in pandas dataframe
chansigit Jul 5, 2024
d28b8ac
fix: The `scale` parameter has been renamed and will be removed in v0…
chansigit Jul 5, 2024
9ed280c
chore: update get_cmap to colormaps[ ]
chansigit Jul 5, 2024
02dbd74
chore: `cloud` -> `figshare`
chansigit Jul 6, 2024
b582a4c
chore: import matplotlib as mpl
chansigit Jul 6, 2024
0be3cf0
chore: resolve warnings
chansigit Jul 6, 2024
6fd158d
trial: Update python-version matrix in GitHub workflow
chansigit Jul 6, 2024
06729a8
fix weird 3.10 version issue: if i use 3.10, it would be recognized a…
chansigit Jul 6, 2024
2736e39
trial: let the build continue on error
chansigit Jul 6, 2024
3339f3d
trial: remove python 3.12 tests
chansigit Jul 6, 2024
7e464dc
Merge pull request #690 from chansigit/master
chansigit Jul 8, 2024
1c9df72
deprecate sparse matrix .A attributes
Sichao25 Jul 9, 2024
d196c16
revert unnecessary changes on marix.A
Sichao25 Jul 9, 2024
87422f0
revert more unnecessary changes on matrix.A
Sichao25 Jul 9, 2024
c9fa676
Merge pull request #691 from Sichao25/sijie-july24-fix
chansigit Jul 10, 2024
1d6ba32
Merge branch 'master' into master
Sichao25 Jul 12, 2024
f8b9da6
deprecate more sparse matrix .A attributes
Sichao25 Jul 22, 2024
62a8198
Merge pull request #695 from Sichao25/sijie-july24-fix
chansigit Jul 22, 2024
8d7c134
Merge branch 'sijie-july24-fix'
chansigit Jul 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/python-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-lastest, windows-2016]
node-version: [12.x, 14.x]
node-version: [22.x, 24.x]

steps:
- uses: actions/checkout@v1
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.7, 3.8, 3.9]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add 3.9, 3.10, 3.11, 3.12?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3.12 failed due to the removal of distutils package https://stackoverflow.com/questions/77247893/modulenotfounderror-no-module-named-distutils-in-python-3-12

other versions on the way

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3.10 and 3.11 also failed. we need more time to get it pass.
I noticed scanpy is asking a python version <3.10, we may remain in 3.9 temporarily.
https://github.com/scverse/scanpy/blob/db2118e8eb60bbf6287ce1413477480e16b2508b/pyproject.toml#L70

python-version: [3.8, 3.9]

steps:
- uses: actions/checkout@v2
Expand All @@ -40,4 +40,4 @@ jobs:
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
# - name: Test with pytest
# run: |
# pytest
# pytest
23 changes: 14 additions & 9 deletions docs/source/_ext/pdfembed.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from docutils import nodes


def pdfembed_html(pdfembed_specs):
"""
Build the iframe code for the pdf file,
Expand All @@ -20,27 +21,31 @@ def pdfembed_html(pdfembed_specs):
align="%s">
</iframe>
"""
return ( html_base_code % (pdfembed_specs['src' ],
pdfembed_specs['height'],
pdfembed_specs['width' ],
pdfembed_specs['align' ]) )
return html_base_code % (
pdfembed_specs["src"],
pdfembed_specs["height"],
pdfembed_specs["width"],
pdfembed_specs["align"],
)


def pdfembed_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
"""
Get iframe specifications and generate the associate HTML code for the pdf iframe.
"""
# parse and init variables
text = text.replace(' ', '')
text = text.replace(" ", "")
pdfembed_specs = {}
# read specs
for component in text.split(','):
pdfembed_specs[component.split(':')[0]] = component.split(':')[1]
for component in text.split(","):
pdfembed_specs[component.split(":")[0]] = component.split(":")[1]
# build node from pdf iframe html code
node = nodes.raw('', pdfembed_html(pdfembed_specs), format='html')
node = nodes.raw("", pdfembed_html(pdfembed_specs), format="html")
return [node], []


def setup(app):
"""
Set up the app with the extension function
"""
app.add_role('pdfembed', pdfembed_role)
app.add_role("pdfembed", pdfembed_role)
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
"sphinxcontrib.bibtex",
"sphinx_gallery.load_style",
# pdf embed
'pdfembed',
"pdfembed",
]

# Mappings for sphinx.ext.intersphinx. Projects have to have Sphinx-generated doc! (.inv file)
Expand Down
3 changes: 1 addition & 2 deletions dynamo/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Mapping Vector Field of Single Cells
"""

from .get_version import get_version, get_dynamo_version
from .get_version import get_dynamo_version, get_version

__version__ = get_version(__file__)
del get_version
Expand All @@ -19,7 +19,6 @@
from . import mv
from . import shiny
from . import sim
from .data_io import *
from . import sample_data
from . import configuration
from . import ext
Expand Down
51 changes: 31 additions & 20 deletions dynamo/configuration.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import warnings
from typing import Any, List, Generator, Optional, Tuple, Union
from typing import Any, Generator, List, Optional, Tuple, Union

import colorcet
import matplotlib
Expand All @@ -15,6 +15,7 @@

class DynamoAdataKeyManager:
"""A class to manage the keys used in anndata object for dynamo."""

VAR_GENE_MEAN_KEY = "pp_gene_mean"
VAR_GENE_VAR_KEY = "pp_gene_variance"
VAR_GENE_HIGHLY_VARIABLE_KEY = "gene_highly_variable"
Expand All @@ -41,8 +42,8 @@ class DynamoAdataKeyManager:
RAW = "raw"

def _select_layer_cell_chunked_data(
mat: np.ndarray,
chunk_size: int,
mat: np.ndarray,
chunk_size: int,
) -> Generator:
"""Select layer data in cell chunks based on chunk_size."""
start = 0
Expand All @@ -55,8 +56,8 @@ def _select_layer_cell_chunked_data(
yield (mat[start:n, :], start, n)

def _select_layer_gene_chunked_data(
mat: np.ndarray,
chunk_size: int,
mat: np.ndarray,
chunk_size: int,
) -> Generator:
"""Select layer data in gene chunks based on chunk_size."""
start = 0
Expand Down Expand Up @@ -131,8 +132,11 @@ def select_layer_chunked_data(
elif layer == DynamoAdataKeyManager.RAW:
return DynamoAdataKeyManager._select_layer_cell_chunked_data(adata.raw.X, chunk_size=chunk_size)
elif layer == DynamoAdataKeyManager.PROTEIN_LAYER:
return DynamoAdataKeyManager._select_layer_cell_chunked_data(
adata.obsm["protein"], chunk_size=chunk_size) if "protein" in adata.obsm_keys() else None
return (
DynamoAdataKeyManager._select_layer_cell_chunked_data(adata.obsm["protein"], chunk_size=chunk_size)
if "protein" in adata.obsm_keys()
else None
)
else:
return DynamoAdataKeyManager._select_layer_cell_chunked_data(adata.layers[layer], chunk_size=chunk_size)
elif chunk_mode == "gene":
Expand All @@ -141,8 +145,11 @@ def select_layer_chunked_data(
elif layer == DynamoAdataKeyManager.RAW:
return DynamoAdataKeyManager._select_layer_gene_chunked_data(adata.raw.X, chunk_size=chunk_size)
elif layer == DynamoAdataKeyManager.PROTEIN_LAYER:
return DynamoAdataKeyManager._select_layer_gene_chunked_data(
adata.obsm["protein"], chunk_size=chunk_size) if "protein" in adata.obsm_keys() else None
return (
DynamoAdataKeyManager._select_layer_gene_chunked_data(adata.obsm["protein"], chunk_size=chunk_size)
if "protein" in adata.obsm_keys()
else None
)
else:
return DynamoAdataKeyManager._select_layer_gene_chunked_data(adata.layers[layer], chunk_size=chunk_size)
else:
Expand Down Expand Up @@ -172,7 +179,10 @@ def check_if_layer_exist(adata: AnnData, layer: str) -> bool:
return layer in adata.layers

def get_available_layer_keys(
adata: AnnData, layers: str = "all", remove_pp_layers: bool = True, include_protein: bool = True,
adata: AnnData,
layers: str = "all",
remove_pp_layers: bool = True,
include_protein: bool = True,
) -> List[str]:
"""Get the list of available layers' keys. If `layers` is set to all, return a list of all available layers; if
`layers` is set to a list, then the intersetion of available layers and `layers` will be returned."""
Expand Down Expand Up @@ -278,6 +288,7 @@ def aggregate_layers_into_total(

class DynamoVisConfig:
"""Dynamo visualization config class holding static variables to change behaviors of functions globally."""

def set_default_mode(background="white"):
"""Set the default mode for dynamo visualization."""
set_figure_params("dynamo", background=background)
Expand Down Expand Up @@ -432,25 +443,25 @@ def update_data_store_mode(mode: str) -> None:
with warnings.catch_warnings():
warnings.simplefilter("ignore")
if "zebrafish" not in matplotlib.colormaps():
plt.register_cmap("zebrafish", zebrafish_cmap)
matplotlib.colormaps.register(name="zebrafish", cmap=zebrafish_cmap)
Xiaojieqiu marked this conversation as resolved.
Show resolved Hide resolved
if "fire" not in matplotlib.colormaps():
plt.register_cmap("fire", fire_cmap)
matplotlib.colormaps.register(name="fire", cmap=fire_cmap)
if "darkblue" not in matplotlib.colormaps():
plt.register_cmap("darkblue", darkblue_cmap)
matplotlib.colormaps.register(name="darkblue", cmap=darkblue_cmap)
if "darkgreen" not in matplotlib.colormaps():
plt.register_cmap("darkgreen", darkgreen_cmap)
matplotlib.colormaps.register(name="darkgreen", cmap=darkgreen_cmap)
if "darkred" not in matplotlib.colormaps():
plt.register_cmap("darkred", darkred_cmap)
matplotlib.colormaps.register(name="darkred", cmap=darkred_cmap)
if "darkpurple" not in matplotlib.colormaps():
plt.register_cmap("darkpurple", darkpurple_cmap)
matplotlib.colormaps.register(name="darkpurple", cmap=darkpurple_cmap)
if "div_blue_black_red" not in matplotlib.colormaps():
plt.register_cmap("div_blue_black_red", div_blue_black_red_cmap)
matplotlib.colormaps.register(name="div_blue_black_red", cmap=div_blue_black_red_cmap)
if "div_blue_red" not in matplotlib.colormaps():
plt.register_cmap("div_blue_red", div_blue_red_cmap)
matplotlib.colormaps.register(name="div_blue_red", cmap=div_blue_red_cmap)
if "glasbey_white" not in matplotlib.colormaps():
plt.register_cmap("glasbey_white", glasbey_white_cmap)
matplotlib.colormaps.register(name="glasbey_white", cmap=glasbey_white_cmap)
if "glasbey_dark" not in matplotlib.colormaps():
plt.register_cmap("glasbey_dark", glasbey_dark_cmap)
matplotlib.colormaps.register(name="glasbey_dark", cmap=glasbey_dark_cmap)


_themes = {
Expand Down
19 changes: 13 additions & 6 deletions dynamo/data_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,11 @@ def convert2float(adata: AnnData, columns: List, var: bool = False) -> None:


def load_NASC_seq(
dir: str, type: str = "TPM", delimiter: str = "_", colnames: Optional[List] = None, dropna: bool = False,
dir: str,
type: str = "TPM",
delimiter: str = "_",
colnames: Optional[List] = None,
dropna: bool = False,
) -> AnnData:
"""Function to create an anndata object from NASC-seq pipeline.

Expand Down Expand Up @@ -323,7 +327,10 @@ def cleanup(adata: AnnData, del_prediction: bool = False, del_2nd_moments: bool


def export_rank_xlsx(
adata: AnnData, path: str = "rank_info.xlsx", ext: str = "excel", rank_prefix: str = "rank",
adata: AnnData,
path: str = "rank_info.xlsx",
ext: str = "excel",
rank_prefix: str = "rank",
) -> None:
import pandas as pd

Expand Down Expand Up @@ -373,15 +380,16 @@ def export_h5ad(adata: AnnData, path: str = "data/processed_data.h5ad") -> None:
for i in fate_keys:
if i is not None:
if "prediction" in adata.uns[i].keys():
adata.uns[i]["prediction"] = {str(index): array for index, array in
enumerate(adata.uns[i]["prediction"])}
adata.uns[i]["prediction"] = {
str(index): array for index, array in enumerate(adata.uns[i]["prediction"])
}
if "t" in adata.uns[i].keys():
adata.uns[i]["t"] = {str(index): array for index, array in enumerate(adata.uns[i]["t"])}

adata.write_h5ad(path)


def import_h5ad(path: str ="data/processed_data.h5ad") -> AnnData:
def import_h5ad(path: str = "data/processed_data.h5ad") -> AnnData:
"""Import a Dynamo h5ad object into anndata."""

adata = read_h5ad(path)
Expand All @@ -397,4 +405,3 @@ def import_h5ad(path: str ="data/processed_data.h5ad") -> AnnData:
adata.uns[i]["t"] = [adata.uns[i]["t"][index] for index in adata.uns[i]["t"]]

return adata

21 changes: 16 additions & 5 deletions dynamo/dynamo_logger.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from typing import Iterable, Optional

import functools
import logging
import sys
import time
from contextlib import contextmanager
from typing import Iterable, Optional


def silence_logger(name: str) -> None:
Expand Down Expand Up @@ -176,7 +175,13 @@ def error(self, message: str, indent_level: int = 1, *args, **kwargs) -> None:
return self.logger.error(message, *args, **kwargs)

def info_insert_adata(
self, key: str, adata_attr: str = "obsm", log_level: int = logging.NOTSET, indent_level: int = 1, *args, **kwargs
self,
key: str,
adata_attr: str = "obsm",
log_level: int = logging.NOTSET,
indent_level: int = 1,
*args,
**kwargs,
) -> None:
"""Log a message for inserting data into an AnnData object."""
message = "<insert> %s to %s in AnnData Object." % (key, adata_attr)
Expand Down Expand Up @@ -314,7 +319,10 @@ def get_temp_timer_logger() -> Logger:

@staticmethod
def progress_logger(
generator: Iterable, logger: Optional[Logger] = None, progress_name: str = "", indent_level: int = 1,
generator: Iterable,
logger: Optional[Logger] = None,
progress_name: str = "",
indent_level: int = 1,
) -> Iterable:
"""A generator that logs the progress of another generator."""
if logger is None:
Expand Down Expand Up @@ -362,7 +370,10 @@ def main_critical(message: str, indent_level: int = 1) -> None:


def main_tqdm(
generator: Iterable, desc: str = "", indent_level: int = 1, logger: LoggerManager = LoggerManager().main_logger,
generator: Iterable,
desc: str = "",
indent_level: int = 1,
logger: LoggerManager = LoggerManager().main_logger,
) -> Iterable:
"""a TQDM style wrapper for logging something like a loop.

Expand Down
9 changes: 7 additions & 2 deletions dynamo/estimation/csc/velocity.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

class Velocity:
"""The class that computes RNA/protein velocity given unknown parameters."""

def __init__(
self,
alpha: Optional[np.ndarray] = None,
Expand Down Expand Up @@ -163,7 +164,9 @@ def vel_u(

return V

def vel_s(self, U: Union[csr_matrix, np.ndarray], S: Union[csr_matrix, np.ndarray]) -> Union[csr_matrix, np.ndarray]:
def vel_s(
self, U: Union[csr_matrix, np.ndarray], S: Union[csr_matrix, np.ndarray]
) -> Union[csr_matrix, np.ndarray]:
"""Calculate the unspliced mRNA velocity.

Args:
Expand Down Expand Up @@ -227,7 +230,9 @@ def vel_s(self, U: Union[csr_matrix, np.ndarray], S: Union[csr_matrix, np.ndarra
V = np.nan
return V

def vel_p(self, S: Union[csr_matrix, np.ndarray], P: Union[csr_matrix, np.ndarray]) -> Union[csr_matrix, np.ndarray]:
def vel_p(
self, S: Union[csr_matrix, np.ndarray], P: Union[csr_matrix, np.ndarray]
) -> Union[csr_matrix, np.ndarray]:
"""Calculate the protein velocity.

Args:
Expand Down
4 changes: 2 additions & 2 deletions dynamo/estimation/deprecated.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import warnings
import functools
import warnings

from numba import float32 # import the types
from numpy import *
from scipy.optimize import least_squares

from .tsc.utils_moments import moments
from ..tools.sampling import lhsclassic
from .tsc.utils_moments import moments


class estimation:
Expand Down
Loading
Loading