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.
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Plot/Visualization.py +467 -7
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/__init__.py +2 -2
- scmultichat-0.2.0/PKG-INFO +30 -0
- scmultichat-0.2.0/requirements.txt +18 -0
- scmultichat-0.2.0/scMultiChat.egg-info/PKG-INFO +30 -0
- scmultichat-0.2.0/scMultiChat.egg-info/requires.txt +18 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/setup.py +1 -1
- scmultichat-0.1.2/PKG-INFO +0 -30
- scmultichat-0.1.2/requirements.txt +0 -18
- scmultichat-0.1.2/scMultiChat.egg-info/PKG-INFO +0 -30
- scmultichat-0.1.2/scMultiChat.egg-info/requires.txt +0 -18
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MANIFEST.in +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Analysis/Intra_strength.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Analysis/Processing.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Analysis/__init__.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/__init__.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/_settings.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/_utils.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/_version.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/plotting/__init__.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/plotting/_palettes.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/plotting/_plot.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/plotting/_post_training.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/plotting/_utils.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/preprocessing/__init__.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/preprocessing/_general.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/preprocessing/_pca.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/preprocessing/_qc.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/preprocessing/_utils.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/preprocessing/_variable_genes.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/readwrite.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/tools/__init__.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/tools/_gene_scores.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/tools/_general.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/tools/_integration.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/tools/_pbg.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/tools/_post_training.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/tools/_umap.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/tools/_utils.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Model/Layers.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Model/__init__.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Model/model_training.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Model/modules.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Model/utilities.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Plot/__init__.py +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/pyproject.toml +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/scMultiChat.egg-info/SOURCES.txt +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/scMultiChat.egg-info/dependency_links.txt +0 -0
- {scmultichat-0.1.2 → scmultichat-0.2.0}/scMultiChat.egg-info/top_level.txt +0 -0
- {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['
|
|
880
|
-
(row['
|
|
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['
|
|
895
|
-
(row['
|
|
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.
|
|
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.
|
|
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
|
scmultichat-0.1.2/PKG-INFO
DELETED
|
@@ -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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/plotting/_post_training.py
RENAMED
|
File without changes
|
|
File without changes
|
{scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/preprocessing/__init__.py
RENAMED
|
File without changes
|
{scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/preprocessing/_general.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/preprocessing/_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scmultichat-0.1.2 → scmultichat-0.2.0}/MultiChat/Heterogeneous_g_emb/tools/_post_training.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|