SURE-tools 2.1.10__tar.gz → 2.1.12__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of SURE-tools might be problematic. Click here for more details.

Files changed (31) hide show
  1. {sure_tools-2.1.10 → sure_tools-2.1.12}/PKG-INFO +1 -1
  2. sure_tools-2.1.12/SURE/flow/plot_quiver.py +197 -0
  3. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE_tools.egg-info/PKG-INFO +1 -1
  4. {sure_tools-2.1.10 → sure_tools-2.1.12}/setup.py +1 -1
  5. sure_tools-2.1.10/SURE/flow/plot_quiver.py +0 -52
  6. {sure_tools-2.1.10 → sure_tools-2.1.12}/LICENSE +0 -0
  7. {sure_tools-2.1.10 → sure_tools-2.1.12}/README.md +0 -0
  8. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE/PerturbFlow.py +0 -0
  9. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE/SURE.py +0 -0
  10. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE/__init__.py +0 -0
  11. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE/assembly/__init__.py +0 -0
  12. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE/assembly/assembly.py +0 -0
  13. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE/assembly/atlas.py +0 -0
  14. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE/atac/__init__.py +0 -0
  15. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE/atac/utils.py +0 -0
  16. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE/codebook/__init__.py +0 -0
  17. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE/codebook/codebook.py +0 -0
  18. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE/flow/__init__.py +0 -0
  19. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE/flow/flow_stats.py +0 -0
  20. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE/perturb/__init__.py +0 -0
  21. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE/perturb/perturb.py +0 -0
  22. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE/utils/__init__.py +0 -0
  23. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE/utils/custom_mlp.py +0 -0
  24. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE/utils/queue.py +0 -0
  25. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE/utils/utils.py +0 -0
  26. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE_tools.egg-info/SOURCES.txt +0 -0
  27. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE_tools.egg-info/dependency_links.txt +0 -0
  28. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE_tools.egg-info/entry_points.txt +0 -0
  29. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE_tools.egg-info/requires.txt +0 -0
  30. {sure_tools-2.1.10 → sure_tools-2.1.12}/SURE_tools.egg-info/top_level.txt +0 -0
  31. {sure_tools-2.1.10 → sure_tools-2.1.12}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: SURE-tools
3
- Version: 2.1.10
3
+ Version: 2.1.12
4
4
  Summary: Succinct Representation of Single Cells
5
5
  Home-page: https://github.com/ZengFLab/SURE
6
6
  Author: Feng Zeng
