Skip to content

Commit

Permalink
Fixed some issue of readme and added violin_box function (#714)
Browse files Browse the repository at this point in the history
  • Loading branch information
Starlitnightly committed Dec 28, 2024
1 parent c181381 commit 26a0ebf
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 2 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<p align="center">
<img height="150" src="https://dynamo-release.readthedocs.io/en/latest/_static/logo_with_word.png" />
<img height="150" src="https://dynamo-release.readthedocs.io/en/latest/_static/logo.png" />
</p>

##
Expand All @@ -21,7 +21,7 @@

Inclusive model of expression dynamics with metabolic labeling based scRNA-seq / multiomics, vector field reconstruction, potential landscape mapping, differential geometry analyses, and most probably paths / *in silico* perturbation predictions.

[Installation](https://dynamo-release.readthedocs.io/en/latest/ten_minutes_to_dynamo.html#how-to-install) - [Ten minutes to dynamo](https://dynamo-release.readthedocs.io/en/latest/ten_minutes_to_dynamo.html) - [Tutorials](https://dynamo-release.readthedocs.io/en/latest/notebooks/Differential_geometry.html) - [API](https://dynamo-release.readthedocs.io/en/latest/API.html) - [Citation](https://www.sciencedirect.com/science/article/pii/S0092867421015774?via%3Dihub) - [Theory](https://dynamo-release.readthedocs.io/en/latest/notebooks/Primer.html)
[Installation](https://dynamo-release.readthedocs.io/en/latest/installation.html) - [Ten minutes to dynamo](https://dynamo-release.readthedocs.io/en/latest/user_guide/index.html) - [Tutorials](https://dynamo-release.readthedocs.io/en/latest/tutorials/index.html) - [API](https://dynamo-release.readthedocs.io/en/latest/api/index.html) - [Citation](https://dynamo-release.readthedocs.io/en/latest/references.html) - [Theory](https://dynamo-release.readthedocs.io/en/latest/introduction/index.html)

![Dynamo](https://user-images.githubusercontent.com/7456281/152110270-7ee1b0ed-1205-495d-9d65-59c7984d2fa2.png)

Expand Down
2 changes: 2 additions & 0 deletions dynamo/data_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ def make_dir(path: str, can_exist: bool = True) -> bool:
main_info("creating a new directory")
os.makedirs(path)
return True




def convert2float(adata: AnnData, columns: List, var: bool = False) -> None:
Expand Down
3 changes: 3 additions & 0 deletions dynamo/plot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@
speed,
)

from .violin_box import violin_box

__all__ = [
"quiver_autoscaler",
"save_fig",
Expand Down Expand Up @@ -161,4 +163,5 @@
"sctransform_plot_fit",
"plot_residual_var",
"plot_dim_reduced_direct_graph",
"violin_box"
]
78 changes: 78 additions & 0 deletions dynamo/plot/violin_box.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from scipy.sparse import issparse

def violin_box(adata, keys, groupby, ax=None,
figsize=(4,4), show=True,
max_strip_points=200):
import colorcet

# 获取 y 数据
y = None
if not adata.raw is None and keys in adata.raw.var_names:
y = adata.raw[:, keys].X
elif keys in adata.obs.columns:
y = adata.obs[keys].values
elif keys in adata.var_names:
y = adata[:, keys].X
else:
raise ValueError(f'{keys} not found in adata.raw.var_names, adata.var_names, or adata.obs.columns')

if issparse(y):
y = y.toarray().reshape(-1)
else:
y = y.reshape(-1)

# 获取 x 数据
x = adata.obs[groupby].values.reshape(-1)

# 创建绘图数据
plot_data = pd.DataFrame({groupby: x, keys: y})

# 创建图形和轴
if ax is None:
fig, ax = plt.subplots(1, 1, figsize=figsize)

# 获取或设置颜色
if f'{groupby}_colors' not in adata.uns or adata.uns[f'{groupby}_colors'] is None:
colors = ['#%02x%02x%02x' % tuple([int(k * 255) for k in i]) for i in colorcet.glasbey_bw_minc_20_maxl_70]
adata.uns[f'{groupby}_colors'] = colors[:len(adata.obs[groupby].unique())]

# 绘制小提琴图
sns.violinplot(x=groupby, y=keys, data=plot_data, hue=groupby, dodge=False,
palette=adata.uns[f'{groupby}_colors'], scale="width", inner=None, ax=ax)

# 调整小提琴图
xlim, ylim = ax.get_xlim(), ax.get_ylim()
for violin in ax.collections:
bbox = violin.get_paths()[0].get_extents()
x0, y0, width, height = bbox.bounds
violin.set_clip_path(plt.Rectangle((x0, y0), width / 2, height, transform=ax.transData))

# 绘制箱线图
sns.boxplot(x=groupby, y=keys, data=plot_data, saturation=1, showfliers=False,
width=0.3, boxprops={'zorder': 3, 'facecolor': 'none'}, ax=ax)

# 限制 stripplot 的数据点数量
if len(plot_data) > max_strip_points:
plot_data = plot_data.sample(max_strip_points)

# 绘制 stripplot
old_len_collections = len(ax.collections)
sns.stripplot(x=groupby, y=keys, data=plot_data, hue=groupby,
palette=adata.uns[f'{groupby}_colors'], dodge=False, ax=ax)

# 调整 stripplot 点的位置
for dots in ax.collections[old_len_collections:]:
dots.set_offsets(dots.get_offsets() + np.array([0.12, 0]))

ax.set_xlim(xlim)
ax.set_ylim(ylim)
plt.xticks(rotation=90)

if show:
plt.show()

return ax

0 comments on commit 26a0ebf

Please sign in to comment.