SURE-tools 2.1.11__py3-none-any.whl → 2.1.13__py3-none-any.whl

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.

SURE/flow/plot_quiver.py CHANGED
@@ -4,6 +4,7 @@ from sklearn.decomposition import PCA
4
4
  import scanpy as sc
5
5
  from matplotlib.colors import ListedColormap
6
6
 
7
+
7
8
  def plot_quiver(z_points, delta_z, method='pca', figsize=(6,4), dpi=200,
8
9
  subsample=None, color_by=None, colormap='viridis',
9
10
  arrow_scale=1.0, arrow_width=0.005, alpha=0.8):
@@ -23,96 +24,131 @@ def plot_quiver(z_points, delta_z, method='pca', figsize=(6,4), dpi=200,
23
24
  arrow_width: 箭头宽度
24
25
  alpha: 透明度
25
26
  """
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
27
34
  if subsample is not None and len(z_points) > subsample:
28
- idx = np.random.choice(len(z_points), subsample, replace=False)
29
- z_points = z_points[idx]
30
- delta_z = delta_z[idx]
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]
31
38
  if color_by is not None:
32
- color_by = color_by[idx]
39
+ color_by_quiver = color_by[quiver_indices]
40
+ else:
41
+ color_by_quiver = None
42
+ color_by_quiver=None
43
+ else:
44
+ z_points_quiver = z_points
45
+ delta_z_quiver = delta_z
46
+ color_by_quiver = color_by
47
+ color_by_quiver=None
33
48
 
34
- # 降维投影
49
+ # 降维投影(使用所有数据)
35
50
  if method == 'variance':
36
- variances = np.var(z_points, axis=0)
51
+ variances = np.var(original_z_points, axis=0)
37
52
  dims = np.argsort(variances)[-2:]
38
- z_2d = z_points[:, dims]
39
- delta_z_2d = delta_z[:, dims]
53
+ z_2d_all = original_z_points[:, dims]
54
+ z_2d_quiver = z_points_quiver[:, dims]
55
+ delta_z_2d = delta_z_quiver[:, dims]
40
56
  dim_names = [f'z[{d}]' for d in dims]
41
57
 
42
58
  elif method == 'pca':
43
59
  pca = PCA(n_components=2)
44
- z_2d = pca.fit_transform(z_points)
45
- delta_z_2d = pca.transform(z_points + delta_z) - z_2d
60
+ z_2d_all = pca.fit_transform(original_z_points)
61
+ z_2d_quiver = pca.transform(z_points_quiver)
62
+ delta_z_2d = pca.transform(z_points_quiver + delta_z_quiver) - z_2d_quiver
46
63
  dim_names = ['PC1', 'PC2']
47
64
 
48
65
  elif method == 'manual':
49
66
  dims = [0, 1]
50
- z_2d = z_points[:, dims]
51
- delta_z_2d = delta_z[:, dims]
67
+ z_2d_all = original_z_points[:, dims]
68
+ z_2d_quiver = z_points_quiver[:, dims]
69
+ delta_z_2d = delta_z_quiver[:, dims]
52
70
  dim_names = [f'z[{d}]' for d in dims]
53
71
 
54
72
  elif method == 'umap':
55
- ad = sc.AnnData(np.vstack([z_points, z_points+delta_z]))
73
+ # 使用所有数据进行UMAP降维
74
+ ad = sc.AnnData(np.vstack([original_z_points, original_z_points+original_delta_z]))
56
75
  sc.pp.neighbors(ad)
57
76
  sc.tl.umap(ad)
58
- z_2d = ad[:z_points.shape[0]].obsm['X_umap']
59
- delta_z_2d = ad[z_points.shape[0]:].obsm['X_umap'] - z_2d
77
+ z_2d_all = ad[:len(original_z_points)].obsm['X_umap']
78
+ z_2d_quiver = z_2d_all[quiver_indices] if quiver_indices is not None else z_2d_all
79
+ 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
60
80
  dim_names = ['UMAP1', 'UMAP2']
61
81
 
62
- # 颜色处理
63
- if color_by is not None:
82
+ # 颜色处理(散点图使用所有数据,quiver使用采样数据)
83
+ if original_color_by is not None:
64
84
  if isinstance(colormap, str):
65
85
  cmap = plt.get_cmap(colormap)
66
86
  else:
67
87
  cmap = colormap
68
88
 
69
- if color_by.dtype.kind in ['i', 'f']: # 数值型标签
70
- colors = cmap(color_by / max(color_by.max(), 1e-8))
89
+ if original_color_by.dtype.kind in ['i', 'f']: # 数值型标签
90
+ # 所有数据的颜色
91
+ colors_all = cmap(original_color_by / max(original_color_by.max(), 1e-8))
92
+ # quiver数据的颜色
93
+ if color_by_quiver is not None:
94
+ colors_quiver = cmap(color_by_quiver / max(color_by_quiver.max(), 1e-8))
95
+ else:
96
+ colors_quiver = 'blue'
71
97
  cbar_label = 'Numeric Label'
72
98
  else: # 类别型标签
73
- unique_labels = np.unique(color_by)
99
+ unique_labels = np.unique(original_color_by)
74
100
  color_map = {label: cmap(i/len(unique_labels))
75
101
  for i, label in enumerate(unique_labels)}
76
- colors = [color_map[label] for label in color_by]
102
+ colors_all = [color_map[label] for label in original_color_by]
103
+ if color_by_quiver is not None:
104
+ colors_quiver = [color_map[label] for label in color_by_quiver]
105
+ else:
106
+ colors_quiver = 'blue'
77
107
  cbar_label = 'Class Label'
78
108
  else:
79
- colors = 'blue'
109
+ colors_all = 'gray'
110
+ colors_quiver = 'blue'
80
111
 
81
112
  # 绘制
82
113
  plt.figure(figsize=figsize, dpi=dpi)
83
114
 
84
- # 绘制quiver(分颜色组绘制以获得正确图例)
85
- if color_by is not None and isinstance(color_by[0], str):
86
- for label in np.unique(color_by):
87
- mask = color_by == label
88
- plt.quiver(z_2d[mask, 0], z_2d[mask, 1],
115
+ # 1. 首先绘制所有数据点的散点图
116
+ plt.scatter(z_2d_all[:, 0], z_2d_all[:, 1],
117
+ c=colors_all, alpha=0.3, s=5, label='All data points')
118
+
119
+ # 2. 绘制quiver(仅采样数据)
120
+ if color_by_quiver is not None and isinstance(color_by_quiver[0], str):
121
+ for label in np.unique(color_by_quiver):
122
+ mask = color_by_quiver == label
123
+ plt.quiver(z_2d_quiver[mask, 0], z_2d_quiver[mask, 1],
89
124
  delta_z_2d[mask, 0], delta_z_2d[mask, 1],
90
125
  angles='xy', scale_units='xy', scale=1.0/arrow_scale,
91
- color=colors[mask], width=arrow_width, alpha=alpha,
92
- label=str(label))
126
+ color=colors_quiver[mask], width=arrow_width, alpha=alpha,
127
+ label=f'{label} (movement)')
93
128
  plt.legend()
94
129
  else:
95
- q = plt.quiver(z_2d[:, 0], z_2d[:, 1],
130
+ q = plt.quiver(z_2d_quiver[:, 0], z_2d_quiver[:, 1],
96
131
  delta_z_2d[:, 0], delta_z_2d[:, 1],
97
132
  angles='xy', scale_units='xy', scale=1.0/arrow_scale,
98
- color=colors, width=arrow_width, alpha=alpha)
133
+ color=colors_quiver, width=arrow_width, alpha=alpha,
134
+ label='Movement vectors')
99
135
 
100
136
  # 添加颜色条(数值型标签)
101
- if color_by is not None and color_by.dtype.kind in ['i', 'f']:
137
+ if original_color_by is not None and original_color_by.dtype.kind in ['i', 'f']:
102
138
  plt.colorbar(plt.cm.ScalarMappable(
103
- norm=plt.Normalize(color_by.min(), color_by.max()),
139
+ norm=plt.Normalize(original_color_by.min(), original_color_by.max()),
104
140
  cmap=cmap), label=cbar_label)
105
141
 
106
142
  # 美化图形
107
- plt.scatter(z_2d[:, 0], z_2d[:, 1], c='gray', alpha=0.3, s=5)
108
143
  plt.xlabel(dim_names[0])
109
144
  plt.ylabel(dim_names[1])
110
- plt.title(f"Latent Space Movement ({method} projection)")
145
+ plt.title(f"Latent Space Movement ({method} projection)\n{len(z_points_quiver)}/{len(original_z_points)} points with vectors")
111
146
  plt.grid(alpha=0.2)
147
+ plt.legend()
112
148
  plt.tight_layout()
113
149
  plt.show()
114
150
 
115
- return z_2d, delta_z_2d
151
+ return z_2d_all, z_2d_quiver, delta_z_2d
116
152
 
117
153
  def plot_quiver_old(z_points, delta_z, method='pca', figsize=(6,4), dpi=200):
118
154
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: SURE-tools
3
- Version: 2.1.11
3
+ Version: 2.1.13
4
4
  Summary: Succinct Representation of Single Cells
5
5
  Home-page: https://github.com/ZengFLab/SURE
6
6
  Author: Feng Zeng
@@ -11,7 +11,7 @@ SURE/codebook/__init__.py,sha256=2T5gjp8JIaBayrXAnOJYSebQHsWprOs87difpR1OPNw,243
11
11
  SURE/codebook/codebook.py,sha256=ZlN6gRX9Gj2D2u3P5KeOsbZri0MoMAiJo9lNeL-MK-I,17117
12
12
  SURE/flow/__init__.py,sha256=rsAjYsh1xVIrxBCuwOE0Q_6N5th1wBgjJceV0ABPG3c,183
13
13
  SURE/flow/flow_stats.py,sha256=3F3waCuEbIQ7bsiGga4cUvJphYdWA307SyGwEh8EzM8,10514
14
- SURE/flow/plot_quiver.py,sha256=FyFc4lSRuY2bMmPMQtPsfwAJ7xhw7XD_e_OCVWa4ZeM,6083
14
+ SURE/flow/plot_quiver.py,sha256=wC42yLKfXYOGrrd4u9AbZS_6QiPUJ9QBXaOso55LjdA,8110
15
15
  SURE/flow/quiver.py,sha256=_euFqSaRrDoZ_oOabOx20LOoUTJ__XPhLW-vzLNQfAo,1859
16
16
  SURE/perturb/__init__.py,sha256=ouxShhbxZM4r5Gf7GmKiutrsmtyq7QL8rHjhgF0BU08,32
17
17
  SURE/perturb/perturb.py,sha256=CqO3xPfNA3cG175tadDidKvGsTu_yKfJRRLn_93awKM,3303
@@ -19,9 +19,9 @@ SURE/utils/__init__.py,sha256=Htqv4KqVKcRiaaTBsR-6yZ4LSlbhbzutjNKXGD9-uds,660
19
19
  SURE/utils/custom_mlp.py,sha256=07TYX1HgxfEjb_3i5MpiZfNhOhx3dKntuwGkrpteWiM,7036
20
20
  SURE/utils/queue.py,sha256=E_5PA5EWcBoGAZj8BkKQnkCK0p4C-4-xcTPqdIXaPXU,1892
21
21
  SURE/utils/utils.py,sha256=IUHjDDtYaAYllCWsZyIzqQwaLul6fJRvHRH4vIYcR-c,8462
22
- sure_tools-2.1.11.dist-info/licenses/LICENSE,sha256=TFHKwmrAViXQbSX5W-NDItkWFjm45HWOeUniDrqmnu0,1065
23
- sure_tools-2.1.11.dist-info/METADATA,sha256=aUC_xD4vGERur0cFsccW59T1ufKKN7mbSDMHMJXHBko,2651
24
- sure_tools-2.1.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
25
- sure_tools-2.1.11.dist-info/entry_points.txt,sha256=-nJI8rVe_qqrR0HmfAODzj-JNfEqCcSsyVh6okSqyHk,83
26
- sure_tools-2.1.11.dist-info/top_level.txt,sha256=BtFTebdiJeqra4r6mm-uEtwVRFLZ_IjYsQ7OnalrOvY,5
27
- sure_tools-2.1.11.dist-info/RECORD,,
22
+ sure_tools-2.1.13.dist-info/licenses/LICENSE,sha256=TFHKwmrAViXQbSX5W-NDItkWFjm45HWOeUniDrqmnu0,1065
23
+ sure_tools-2.1.13.dist-info/METADATA,sha256=ZcsPEH_ed7pp9FaJCAJClFC4EeFY3l7TGgEFg7yRTYM,2651
24
+ sure_tools-2.1.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
25
+ sure_tools-2.1.13.dist-info/entry_points.txt,sha256=-nJI8rVe_qqrR0HmfAODzj-JNfEqCcSsyVh6okSqyHk,83
26
+ sure_tools-2.1.13.dist-info/top_level.txt,sha256=BtFTebdiJeqra4r6mm-uEtwVRFLZ_IjYsQ7OnalrOvY,5
27
+ sure_tools-2.1.13.dist-info/RECORD,,