@@ -0,0 +1,197 @@
1
+ import numpy as np
2
+ import matplotlib.pyplot as plt
3
+ from sklearn.decomposition import PCA
4
+ import scanpy as sc
5
+ from matplotlib.colors import ListedColormap
6
+
7
+
8
+ def plot_quiver(z_points, delta_z, method='pca', figsize=(6,4), dpi=200,
9
+ subsample=None, color_by=None, colormap='viridis',
10
+ arrow_scale=1.0, arrow_width=0.005, alpha=0.8):
11
+ """
12
+ 优化后的quiver可视化函数
13
+
14
+ Args:
15
+ z_points: 原始潜在空间点 [n_samples, n_dims]
16
+ delta_z: 移动向量 [n_samples, n_dims]
17
+ method: 降维方法 ('pca', 'variance', 'manual', 'umap')
18
+ figsize: 图像大小
19
+ dpi: 分辨率
20
+ subsample: 随机采样的数据点数量 (None表示不采样)
21
+ color_by: 颜色标签数组 [n_samples]
22
+ colormap: 颜色映射名称或ListedColormap对象
23
+ arrow_scale: 箭头缩放因子
24
+ arrow_width: 箭头宽度
25
+ alpha: 透明度
26
+ """
27
+ # 保存原始数据用于散点图
28
+ original_z_points = z_points.copy()
29
+ original_delta_z = delta_z.copy()
30
+ original_color_by = color_by.copy() if color_by is not None else None
31
+
32
+ # 数据采样(仅用于quiver)
33
+ quiver_indices = None
34
+ if subsample is not None and len(z_points) > subsample:
35
+ quiver_indices = np.random.choice(len(z_points), subsample, replace=False)
36
+ z_points_quiver = z_points[quiver_indices]
37
+ delta_z_quiver = delta_z[quiver_indices]
38
+ if color_by is not None:
39
+ color_by_quiver = color_by[quiver_indices]
40
+ else:
41
+ color_by_quiver = None
42
+ else:
43
+ z_points_quiver = z_points
44
+ delta_z_quiver = delta_z
45
+ color_by_quiver = color_by
46
+
47
+ # 降维投影(使用所有数据)
48
+ if method == 'variance':
49
+ variances = np.var(original_z_points, axis=0)
50
+ dims = np.argsort(variances)[-2:]
51
+ z_2d_all = original_z_points[:, dims]
52
+ z_2d_quiver = z_points_quiver[:, dims]
53
+ delta_z_2d = delta_z_quiver[:, dims]
54
+ dim_names = [f'z[{d}]' for d in dims]
55
+
56
+ elif method == 'pca':
57
+ pca = PCA(n_components=2)
58
+ z_2d_all = pca.fit_transform(original_z_points)
59
+ z_2d_quiver = pca.transform(z_points_quiver)
60
+ delta_z_2d = pca.transform(z_points_quiver + delta_z_quiver) - z_2d_quiver
61
+ dim_names = ['PC1', 'PC2']
62
+
63
+ elif method == 'manual':
64
+ dims = [0, 1]
65
+ z_2d_all = original_z_points[:, dims]
66
+ z_2d_quiver = z_points_quiver[:, dims]
67
+ delta_z_2d = delta_z_quiver[:, dims]
68
+ dim_names = [f'z[{d}]' for d in dims]
69
+
70
+ elif method == 'umap':
71
+ # 使用所有数据进行UMAP降维
72
+ ad = sc.AnnData(np.vstack([original_z_points, original_z_points+original_delta_z]))
73
+ sc.pp.neighbors(ad)
74
+ sc.tl.umap(ad)
75
+ z_2d_all = ad[:len(original_z_points)].obsm['X_umap']
76
+ z_2d_quiver = z_2d_all[quiver_indices] if quiver_indices is not None else z_2d_all
77
+ delta_z_2d = ad[len(original_z_points):].obsm['X_umap'][quiver_indices] - z_2d_quiver if quiver_indices is not None else ad[len(original_z_points):].obsm['X_umap'] - z_2d_all
78
+ dim_names = ['UMAP1', 'UMAP2']
79
+
80
+ # 颜色处理(散点图使用所有数据,quiver使用采样数据)
81
+ if original_color_by is not None:
82
+ if isinstance(colormap, str):
83
+ cmap = plt.get_cmap(colormap)
84
+ else:
85
+ cmap = colormap
86
+
87
+ if original_color_by.dtype.kind in ['i', 'f']: # 数值型标签
88
+ # 所有数据的颜色
89
+ colors_all = cmap(original_color_by / max(original_color_by.max(), 1e-8))
90
+ # quiver数据的颜色
91
+ if color_by_quiver is not None:
92
+ colors_quiver = cmap(color_by_quiver / max(color_by_quiver.max(), 1e-8))
93
+ else:
94
+ colors_quiver = 'blue'
95
+ cbar_label = 'Numeric Label'
96
+ else: # 类别型标签
97
+ unique_labels = np.unique(original_color_by)
98
+ color_map = {label: cmap(i/len(unique_labels))
99
+ for i, label in enumerate(unique_labels)}
100
+ colors_all = [color_map[label] for label in original_color_by]
101
+ if color_by_quiver is not None:
102
+ colors_quiver = [color_map[label] for label in color_by_quiver]
103
+ else:
104
+ colors_quiver = 'blue'
105
+ cbar_label = 'Class Label'
106
+ else:
107
+ colors_all = 'gray'
108
+ colors_quiver = 'blue'
109
+
110
+ # 绘制
111
+ plt.figure(figsize=figsize, dpi=dpi)
112
+
113
+ # 1. 首先绘制所有数据点的散点图
114
+ plt.scatter(z_2d_all[:, 0], z_2d_all[:, 1],
115
+ c=colors_all, alpha=0.3, s=5, label='All data points')
116
+
117
+ # 2. 绘制quiver(仅采样数据)
118
+ if color_by_quiver is not None and isinstance(color_by_quiver[0], str):
119
+ for label in np.unique(color_by_quiver):
120
+ mask = color_by_quiver == label
121
+ plt.quiver(z_2d_quiver[mask, 0], z_2d_quiver[mask, 1],
122
+ delta_z_2d[mask, 0], delta_z_2d[mask, 1],
123
+ angles='xy', scale_units='xy', scale=1.0/arrow_scale,
124
+ color=colors_quiver[mask], width=arrow_width, alpha=alpha,
125
+ label=f'{label} (movement)')
126
+ plt.legend()
127
+ else:
128
+ q = plt.quiver(z_2d_quiver[:, 0], z_2d_quiver[:, 1],
129
+ delta_z_2d[:, 0], delta_z_2d[:, 1],
130
+ angles='xy', scale_units='xy', scale=1.0/arrow_scale,
131
+ color=colors_quiver, width=arrow_width, alpha=alpha,
132
+ label='Movement vectors')
133
+
134
+ # 添加颜色条(数值型标签)
135
+ if original_color_by is not None and original_color_by.dtype.kind in ['i', 'f']:
136
+ plt.colorbar(plt.cm.ScalarMappable(
137
+ norm=plt.Normalize(original_color_by.min(), original_color_by.max()),
138
+ cmap=cmap), label=cbar_label)
139
+
140
+ # 美化图形
141
+ plt.xlabel(dim_names[0])
142
+ plt.ylabel(dim_names[1])
143
+ plt.title(f"Latent Space Movement ({method} projection)\n{len(z_points_quiver)}/{len(original_z_points)} points with vectors")
144
+ plt.grid(alpha=0.2)
145
+ plt.legend()
146
+ plt.tight_layout()
147
+ plt.show()
148
+
149
+ return z_2d_all, z_2d_quiver, delta_z_2d
150
+
151
+ def plot_quiver_old(z_points, delta_z, method='pca', figsize=(6,4), dpi=200):
152
+ """
153
+ 从高维潜在空间选择2个维度进行quiver可视化
154
+ """
155
+ if method == 'variance':
156
+ # 方法1: 选择方差最大的2个维度
157
+ variances = np.var(z_points, axis=0)
158
+ dims = np.argsort(variances)[-2:] # 选择方差最大的两个维度
159
+ dim_names = [f'z[{d}]' for d in dims]
160
+
161
+ elif method == 'pca':
162
+ # 方法2: 使用PCA的前两个主成分
163
+ pca = PCA(n_components=2)
164
+ z_2d = pca.fit_transform(z_points)
165
+ delta_z_2d = pca.transform(z_points + delta_z) - z_2d
166
+ dim_names = ['PC1', 'PC2']
167
+
168
+ elif method == 'manual':
169
+ # 方法3: 手动选择感兴趣的维度
170
+ dims = [0, 1] # 选择前两个维度
171
+ z_2d = z_points[:, dims]
172
+ delta_z_2d = delta_z[:, dims]
173
+ dim_names = [f'z[{d}]' for d in dims]
174
+
175
+ elif method == 'umap':
176
+ ad = sc.AnnData(np.vstack([z_points, z_points+delta_z]))
177
+ sc.pp.neighbors(ad)
178
+ sc.tl.umap(ad)
179
+ z_2d = ad[:z_points.shape[0]].obsm['X_umap']
180
+ delta_z_2d = ad[z_points.shape[0]:].obsm['X_umap'] - z_2d
181
+ dim_names = ['UMAP1', 'UMAP2']
182
+
183
+ # 绘制quiver图
184
+ plt.figure(figsize=figsize, dpi=dpi)
185
+ plt.quiver(z_2d[:, 0], z_2d[:, 1],
186
+ delta_z_2d[:, 0], delta_z_2d[:, 1],
187
+ angles='xy', scale_units='xy', scale=1,
188
+ color='blue', alpha=0.6, width=0.005)
189
+
190
+ plt.scatter(z_2d[:, 0], z_2d[:, 1], c='gray', alpha=0.5, s=10)
191
+ plt.xlabel(dim_names[0])
192
+ plt.ylabel(dim_names[1])
193
+ plt.title(f"Latent Space Movement ({method} projection)")
194
+ plt.grid(alpha=0.3)
195
+ plt.show()
196
+
197
+ return z_2d, delta_z_2d
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: SURE-tools
3
- Version: 2.1.10
3
+ Version: 2.1.12
4
4
  Summary: Succinct Representation of Single Cells
