scMultiChat 0.1.2__tar.gz → 0.2.0__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.
Files changed (50) hide show
  1. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Plot/Visualization.py +467 -7
  2. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/__init__.py +2 -2
  3. scmultichat-0.2.0/PKG-INFO +30 -0
  4. scmultichat-0.2.0/requirements.txt +18 -0
  5. scmultichat-0.2.0/scMultiChat.egg-info/PKG-INFO +30 -0
  6. scmultichat-0.2.0/scMultiChat.egg-info/requires.txt +18 -0
  7. {scmultichat-0.1.2 → scmultichat-0.2.0}/setup.py +1 -1
  8. scmultichat-0.1.2/PKG-INFO +0 -30
  9. scmultichat-0.1.2/requirements.txt +0 -18
  10. scmultichat-0.1.2/scMultiChat.egg-info/PKG-INFO +0 -30
  11. scmultichat-0.1.2/scMultiChat.egg-info/requires.txt +0 -18
  12. {scmultichat-0.1.2 → scmultichat-0.2.0}/MANIFEST.in +0 -0
  13. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Analysis/Intra_strength.py +0 -0
  14. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Analysis/Processing.py +0 -0
  15. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Analysis/__init__.py +0 -0
  16. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/__init__.py +0 -0
  17. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/_settings.py +0 -0
  18. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/_utils.py +0 -0
  19. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/_version.py +0 -0
  20. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/plotting/__init__.py +0 -0
  21. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/plotting/_palettes.py +0 -0
  22. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/plotting/_plot.py +0 -0
  23. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/plotting/_post_training.py +0 -0
  24. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/plotting/_utils.py +0 -0
  25. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/preprocessing/__init__.py +0 -0
  26. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/preprocessing/_general.py +0 -0
  27. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/preprocessing/_pca.py +0 -0
  28. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/preprocessing/_qc.py +0 -0
  29. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/preprocessing/_utils.py +0 -0
  30. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/preprocessing/_variable_genes.py +0 -0
  31. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/readwrite.py +0 -0
  32. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/tools/__init__.py +0 -0
  33. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/tools/_gene_scores.py +0 -0
  34. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/tools/_general.py +0 -0
  35. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/tools/_integration.py +0 -0
  36. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/tools/_pbg.py +0 -0
  37. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/tools/_post_training.py +0 -0
  38. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/tools/_umap.py +0 -0
  39. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/tools/_utils.py +0 -0
  40. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Model/Layers.py +0 -0
  41. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Model/__init__.py +0 -0
  42. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Model/model_training.py +0 -0
  43. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Model/modules.py +0 -0
  44. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Model/utilities.py +0 -0
  45. {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Plot/__init__.py +0 -0
  46. {scmultichat-0.1.2 → scmultichat-0.2.0}/pyproject.toml +0 -0
  47. {scmultichat-0.1.2 → scmultichat-0.2.0}/scMultiChat.egg-info/SOURCES.txt +0 -0
  48. {scmultichat-0.1.2 → scmultichat-0.2.0}/scMultiChat.egg-info/dependency_links.txt +0 -0
  49. {scmultichat-0.1.2 → scmultichat-0.2.0}/scMultiChat.egg-info/top_level.txt +0 -0
  50. {scmultichat-0.1.2 → scmultichat-0.2.0}/setup.cfg +0 -0
@@ -11,6 +11,7 @@ from itertools import product
11
11
  from scipy import stats
12
12
 
13
13
 
14
+
14
15
 
15
16
 
16
17
  def get_sender_adj(Nei_adj, cell_type):
@@ -861,23 +862,23 @@ def plot_two_hop_signaling(
861
862
 
862
863
  # background cells
863
864
  plt.scatter(
864
- coord_df['y'],
865
865
  coord_df['x'],
866
+ coord_df['y'],
866
867
  c=coord_df['color'],
867
868
  alpha=alpha,
868
869
  s=point_size,
869
870
  linewidths=0
870
871
  )
871
872
 
872
- plt.gca().invert_yaxis()
873
+ # plt.gca().invert_yaxis()
873
874
 
874
875
  # first hop (X → Relay)
875
876
  for _, row in cur_xr.iterrows():
876
877
  lw = max(0.5, row['score'] * arrow_scale)
877
878
 
878
879
  arrow = FancyArrowPatch(
879
- (row['sender_y'], row['sender_x']),
880
- (row['receiver_y'], row['receiver_x']),
880
+ (row['sender_x'], row['sender_y']),
881
+ (row['receiver_x'], row['receiver_y']),
881
882
  connectionstyle=f"arc3,rad={rad}",
882
883
  arrowstyle=ArrowStyle("Simple", head_length=1.8, head_width=2, tail_width=0.01),
883
884
  color='#13393E',
@@ -891,8 +892,8 @@ def plot_two_hop_signaling(
891
892
  lw = max(0.5, row['score'] * arrow_scale)
892
893
 
893
894
  arrow = FancyArrowPatch(
894
- (row['sender_y'], row['sender_x']),
895
- (row['receiver_y'], row['receiver_x']),
895
+ (row['sender_x'], row['sender_y']),
896
+ (row['receiver_x'], row['receiver_y']),
896
897
  connectionstyle=f"arc3,rad={rad}",
897
898
  arrowstyle=ArrowStyle("Simple", head_length=1.8, head_width=2, tail_width=0.01),
898
899
  color='#B32142',
@@ -1043,4 +1044,463 @@ def plot_effective_two_hop_signaling(
1043
1044
  # ===== 8. Title =====
1044
1045
  plt.title(f'Effective two-hop signaling: \n{pair1} → {pair2}')
1045
1046
 
1046
- plt.show()
1047
+ plt.show()
1048
+
1049
+
1050
+ def build_gene_relay_two_hop_events(sig_path, focus_gene):
1051
+ """
1052
+ Build two-hop signaling events centered on a focus gene.
1053
+
1054
+ Logic:
1055
+ 1. First hop: X -> Relay, where path_symbol ends with focus_gene.
1056
+ 2. Second hop: Relay -> Y, where path_symbol starts with focus_gene.
1057
+ 3. Merge by Relay cell.
1058
+
1059
+ Parameters
1060
+ ----------
1061
+ sig_path : pd.DataFrame
1062
+ Significant signaling path table.
1063
+ Required columns:
1064
+ from_cell, to_cell, source, target, path_symbol, comm_score, z_score
1065
+
1066
+ focus_gene : str
1067
+ Focus gene used as relay signaling molecule, e.g. 'Hgf'.
1068
+
1069
+ Returns
1070
+ -------
1071
+ merged_df : pd.DataFrame
1072
+ Two-hop signaling events joined by relay cell.
1073
+ """
1074
+
1075
+ # First hop: upstream signal ending with focus_gene
1076
+ one_hop_sig_path = sig_path[
1077
+ sig_path["path_symbol"].str.endswith(focus_gene, na=False)
1078
+ ].copy()
1079
+
1080
+ # Second hop: downstream signal starting with focus_gene
1081
+ two_hop_sig_path = sig_path[
1082
+ sig_path["path_symbol"].str.startswith(focus_gene, na=False)
1083
+ ].copy()
1084
+
1085
+ one_hop_sig_path.rename(
1086
+ columns={
1087
+ "from_cell": "X_name",
1088
+ "to_cell": "Relay_name",
1089
+ "source": "X_Source",
1090
+ "target": "Relay_Target",
1091
+ "path_symbol": "X_Path_Symbol",
1092
+ "comm_score": "X_Comm_Score",
1093
+ "z_score": "X_Z_Score",
1094
+ },
1095
+ inplace=True
1096
+ )
1097
+
1098
+ merged_df = pd.merge(
1099
+ left=one_hop_sig_path,
1100
+ right=two_hop_sig_path,
1101
+ left_on="Relay_name",
1102
+ right_on="from_cell",
1103
+ how="inner"
1104
+ )
1105
+
1106
+ return merged_df
1107
+
1108
+
1109
+ def plot_two_hop_cell_identity(
1110
+ focus_gene,
1111
+ base_path=None,
1112
+ coord_df=None,
1113
+ coord=None,
1114
+ cell_type=None,
1115
+ color_map=None,
1116
+ merged_df=None,
1117
+ figsize=(18, 5),
1118
+ bg_color="#D3D3D3",
1119
+ bg_size=15,
1120
+ bg_alpha=1,
1121
+ role_size=25,
1122
+ role_alpha=0.8
1123
+ ):
1124
+ """
1125
+ Plot source / relay / target cell identities for two-hop signaling events.
1126
+
1127
+ Parameters
1128
+ ----------
1129
+ focus_gene : str
1130
+ Gene name, e.g. 'Vegfa'.
1131
+ base_path : str
1132
+ Dataset base path.
1133
+ coord_df : pd.DataFrame, optional
1134
+ Coordinate dataframe with x, y, color columns.
1135
+ coord : pd.DataFrame, optional
1136
+ Coordinate dataframe with x, y columns. Used when coord_df is not given.
1137
+ cell_type : pd.DataFrame, optional
1138
+ Cell type annotation with column 'cell_type'. Used when coord_df is not given.
1139
+ color_map : dict, optional
1140
+ Cell type color map. Used when coord_df is not given.
1141
+ merged_df : pd.DataFrame, optional
1142
+ Preloaded merged two-hop event dataframe.
1143
+ """
1144
+
1145
+ # ===== Load merged two-hop event data =====
1146
+ if merged_df is None:
1147
+ if base_path is None:
1148
+ raise ValueError("Please provide either merged_df or base_path + focus_gene.")
1149
+ else:
1150
+ print("Loading merged two-hop event data...")
1151
+ merged_file = os.path.join(base_path, f"{focus_gene}_merged_data.csv")
1152
+ merged_df = pd.read_csv(merged_file)
1153
+
1154
+ df = merged_df.copy()
1155
+
1156
+ # ===== Build coord_df if not provided =====
1157
+ if coord_df is None:
1158
+ if coord is None or cell_type is None or color_map is None:
1159
+ raise ValueError("Please provide either coord_df, or coord + cell_type + color_map.")
1160
+
1161
+ coord_df = coord.copy()
1162
+
1163
+ if "cell_type" not in cell_type.columns and "celltype" in cell_type.columns:
1164
+ cell_type = cell_type.rename(columns={"celltype": "cell_type"})
1165
+
1166
+ coord_df["color"] = cell_type.loc[coord_df.index, "cell_type"].map(color_map)
1167
+
1168
+ # ===== Compatible column names =====
1169
+ source_col = "X_name" if "X_name" in df.columns else "X_Name"
1170
+ relay_col = "Relay_name" if "Relay_name" in df.columns else "Relay_Name"
1171
+
1172
+ if "to_cell" in df.columns:
1173
+ target_col = "to_cell"
1174
+ elif "Y_name" in df.columns:
1175
+ target_col = "Y_name"
1176
+ else:
1177
+ target_col = "Y_Name"
1178
+
1179
+ # ===== Extract cells =====
1180
+ source_cells = set(df[source_col].dropna())
1181
+ relay_cells = set(df[relay_col].dropna())
1182
+ target_cells = set(df[target_col].dropna())
1183
+
1184
+ # ===== Add role flags =====
1185
+ plot_df = coord_df.copy()
1186
+ plot_df["is_source"] = plot_df.index.isin(source_cells)
1187
+ plot_df["is_relay"] = plot_df.index.isin(relay_cells)
1188
+ plot_df["is_target"] = plot_df.index.isin(target_cells)
1189
+
1190
+ print("source cells:", plot_df["is_source"].sum())
1191
+ print("relay cells:", plot_df["is_relay"].sum())
1192
+ print("target cells:", plot_df["is_target"].sum())
1193
+
1194
+ # ===== Plot =====
1195
+ fig, axes = plt.subplots(1, 3, figsize=figsize)
1196
+
1197
+ role_info = [
1198
+ ("Source", "is_source"),
1199
+ ("Relay", "is_relay"),
1200
+ ("Target", "is_target"),
1201
+ ]
1202
+
1203
+ for ax, (title, flag) in zip(axes, role_info):
1204
+ ax.scatter(
1205
+ plot_df["x"], plot_df["y"],
1206
+ color=bg_color,
1207
+ s=bg_size,
1208
+ alpha=bg_alpha
1209
+ )
1210
+
1211
+ sub = plot_df[plot_df[flag]]
1212
+
1213
+ ax.scatter(
1214
+ sub["x"], sub["y"],
1215
+ c=sub["color"],
1216
+ s=role_size,
1217
+ alpha=role_alpha
1218
+ )
1219
+
1220
+ # ax.invert_yaxis()
1221
+ ax.set_title(title)
1222
+ ax.set_xlabel("X")
1223
+ ax.set_ylabel("Y")
1224
+
1225
+ plt.tight_layout()
1226
+ plt.show()
1227
+
1228
+ return plot_df, fig, axes
1229
+
1230
+
1231
+ def plot_two_hop_cell_identity_combined(
1232
+ focus_gene,
1233
+ base_path=None,
1234
+ coord_df=None,
1235
+ coord=None,
1236
+ cell_type=None,
1237
+ color_map=None,
1238
+ merged_df=None,
1239
+ figsize=(6, 5),
1240
+ bg_color="#D3D3D3",
1241
+ bg_size=15,
1242
+ bg_alpha=1,
1243
+ marker_map=None,
1244
+ size_map=None,
1245
+ linewidth_map=None,
1246
+ role_color_map=None,
1247
+ role_alpha=0.9,
1248
+ invert_yaxis=False,
1249
+ save=False,
1250
+ fig_dir=None
1251
+ ):
1252
+ """
1253
+ Plot source / relay / target cell identities in one combined panel.
1254
+
1255
+ Parameters
1256
+ ----------
1257
+ focus_gene : str
1258
+ Gene name, e.g. 'Vegfa'.
1259
+ base_path : str, optional
1260
+ Dataset base path. Used to load {focus_gene}_merged_data.csv if merged_df is not provided.
1261
+ coord_df : pd.DataFrame, optional
1262
+ Coordinate dataframe with x, y, and color columns.
1263
+ coord : pd.DataFrame, optional
1264
+ Coordinate dataframe with x, y columns. Used when coord_df is not given.
1265
+ cell_type : pd.DataFrame, optional
1266
+ Cell type annotation with column 'cell_type'. Used when coord_df is not given.
1267
+ color_map : dict, optional
1268
+ Cell type color map. Used when coord_df is not given.
1269
+ merged_df : pd.DataFrame, optional
1270
+ Preloaded merged two-hop event dataframe.
1271
+ save : bool
1272
+ Whether to save figure.
1273
+ fig_dir : str, optional
1274
+ Directory for saving figure if save=True.
1275
+ """
1276
+
1277
+ # ===== Load merged two-hop event data =====
1278
+ if merged_df is None:
1279
+ if base_path is None:
1280
+ raise ValueError("Please provide either merged_df or base_path + focus_gene.")
1281
+ print("Loading merged two-hop event data...")
1282
+ merged_file = os.path.join(base_path, f"{focus_gene}_merged_data.csv")
1283
+ merged_df = pd.read_csv(merged_file)
1284
+
1285
+ df = merged_df.copy()
1286
+
1287
+ # ===== Build coord_df if not provided =====
1288
+ if coord_df is None:
1289
+ if coord is None or cell_type is None or color_map is None:
1290
+ raise ValueError("Please provide either coord_df, or coord + cell_type + color_map.")
1291
+
1292
+ coord_df = coord.copy()
1293
+
1294
+ if "cell_type" not in cell_type.columns and "celltype" in cell_type.columns:
1295
+ cell_type = cell_type.rename(columns={"celltype": "cell_type"})
1296
+
1297
+ coord_df["color"] = cell_type.loc[coord_df.index, "cell_type"].map(color_map)
1298
+
1299
+ # ===== Compatible column names =====
1300
+ source_col = "X_name" if "X_name" in df.columns else "X_Name"
1301
+ relay_col = "Relay_name" if "Relay_name" in df.columns else "Relay_Name"
1302
+
1303
+ if "to_cell" in df.columns:
1304
+ target_col = "to_cell"
1305
+ elif "Y_name" in df.columns:
1306
+ target_col = "Y_name"
1307
+ else:
1308
+ target_col = "Y_Name"
1309
+
1310
+ # ===== Extract cells =====
1311
+ source_cells = set(df[source_col].dropna())
1312
+ relay_cells = set(df[relay_col].dropna())
1313
+ target_cells = set(df[target_col].dropna())
1314
+
1315
+ # ===== Add role flags =====
1316
+ plot_df = coord_df.copy()
1317
+ plot_df["is_source"] = plot_df.index.isin(source_cells)
1318
+ plot_df["is_relay"] = plot_df.index.isin(relay_cells)
1319
+ plot_df["is_target"] = plot_df.index.isin(target_cells)
1320
+
1321
+ print("source cells:", plot_df["is_source"].sum())
1322
+ print("relay cells:", plot_df["is_relay"].sum())
1323
+ print("target cells:", plot_df["is_target"].sum())
1324
+
1325
+ # ===== Default plotting style =====
1326
+ if marker_map is None:
1327
+ marker_map = {
1328
+ "source": "^",
1329
+ "relay": "+",
1330
+ "target": "o"
1331
+ }
1332
+
1333
+ if size_map is None:
1334
+ size_map = {
1335
+ "source": 40,
1336
+ "relay": 70,
1337
+ "target": 40
1338
+ }
1339
+
1340
+ if linewidth_map is None:
1341
+ linewidth_map = {
1342
+ "source": 0.8,
1343
+ "relay": 1.5,
1344
+ "target": 0.8
1345
+ }
1346
+
1347
+ if role_color_map is None:
1348
+ role_color_map = {
1349
+ "source": "#ab8adf",
1350
+ "relay": "#23bdf5",
1351
+ "target": "#fa7d8a"
1352
+ }
1353
+
1354
+ # ===== Plot =====
1355
+ fig, ax = plt.subplots(figsize=figsize)
1356
+
1357
+ # background
1358
+ ax.scatter(
1359
+ plot_df["x"], plot_df["y"],
1360
+ color=bg_color,
1361
+ s=bg_size,
1362
+ alpha=bg_alpha
1363
+ )
1364
+
1365
+ # overlay source / relay / target
1366
+ for role, flag in zip(
1367
+ ["source", "relay", "target"],
1368
+ ["is_source", "is_relay", "is_target"]
1369
+ ):
1370
+ sub = plot_df[plot_df[flag]]
1371
+
1372
+ if role == "relay":
1373
+ ax.scatter(
1374
+ sub["x"], sub["y"],
1375
+ c=role_color_map[role],
1376
+ s=size_map[role],
1377
+ marker=marker_map[role],
1378
+ linewidths=linewidth_map[role],
1379
+ alpha=role_alpha,
1380
+ label=role
1381
+ )
1382
+ else:
1383
+ ax.scatter(
1384
+ sub["x"], sub["y"],
1385
+ facecolors="none",
1386
+ edgecolors=role_color_map[role],
1387
+ s=size_map[role],
1388
+ marker=marker_map[role],
1389
+ linewidths=linewidth_map[role],
1390
+ alpha=role_alpha,
1391
+ label=role
1392
+ )
1393
+
1394
+ if invert_yaxis:
1395
+ ax.invert_yaxis()
1396
+
1397
+ ax.legend(title="Role")
1398
+ ax.set_title(f"{focus_gene} - Cell Identity (Combined)")
1399
+ ax.set_xlabel("X")
1400
+ ax.set_ylabel("Y")
1401
+
1402
+ plt.tight_layout()
1403
+ plt.show()
1404
+
1405
+ return plot_df, fig, ax
1406
+
1407
+
1408
+ def plot_top_signal_ranked_abundance(
1409
+ focus_cell,
1410
+ cell_type,
1411
+ sig_pair_res=None,
1412
+ sig_lrp=None,
1413
+ top_n=20,
1414
+ figsize=(12, 6),
1415
+ palette="GnBu",
1416
+ save=False,
1417
+ figpath=None
1418
+ ):
1419
+ """
1420
+ Plot top abundant significant paths targeting a focus cell type.
1421
+
1422
+ Parameters
1423
+ ----------
1424
+ focus_cell : str
1425
+ Focus cell type, e.g. 'Astro'.
1426
+ cell_type : pd.DataFrame
1427
+ Cell annotation dataframe with column 'cell_type'.
1428
+ sig_pair_res : pd.DataFrame
1429
+ Significant path/pair result dataframe.
1430
+ sig_lrp : pd.DataFrame, optional
1431
+ Alias for sig_pair_res. Kept for compatibility.
1432
+ top_n : int
1433
+ Number of top paths to show.
1434
+ figsize : tuple
1435
+ Figure size.
1436
+ palette : str
1437
+ Seaborn palette.
1438
+ save : bool
1439
+ Whether to save figure.
1440
+ figpath : str
1441
+ Save path without extension.
1442
+ """
1443
+
1444
+ if sig_pair_res is None:
1445
+ if sig_lrp is None:
1446
+ raise ValueError("Please provide sig_pair_res or sig_lrp.")
1447
+ sig_pair_res = sig_lrp
1448
+
1449
+ if "cell_type" not in cell_type.columns and "celltype" in cell_type.columns:
1450
+ cell_type = cell_type.rename(columns={"celltype": "cell_type"})
1451
+
1452
+ focus_samples = cell_type[cell_type["cell_type"] == focus_cell].index.tolist()
1453
+
1454
+ if len(focus_samples) == 0:
1455
+ raise ValueError(f"No cells found for focus_cell: {focus_cell}")
1456
+
1457
+ if "to_cell" not in sig_pair_res.columns:
1458
+ raise ValueError("sig_pair_res must contain column 'to_cell'.")
1459
+
1460
+ if "path_symbol" not in sig_pair_res.columns:
1461
+ raise ValueError("sig_pair_res must contain column 'path_symbol'.")
1462
+
1463
+ focus_sig_lrp = sig_pair_res[
1464
+ sig_pair_res["to_cell"].isin(focus_samples)
1465
+ ].copy()
1466
+
1467
+ path_counts = focus_sig_lrp["path_symbol"].value_counts()
1468
+
1469
+ if len(path_counts) == 0:
1470
+ raise ValueError(f"No significant paths targeting {focus_cell} cells.")
1471
+
1472
+ top_n = min(top_n, len(path_counts))
1473
+ plot_counts = path_counts.head(top_n)
1474
+
1475
+ plt.figure(figsize=figsize)
1476
+
1477
+ ax = sns.barplot(
1478
+ x=plot_counts.index,
1479
+ y=plot_counts.values,
1480
+ hue=plot_counts.values,
1481
+ palette=palette,
1482
+ legend=False
1483
+ )
1484
+
1485
+ plt.title(
1486
+ f"Communication abundance of significant signals targeting {focus_cell}",
1487
+ fontsize=14
1488
+ )
1489
+ plt.xlabel("Communication signals", fontsize=12)
1490
+ plt.ylabel("Communication abundance (n)", fontsize=12)
1491
+ plt.xticks(rotation=45, ha="right")
1492
+
1493
+ for p in ax.patches:
1494
+ ax.annotate(
1495
+ f"{int(p.get_height())}",
1496
+ (p.get_x() + p.get_width() / 2., p.get_height()),
1497
+ ha="center",
1498
+ va="center",
1499
+ xytext=(0, 5),
1500
+ textcoords="offset points"
1501
+ )
1502
+
1503
+ plt.tight_layout()
1504
+ plt.show()
1505
+
1506
+ return focus_sig_lrp, path_counts
@@ -1,6 +1,6 @@
1
1
  """
2
2
  MultiChat
3
- # Version: 0.1.1
3
+ # Version: 0.2.0
4
4
  # Author: Caiwei Zhen
5
5
  """
6
6
 
@@ -9,5 +9,5 @@ from .Analysis import Intra_strength as tl
9
9
  from .Analysis import Processing as pp
10
10
  from .Plot import Visualization as pl
11
11
 
12
- __version__ = "0.1.1"
12
+ __version__ = "0.2.0"
13
13
  __author__ = "Caiwei Zhen"
@@ -0,0 +1,30 @@
1
+ Metadata-Version: 2.4
2
+ Name: scMultiChat
3
+ Version: 0.2.0
4
+ Summary: Cell-cell communication using MultiChat
5
+ Author: Caiwei Zhen
6
+ Author-email: cwzhen@whu.edu.cn
7
+ Requires-Python: >=3.12
8
+ Requires-Dist: anndata==0.12.2
9
+ Requires-Dist: importlib_metadata==8.7.0
10
+ Requires-Dist: importlib_resources==6.5.2
11
+ Requires-Dist: matplotlib==3.10.5
12
+ Requires-Dist: networkx==3.5
13
+ Requires-Dist: numpy==2.2.0
14
+ Requires-Dist: pandas==2.3.2
15
+ Requires-Dist: polars==1.32.3
16
+ Requires-Dist: scanpy==1.11.4
17
+ Requires-Dist: scikit-learn==1.7.1
18
+ Requires-Dist: scikit-misc==0.5.1
19
+ Requires-Dist: scipy==1.16.1
20
+ Requires-Dist: seaborn==0.13.2
21
+ Requires-Dist: tables==3.10.2
22
+ Requires-Dist: torch==2.8.0
23
+ Requires-Dist: torchaudio==2.8.0
24
+ Requires-Dist: torchvision==0.23.0
25
+ Requires-Dist: tqdm==4.67.1
26
+ Dynamic: author
27
+ Dynamic: author-email
28
+ Dynamic: requires-dist
29
+ Dynamic: requires-python
30
+ Dynamic: summary
@@ -0,0 +1,18 @@
1
+ anndata==0.12.2
2
+ importlib_metadata==8.7.0
3
+ importlib_resources==6.5.2
4
+ matplotlib==3.10.5
5
+ networkx==3.5
6
+ numpy==2.2.0
7
+ pandas==2.3.2
8
+ polars==1.32.3
9
+ scanpy==1.11.4
10
+ scikit-learn==1.7.1
11
+ scikit-misc==0.5.1
12
+ scipy==1.16.1
13
+ seaborn==0.13.2
14
+ tables==3.10.2
15
+ torch==2.8.0
16
+ torchaudio==2.8.0
17
+ torchvision==0.23.0
18
+ tqdm==4.67.1
@@ -0,0 +1,30 @@
1
+ Metadata-Version: 2.4
2
+ Name: scMultiChat
3
+ Version: 0.2.0
4
+ Summary: Cell-cell communication using MultiChat
5
+ Author: Caiwei Zhen
6
+ Author-email: cwzhen@whu.edu.cn
7
+ Requires-Python: >=3.12
8
+ Requires-Dist: anndata==0.12.2
9
+ Requires-Dist: importlib_metadata==8.7.0
10
+ Requires-Dist: importlib_resources==6.5.2
11
+ Requires-Dist: matplotlib==3.10.5
12
+ Requires-Dist: networkx==3.5
13
+ Requires-Dist: numpy==2.2.0
14
+ Requires-Dist: pandas==2.3.2
15
+ Requires-Dist: polars==1.32.3
16
+ Requires-Dist: scanpy==1.11.4
17
+ Requires-Dist: scikit-learn==1.7.1
18
+ Requires-Dist: scikit-misc==0.5.1
19
+ Requires-Dist: scipy==1.16.1
20
+ Requires-Dist: seaborn==0.13.2
21
+ Requires-Dist: tables==3.10.2
22
+ Requires-Dist: torch==2.8.0
23
+ Requires-Dist: torchaudio==2.8.0
24
+ Requires-Dist: torchvision==0.23.0
25
+ Requires-Dist: tqdm==4.67.1
26
+ Dynamic: author
27
+ Dynamic: author-email
28
+ Dynamic: requires-dist
29
+ Dynamic: requires-python
30
+ Dynamic: summary
@@ -0,0 +1,18 @@
1
+ anndata==0.12.2
2
+ importlib_metadata==8.7.0
3
+ importlib_resources==6.5.2
4
+ matplotlib==3.10.5
5
+ networkx==3.5
6
+ numpy==2.2.0
7
+ pandas==2.3.2
8
+ polars==1.32.3
9
+ scanpy==1.11.4
10
+ scikit-learn==1.7.1
11
+ scikit-misc==0.5.1
12
+ scipy==1.16.1
13
+ seaborn==0.13.2
14
+ tables==3.10.2
15
+ torch==2.8.0
16
+ torchaudio==2.8.0
17
+ torchvision==0.23.0
18
+ tqdm==4.67.1
@@ -6,7 +6,7 @@ def read_requirements():
6
6
 
7
7
  setup(
8
8
  name="scMultiChat",
9
- version="0.1.2",
9
+ version="0.2.0",
10
10
  packages=find_packages(),
11
11
  install_requires=read_requirements(),
12
12
  author="Caiwei Zhen",
@@ -1,30 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: scMultiChat
3
- Version: 0.1.2
4
- Summary: Cell-cell communication using MultiChat
5
- Author: Caiwei Zhen
6
- Author-email: cwzhen@whu.edu.cn
7
- Requires-Python: >=3.12
8
- Requires-Dist: adjustText==1.3.0
9
- Requires-Dist: adjustText==1.3.0
10
- Requires-Dist: anndata==0.12.10
11
- Requires-Dist: attr==0.3.2
12
- Requires-Dist: kneed==0.8.6
13
- Requires-Dist: matplotlib==3.10.8
14
- Requires-Dist: numpy==2.4.4
15
- Requires-Dist: pandas==3.0.2
16
- Requires-Dist: plotly==6.3.0
17
- Requires-Dist: pybedtools==0.12.0
18
- Requires-Dist: scanpy==1.12.1
19
- Requires-Dist: scikit_learn==1.8.0
20
- Requires-Dist: scipy==1.17.1
21
- Requires-Dist: seaborn==0.13.2
22
- Requires-Dist: statsmodels==0.14.5
23
- Requires-Dist: tables==3.10.2
24
- Requires-Dist: tqdm==4.67.1
25
- Requires-Dist: umap_learn==0.5.9.post2
26
- Dynamic: author
27
- Dynamic: author-email
28
- Dynamic: requires-dist
29
- Dynamic: requires-python
30
- Dynamic: summary
@@ -1,18 +0,0 @@
1
- adjustText==1.3.0
2
- adjustText==1.3.0
3
- anndata==0.12.10
4
- attr==0.3.2
5
- kneed==0.8.6
6
- matplotlib==3.10.8
7
- numpy==2.4.4
8
- pandas==3.0.2
9
- plotly==6.3.0
10
- pybedtools==0.12.0
11
- scanpy==1.12.1
12
- scikit_learn==1.8.0
13
- scipy==1.17.1
14
- seaborn==0.13.2
15
- statsmodels==0.14.5
16
- tables==3.10.2
17
- tqdm==4.67.1
18
- umap_learn==0.5.9.post2
@@ -1,30 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: scMultiChat
3
- Version: 0.1.2
4
- Summary: Cell-cell communication using MultiChat
5
- Author: Caiwei Zhen
6
- Author-email: cwzhen@whu.edu.cn
7
- Requires-Python: >=3.12
8
- Requires-Dist: adjustText==1.3.0
9
- Requires-Dist: adjustText==1.3.0
10
- Requires-Dist: anndata==0.12.10
11
- Requires-Dist: attr==0.3.2
12
- Requires-Dist: kneed==0.8.6
13
- Requires-Dist: matplotlib==3.10.8
14
- Requires-Dist: numpy==2.4.4
15
- Requires-Dist: pandas==3.0.2
16
- Requires-Dist: plotly==6.3.0
17
- Requires-Dist: pybedtools==0.12.0
18
- Requires-Dist: scanpy==1.12.1
19
- Requires-Dist: scikit_learn==1.8.0
20
- Requires-Dist: scipy==1.17.1
21
- Requires-Dist: seaborn==0.13.2
22
- Requires-Dist: statsmodels==0.14.5
23
- Requires-Dist: tables==3.10.2
24
- Requires-Dist: tqdm==4.67.1
25
- Requires-Dist: umap_learn==0.5.9.post2
26
- Dynamic: author
27
- Dynamic: author-email
28
- Dynamic: requires-dist
29
- Dynamic: requires-python
30
- Dynamic: summary
@@ -1,18 +0,0 @@
1
- adjustText==1.3.0
2
- adjustText==1.3.0
3
- anndata==0.12.10
4
- attr==0.3.2
5
- kneed==0.8.6
6
- matplotlib==3.10.8
7
- numpy==2.4.4
8
- pandas==3.0.2
9
- plotly==6.3.0
10
- pybedtools==0.12.0
11
- scanpy==1.12.1
12
- scikit_learn==1.8.0
13
- scipy==1.17.1
14
- seaborn==0.13.2
15
- statsmodels==0.14.5
16
- tables==3.10.2
17
- tqdm==4.67.1
18
- umap_learn==0.5.9.post2
File without changes
File without changes
File without changes