5
5
  Home-page: https://github.com/ZengFLab/SURE
6
6
  Author: Feng Zeng
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setup(
7
7
  name='SURE-tools',
8
- version='2.1.10',
8
+ version='2.1.12',
9
9
  description='Succinct Representation of Single Cells',
10
10
  long_description=long_description,
11
11
  long_description_content_type="text/markdown",
@@ -1,52 +0,0 @@
1
- import numpy as np
2
- import matplotlib.pyplot as plt
3
- from sklearn.decomposition import PCA
4
- import scanpy as sc
5
-
6
- def plot_quiver(z_points, delta_z, method='umap', figsize=(6,4), dpi=200):
7
- """
8
- 从高维潜在空间选择2个维度进行quiver可视化
9
- """
10
- if method == 'variance':
11
- # 方法1: 选择方差最大的2个维度
12
- variances = np.var(z_points, axis=0)
13
- dims = np.argsort(variances)[-2:] # 选择方差最大的两个维度
14
- dim_names = [f'z[{d}]' for d in dims]
15
-
16
- elif method == 'pca':
17
- # 方法2: 使用PCA的前两个主成分
18
- pca = PCA(n_components=2)
19
- z_2d = pca.fit_transform(z_points)
20
- delta_z_2d = pca.transform(z_points + delta_z) - z_2d
21
- dim_names = ['PC1', 'PC2']
22
-
23
- elif method == 'manual':
24
- # 方法3: 手动选择感兴趣的维度
25
- dims = [0, 1] # 选择前两个维度
26
- z_2d = z_points[:, dims]
27
- delta_z_2d = delta_z[:, dims]
28
- dim_names = [f'z[{d}]' for d in dims]
29
-
30
- elif method == 'umap':
31
- ad = sc.AnnData(np.vstack([z_points, z_points+delta_z]))
32
- sc.pp.neighbors(ad)
33
- sc.tl.umap(ad)
34
- z_2d = ad[:z_points.shape[0]].obsm['X_umap']
35
- delta_z_2d = ad[z_points.shape[0]:].obsm['X_umap'] - z_2d
36
- dim_names = ['UMAP1', 'UMAP2']
37
-
38
- # 绘制quiver图
39
- plt.figure(figsize=figsize, dpi=dpi)
40
- plt.quiver(z_2d[:, 0], z_2d[:, 1],
41
- delta_z_2d[:, 0], delta_z_2d[:, 1],
42
- angles='xy', scale_units='xy', scale=1,
43
- color='blue', alpha=0.6, width=0.005)
44
-
45
- plt.scatter(z_2d[:, 0], z_2d[:, 1], c='gray', alpha=0.5, s=10)
46
- plt.xlabel(dim_names[0])
47
- plt.ylabel(dim_names[1])
48
- plt.title(f"Latent Space Movement ({method} projection)")
49
- plt.grid(alpha=0.3)
50
- plt.show()
51
-
52
- return z_2d, delta_z_2d
File without changes
File without changes
File without changes
File without changes