risk-network 0.0.4b0__py3-none-any.whl → 0.0.4b2__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.
- risk/__init__.py +1 -1
- risk/annotations/io.py +1 -1
- risk/neighborhoods/neighborhoods.py +10 -1
- risk/network/graph.py +4 -4
- risk/network/io.py +189 -16
- risk/network/plot.py +37 -40
- risk/risk.py +4 -41
- {risk_network-0.0.4b0.dist-info → risk_network-0.0.4b2.dist-info}/METADATA +4 -4
- {risk_network-0.0.4b0.dist-info → risk_network-0.0.4b2.dist-info}/RECORD +12 -12
- {risk_network-0.0.4b0.dist-info → risk_network-0.0.4b2.dist-info}/WHEEL +1 -1
- {risk_network-0.0.4b0.dist-info → risk_network-0.0.4b2.dist-info}/LICENSE +0 -0
- {risk_network-0.0.4b0.dist-info → risk_network-0.0.4b2.dist-info}/top_level.txt +0 -0
risk/__init__.py
CHANGED
risk/annotations/io.py
CHANGED
@@ -25,7 +25,7 @@ class AnnotationsIO:
|
|
25
25
|
def __init__(self):
|
26
26
|
pass
|
27
27
|
|
28
|
-
def
|
28
|
+
def load_json_annotation(self, filepath: str, network: nx.Graph) -> Dict[str, Any]:
|
29
29
|
"""Load annotations from a JSON file and convert them to a DataFrame.
|
30
30
|
|
31
31
|
Args:
|
@@ -170,7 +170,16 @@ def _impute_neighbors(
|
|
170
170
|
# Calculate shortest distances for each node to determine the distance threshold
|
171
171
|
shortest_distances = []
|
172
172
|
for node in network.nodes():
|
173
|
-
|
173
|
+
try:
|
174
|
+
neighbors = [
|
175
|
+
n for n in network.neighbors(node) if binary_enrichment_matrix[n].sum() != 0
|
176
|
+
]
|
177
|
+
except IndexError as e:
|
178
|
+
raise IndexError(
|
179
|
+
f"Failed to find neighbors for node '{node}': Ensure that the node exists in the network and that the binary enrichment matrix is correctly indexed."
|
180
|
+
) from e
|
181
|
+
|
182
|
+
# Calculate the shortest distance to a neighbor
|
174
183
|
if neighbors:
|
175
184
|
shortest_distance = min([_get_euclidean_distance(node, n, network) for n in neighbors])
|
176
185
|
shortest_distances.append(shortest_distance)
|
risk/network/graph.py
CHANGED
@@ -49,8 +49,8 @@ class NetworkGraph:
|
|
49
49
|
self.trimmed_domains = trimmed_domains
|
50
50
|
self.node_label_to_id_map = node_label_to_id_map
|
51
51
|
self.node_enrichment_sums = node_enrichment_sums
|
52
|
-
# NOTE: self.
|
53
|
-
self.
|
52
|
+
# NOTE: self.network and self.node_coordinates are declared in _initialize_network
|
53
|
+
self.network = None
|
54
54
|
self.node_coordinates = None
|
55
55
|
self._initialize_network(network)
|
56
56
|
|
@@ -95,8 +95,8 @@ class NetworkGraph:
|
|
95
95
|
"""
|
96
96
|
# Unfold the network's 3D coordinates to 2D
|
97
97
|
G_2d = _unfold_sphere_to_plane(G)
|
98
|
-
# Assign the unfolded graph to self.
|
99
|
-
self.
|
98
|
+
# Assign the unfolded graph to self.network
|
99
|
+
self.network = G_2d
|
100
100
|
# Extract 2D coordinates of nodes
|
101
101
|
self.node_coordinates = _extract_node_coordinates(G_2d)
|
102
102
|
|
risk/network/io.py
CHANGED
@@ -33,15 +33,63 @@ class NetworkIO:
|
|
33
33
|
include_edge_weight: bool = True,
|
34
34
|
weight_label: str = "weight",
|
35
35
|
):
|
36
|
+
"""Initialize the NetworkIO class.
|
37
|
+
|
38
|
+
Args:
|
39
|
+
compute_sphere (bool, optional): Whether to map nodes to a sphere. Defaults to True.
|
40
|
+
surface_depth (float, optional): Surface depth for the sphere. Defaults to 0.0.
|
41
|
+
min_edges_per_node (int, optional): Minimum number of edges per node. Defaults to 0.
|
42
|
+
include_edge_weight (bool, optional): Whether to include edge weights in calculations. Defaults to True.
|
43
|
+
weight_label (str, optional): Label for edge weights. Defaults to "weight".
|
44
|
+
"""
|
36
45
|
self.compute_sphere = compute_sphere
|
37
46
|
self.surface_depth = surface_depth
|
47
|
+
self.min_edges_per_node = min_edges_per_node
|
38
48
|
self.include_edge_weight = include_edge_weight
|
39
49
|
self.weight_label = weight_label
|
40
|
-
|
50
|
+
params.log_network(
|
51
|
+
compute_sphere=compute_sphere,
|
52
|
+
surface_depth=surface_depth,
|
53
|
+
min_edges_per_node=min_edges_per_node,
|
54
|
+
include_edge_weight=include_edge_weight,
|
55
|
+
weight_label=weight_label,
|
56
|
+
)
|
41
57
|
|
42
|
-
|
58
|
+
@classmethod
|
59
|
+
def load_gpickle_network(
|
60
|
+
cls,
|
61
|
+
filepath: str,
|
62
|
+
compute_sphere: bool = True,
|
63
|
+
surface_depth: float = 0.0,
|
64
|
+
min_edges_per_node: int = 0,
|
65
|
+
include_edge_weight: bool = True,
|
66
|
+
weight_label: str = "weight",
|
67
|
+
) -> nx.Graph:
|
43
68
|
"""Load a network from a GPickle file.
|
44
69
|
|
70
|
+
Args:
|
71
|
+
filepath (str): Path to the GPickle file.
|
72
|
+
compute_sphere (bool, optional): Whether to map nodes to a sphere. Defaults to True.
|
73
|
+
surface_depth (float, optional): Surface depth for the sphere. Defaults to 0.0.
|
74
|
+
min_edges_per_node (int, optional): Minimum number of edges per node. Defaults to 0.
|
75
|
+
include_edge_weight (bool, optional): Whether to include edge weights in calculations. Defaults to True.
|
76
|
+
weight_label (str, optional): Label for edge weights. Defaults to "weight".
|
77
|
+
|
78
|
+
Returns:
|
79
|
+
nx.Graph: Loaded and processed network.
|
80
|
+
"""
|
81
|
+
networkio = cls(
|
82
|
+
compute_sphere=compute_sphere,
|
83
|
+
surface_depth=surface_depth,
|
84
|
+
min_edges_per_node=min_edges_per_node,
|
85
|
+
include_edge_weight=include_edge_weight,
|
86
|
+
weight_label=weight_label,
|
87
|
+
)
|
88
|
+
return networkio._load_gpickle_network(filepath=filepath)
|
89
|
+
|
90
|
+
def _load_gpickle_network(self, filepath: str) -> nx.Graph:
|
91
|
+
"""Private method to load a network from a GPickle file.
|
92
|
+
|
45
93
|
Args:
|
46
94
|
filepath (str): Path to the GPickle file.
|
47
95
|
|
@@ -56,11 +104,43 @@ class NetworkIO:
|
|
56
104
|
|
57
105
|
return self._initialize_graph(G)
|
58
106
|
|
59
|
-
|
107
|
+
@classmethod
|
108
|
+
def load_networkx_network(
|
109
|
+
cls,
|
110
|
+
network: nx.Graph,
|
111
|
+
compute_sphere: bool = True,
|
112
|
+
surface_depth: float = 0.0,
|
113
|
+
min_edges_per_node: int = 0,
|
114
|
+
include_edge_weight: bool = True,
|
115
|
+
weight_label: str = "weight",
|
116
|
+
) -> nx.Graph:
|
60
117
|
"""Load a NetworkX graph.
|
61
118
|
|
62
119
|
Args:
|
63
|
-
|
120
|
+
network (nx.Graph): A NetworkX graph object.
|
121
|
+
compute_sphere (bool, optional): Whether to map nodes to a sphere. Defaults to True.
|
122
|
+
surface_depth (float, optional): Surface depth for the sphere. Defaults to 0.0.
|
123
|
+
min_edges_per_node (int, optional): Minimum number of edges per node. Defaults to 0.
|
124
|
+
include_edge_weight (bool, optional): Whether to include edge weights in calculations. Defaults to True.
|
125
|
+
weight_label (str, optional): Label for edge weights. Defaults to "weight".
|
126
|
+
|
127
|
+
Returns:
|
128
|
+
nx.Graph: Loaded and processed network.
|
129
|
+
"""
|
130
|
+
networkio = cls(
|
131
|
+
compute_sphere=compute_sphere,
|
132
|
+
surface_depth=surface_depth,
|
133
|
+
min_edges_per_node=min_edges_per_node,
|
134
|
+
include_edge_weight=include_edge_weight,
|
135
|
+
weight_label=weight_label,
|
136
|
+
)
|
137
|
+
return networkio._load_networkx_network(network=network)
|
138
|
+
|
139
|
+
def _load_networkx_network(self, network: nx.Graph) -> nx.Graph:
|
140
|
+
"""Private method to load a NetworkX graph.
|
141
|
+
|
142
|
+
Args:
|
143
|
+
network (nx.Graph): A NetworkX graph object.
|
64
144
|
|
65
145
|
Returns:
|
66
146
|
nx.Graph: Processed network.
|
@@ -68,17 +148,60 @@ class NetworkIO:
|
|
68
148
|
filetype = "NetworkX"
|
69
149
|
params.log_network(filetype=filetype)
|
70
150
|
self._log_loading(filetype)
|
71
|
-
return self._initialize_graph(
|
151
|
+
return self._initialize_graph(network)
|
72
152
|
|
153
|
+
@classmethod
|
73
154
|
def load_cytoscape_network(
|
74
|
-
|
155
|
+
cls,
|
75
156
|
filepath: str,
|
76
157
|
source_label: str = "source",
|
77
158
|
target_label: str = "target",
|
159
|
+
compute_sphere: bool = True,
|
160
|
+
surface_depth: float = 0.0,
|
161
|
+
min_edges_per_node: int = 0,
|
162
|
+
include_edge_weight: bool = True,
|
163
|
+
weight_label: str = "weight",
|
78
164
|
view_name: str = "",
|
79
165
|
) -> nx.Graph:
|
80
166
|
"""Load a network from a Cytoscape file.
|
81
167
|
|
168
|
+
Args:
|
169
|
+
filepath (str): Path to the Cytoscape file.
|
170
|
+
source_label (str, optional): Source node label. Defaults to "source".
|
171
|
+
target_label (str, optional): Target node label. Defaults to "target".
|
172
|
+
view_name (str, optional): Specific view name to load. Defaults to None.
|
173
|
+
compute_sphere (bool, optional): Whether to map nodes to a sphere. Defaults to True.
|
174
|
+
surface_depth (float, optional): Surface depth for the sphere. Defaults to 0.0.
|
175
|
+
min_edges_per_node (int, optional): Minimum number of edges per node. Defaults to 0.
|
176
|
+
include_edge_weight (bool, optional): Whether to include edge weights in calculations. Defaults to True.
|
177
|
+
weight_label (str, optional): Label for edge weights. Defaults to "weight".
|
178
|
+
|
179
|
+
Returns:
|
180
|
+
nx.Graph: Loaded and processed network.
|
181
|
+
"""
|
182
|
+
networkio = cls(
|
183
|
+
compute_sphere=compute_sphere,
|
184
|
+
surface_depth=surface_depth,
|
185
|
+
min_edges_per_node=min_edges_per_node,
|
186
|
+
include_edge_weight=include_edge_weight,
|
187
|
+
weight_label=weight_label,
|
188
|
+
)
|
189
|
+
return networkio._load_cytoscape_network(
|
190
|
+
filepath=filepath,
|
191
|
+
source_label=source_label,
|
192
|
+
target_label=target_label,
|
193
|
+
view_name=view_name,
|
194
|
+
)
|
195
|
+
|
196
|
+
def _load_cytoscape_network(
|
197
|
+
self,
|
198
|
+
filepath: str,
|
199
|
+
source_label: str = "source",
|
200
|
+
target_label: str = "target",
|
201
|
+
view_name: str = "",
|
202
|
+
) -> nx.Graph:
|
203
|
+
"""Private method to load a network from a Cytoscape file.
|
204
|
+
|
82
205
|
Args:
|
83
206
|
filepath (str): Path to the Cytoscape file.
|
84
207
|
source_label (str, optional): Source node label. Defaults to "source".
|
@@ -173,9 +296,49 @@ class NetworkIO:
|
|
173
296
|
for dirname in cys_dirnames:
|
174
297
|
shutil.rmtree(dirname)
|
175
298
|
|
176
|
-
|
299
|
+
@classmethod
|
300
|
+
def load_cytoscape_json_network(
|
301
|
+
cls,
|
302
|
+
filepath: str,
|
303
|
+
source_label: str = "source",
|
304
|
+
target_label: str = "target",
|
305
|
+
compute_sphere: bool = True,
|
306
|
+
surface_depth: float = 0.0,
|
307
|
+
min_edges_per_node: int = 0,
|
308
|
+
include_edge_weight: bool = True,
|
309
|
+
weight_label: str = "weight",
|
310
|
+
) -> nx.Graph:
|
177
311
|
"""Load a network from a Cytoscape JSON (.cyjs) file.
|
178
312
|
|
313
|
+
Args:
|
314
|
+
filepath (str): Path to the Cytoscape JSON file.
|
315
|
+
source_label (str, optional): Source node label. Default is "source".
|
316
|
+
target_label (str, optional): Target node label. Default is "target".
|
317
|
+
compute_sphere (bool, optional): Whether to map nodes to a sphere. Defaults to True.
|
318
|
+
surface_depth (float, optional): Surface depth for the sphere. Defaults to 0.0.
|
319
|
+
min_edges_per_node (int, optional): Minimum number of edges per node. Defaults to 0.
|
320
|
+
include_edge_weight (bool, optional): Whether to include edge weights in calculations. Defaults to True.
|
321
|
+
weight_label (str, optional): Label for edge weights. Defaults to "weight".
|
322
|
+
|
323
|
+
Returns:
|
324
|
+
NetworkX graph: Loaded and processed network.
|
325
|
+
"""
|
326
|
+
networkio = cls(
|
327
|
+
compute_sphere=compute_sphere,
|
328
|
+
surface_depth=surface_depth,
|
329
|
+
min_edges_per_node=min_edges_per_node,
|
330
|
+
include_edge_weight=include_edge_weight,
|
331
|
+
weight_label=weight_label,
|
332
|
+
)
|
333
|
+
return networkio._load_cytoscape_json_network(
|
334
|
+
filepath=filepath,
|
335
|
+
source_label=source_label,
|
336
|
+
target_label=target_label,
|
337
|
+
)
|
338
|
+
|
339
|
+
def _load_cytoscape_json_network(self, filepath, source_label="source", target_label="target"):
|
340
|
+
"""Private method to load a network from a Cytoscape JSON (.cyjs) file.
|
341
|
+
|
179
342
|
Args:
|
180
343
|
filepath (str): Path to the Cytoscape JSON file.
|
181
344
|
source_label (str, optional): Source node label. Default is "source".
|
@@ -187,36 +350,46 @@ class NetworkIO:
|
|
187
350
|
filetype = "Cytoscape JSON"
|
188
351
|
params.log_network(filetype=filetype, filepath=str(filepath))
|
189
352
|
self._log_loading(filetype, filepath=filepath)
|
353
|
+
|
190
354
|
# Load the Cytoscape JSON file
|
191
355
|
with open(filepath, "r") as f:
|
192
356
|
cyjs_data = json.load(f)
|
193
357
|
|
194
358
|
# Create a graph
|
195
359
|
G = nx.Graph()
|
196
|
-
#
|
360
|
+
# Store node positions for later use
|
197
361
|
node_x_positions = {}
|
198
362
|
node_y_positions = {}
|
199
363
|
for node in cyjs_data["elements"]["nodes"]:
|
200
364
|
node_data = node["data"]
|
201
|
-
node_id = node_data["
|
365
|
+
node_id = node_data["id_original"]
|
202
366
|
node_x_positions[node_id] = node["position"]["x"]
|
203
367
|
node_y_positions[node_id] = node["position"]["y"]
|
204
|
-
G.add_node(node_id)
|
205
|
-
G.nodes[node_id]["label"] = node_data.get("name", node_id)
|
206
|
-
G.nodes[node_id]["x"] = node["position"]["x"]
|
207
|
-
G.nodes[node_id]["y"] = node["position"]["y"]
|
208
368
|
|
209
|
-
# Process edges
|
369
|
+
# Process edges and add them to the graph
|
210
370
|
for edge in cyjs_data["elements"]["edges"]:
|
211
371
|
edge_data = edge["data"]
|
212
|
-
source = edge_data[source_label]
|
213
|
-
target = edge_data[target_label]
|
372
|
+
source = edge_data[f"{source_label}_original"]
|
373
|
+
target = edge_data[f"{target_label}_original"]
|
374
|
+
# Add the edge to the graph, optionally including weights
|
214
375
|
if self.weight_label is not None and self.weight_label in edge_data:
|
215
376
|
weight = float(edge_data[self.weight_label])
|
216
377
|
G.add_edge(source, target, weight=weight)
|
217
378
|
else:
|
218
379
|
G.add_edge(source, target)
|
219
380
|
|
381
|
+
# Ensure nodes exist in the graph and add them if not present
|
382
|
+
if source not in G:
|
383
|
+
G.add_node(source)
|
384
|
+
if target not in G:
|
385
|
+
G.add_node(target)
|
386
|
+
|
387
|
+
# Add node attributes (like label, x, y positions)
|
388
|
+
for node in G.nodes():
|
389
|
+
G.nodes[node]["label"] = node
|
390
|
+
G.nodes[node]["x"] = node_x_positions.get(node, 0) # Use stored positions
|
391
|
+
G.nodes[node]["y"] = node_y_positions.get(node, 0) # Use stored positions
|
392
|
+
|
220
393
|
# Initialize the graph
|
221
394
|
return self._initialize_graph(G)
|
222
395
|
|
risk/network/plot.py
CHANGED
@@ -27,7 +27,7 @@ class NetworkPlotter:
|
|
27
27
|
|
28
28
|
def __init__(
|
29
29
|
self,
|
30
|
-
|
30
|
+
graph: NetworkGraph,
|
31
31
|
figsize: tuple = (10, 10),
|
32
32
|
background_color: str = "white",
|
33
33
|
plot_outline: bool = True,
|
@@ -37,22 +37,22 @@ class NetworkPlotter:
|
|
37
37
|
"""Initialize the NetworkPlotter with a NetworkGraph object and plotting parameters.
|
38
38
|
|
39
39
|
Args:
|
40
|
-
|
40
|
+
graph (NetworkGraph): The network data and attributes to be visualized.
|
41
41
|
figsize (tuple, optional): Size of the figure in inches (width, height). Defaults to (10, 10).
|
42
42
|
background_color (str, optional): Background color of the plot. Defaults to "white".
|
43
43
|
plot_outline (bool, optional): Whether to plot the network perimeter circle. Defaults to True.
|
44
44
|
outline_color (str, optional): Color of the network perimeter circle. Defaults to "black".
|
45
45
|
outline_scale (float, optional): Outline scaling factor for the perimeter diameter. Defaults to 1.0.
|
46
46
|
"""
|
47
|
-
self.
|
47
|
+
self.graph = graph
|
48
48
|
# Initialize the plot with the specified parameters
|
49
49
|
self.ax = self._initialize_plot(
|
50
|
-
|
50
|
+
graph, figsize, background_color, plot_outline, outline_color, outline_scale
|
51
51
|
)
|
52
52
|
|
53
53
|
def _initialize_plot(
|
54
54
|
self,
|
55
|
-
|
55
|
+
graph: NetworkGraph,
|
56
56
|
figsize: tuple,
|
57
57
|
background_color: str,
|
58
58
|
plot_outline: bool,
|
@@ -62,7 +62,7 @@ class NetworkPlotter:
|
|
62
62
|
"""Set up the plot with figure size, optional circle perimeter, and background color.
|
63
63
|
|
64
64
|
Args:
|
65
|
-
|
65
|
+
graph (NetworkGraph): The network data and attributes to be visualized.
|
66
66
|
figsize (tuple): Size of the figure in inches (width, height).
|
67
67
|
background_color (str): Background color of the plot.
|
68
68
|
plot_outline (bool): Whether to plot the network perimeter circle.
|
@@ -73,7 +73,7 @@ class NetworkPlotter:
|
|
73
73
|
plt.Axes: The axis object for the plot.
|
74
74
|
"""
|
75
75
|
# Extract node coordinates from the network graph
|
76
|
-
node_coordinates =
|
76
|
+
node_coordinates = graph.node_coordinates
|
77
77
|
# Calculate the center and radius of the bounding box around the network
|
78
78
|
center, radius = _calculate_bounding_box(node_coordinates)
|
79
79
|
# Scale the radius by the outline_scale factor
|
@@ -141,10 +141,10 @@ class NetworkPlotter:
|
|
141
141
|
network_node_shape=node_shape,
|
142
142
|
)
|
143
143
|
# Extract node coordinates from the network graph
|
144
|
-
node_coordinates = self.
|
144
|
+
node_coordinates = self.graph.node_coordinates
|
145
145
|
# Draw the nodes of the graph
|
146
146
|
nx.draw_networkx_nodes(
|
147
|
-
self.
|
147
|
+
self.graph.network,
|
148
148
|
pos=node_coordinates,
|
149
149
|
node_size=node_size,
|
150
150
|
node_color=node_color,
|
@@ -155,7 +155,7 @@ class NetworkPlotter:
|
|
155
155
|
)
|
156
156
|
# Draw the edges of the graph
|
157
157
|
nx.draw_networkx_edges(
|
158
|
-
self.
|
158
|
+
self.graph.network,
|
159
159
|
pos=node_coordinates,
|
160
160
|
width=edge_width,
|
161
161
|
edge_color=edge_color,
|
@@ -197,20 +197,18 @@ class NetworkPlotter:
|
|
197
197
|
)
|
198
198
|
# Filter to get node IDs and their coordinates
|
199
199
|
node_ids = [
|
200
|
-
self.
|
200
|
+
self.graph.node_label_to_id_map.get(node)
|
201
201
|
for node in nodes
|
202
|
-
if node in self.
|
202
|
+
if node in self.graph.node_label_to_id_map
|
203
203
|
]
|
204
204
|
if not node_ids:
|
205
205
|
raise ValueError("No nodes found in the network graph.")
|
206
206
|
|
207
207
|
# Get the coordinates of the filtered nodes
|
208
|
-
node_coordinates = {
|
209
|
-
node_id: self.network_graph.node_coordinates[node_id] for node_id in node_ids
|
210
|
-
}
|
208
|
+
node_coordinates = {node_id: self.graph.node_coordinates[node_id] for node_id in node_ids}
|
211
209
|
# Draw the nodes in the subnetwork
|
212
210
|
nx.draw_networkx_nodes(
|
213
|
-
self.
|
211
|
+
self.graph.network,
|
214
212
|
pos=node_coordinates,
|
215
213
|
nodelist=node_ids,
|
216
214
|
node_size=node_size,
|
@@ -221,7 +219,7 @@ class NetworkPlotter:
|
|
221
219
|
ax=self.ax,
|
222
220
|
)
|
223
221
|
# Draw the edges between the specified nodes in the subnetwork
|
224
|
-
subgraph = self.
|
222
|
+
subgraph = self.graph.network.subgraph(node_ids)
|
225
223
|
nx.draw_networkx_edges(
|
226
224
|
subgraph,
|
227
225
|
pos=node_coordinates,
|
@@ -260,9 +258,9 @@ class NetworkPlotter:
|
|
260
258
|
color = self.get_annotated_contour_colors(color=color)
|
261
259
|
|
262
260
|
# Extract node coordinates from the network graph
|
263
|
-
node_coordinates = self.
|
261
|
+
node_coordinates = self.graph.node_coordinates
|
264
262
|
# Draw contours for each domain in the network
|
265
|
-
for idx, (_, nodes) in enumerate(self.
|
263
|
+
for idx, (_, nodes) in enumerate(self.graph.domain_to_nodes.items()):
|
266
264
|
if len(nodes) > 1:
|
267
265
|
self._draw_kde_contour(
|
268
266
|
self.ax,
|
@@ -307,15 +305,15 @@ class NetworkPlotter:
|
|
307
305
|
)
|
308
306
|
# Filter to get node IDs and their coordinates
|
309
307
|
node_ids = [
|
310
|
-
self.
|
308
|
+
self.graph.node_label_to_id_map.get(node)
|
311
309
|
for node in nodes
|
312
|
-
if node in self.
|
310
|
+
if node in self.graph.node_label_to_id_map
|
313
311
|
]
|
314
312
|
if not node_ids or len(node_ids) == 1:
|
315
313
|
raise ValueError("No nodes found in the network graph or insufficient nodes to plot.")
|
316
314
|
|
317
315
|
# Draw the KDE contour for the specified nodes
|
318
|
-
node_coordinates = self.
|
316
|
+
node_coordinates = self.graph.node_coordinates
|
319
317
|
self._draw_kde_contour(
|
320
318
|
self.ax,
|
321
319
|
node_coordinates,
|
@@ -438,7 +436,7 @@ class NetworkPlotter:
|
|
438
436
|
|
439
437
|
# Calculate the center and radius of the network
|
440
438
|
domain_centroids = {}
|
441
|
-
for domain, nodes in self.
|
439
|
+
for domain, nodes in self.graph.domain_to_nodes.items():
|
442
440
|
if nodes: # Skip if the domain has no nodes
|
443
441
|
domain_centroids[domain] = self._calculate_domain_centroid(nodes)
|
444
442
|
|
@@ -448,10 +446,7 @@ class NetworkPlotter:
|
|
448
446
|
# Loop through domain_centroids with index
|
449
447
|
for idx, (domain, centroid) in enumerate(domain_centroids.items()):
|
450
448
|
# Check if the domain passes the word count condition
|
451
|
-
if (
|
452
|
-
len(self.network_graph.trimmed_domain_to_term[domain].split(" ")[:max_words])
|
453
|
-
>= min_words
|
454
|
-
):
|
449
|
+
if len(self.graph.trimmed_domain_to_term[domain].split(" ")[:max_words]) >= min_words:
|
455
450
|
# Add to filtered_domain_centroids
|
456
451
|
filtered_domain_centroids[domain] = centroid
|
457
452
|
# Keep track of the valid index
|
@@ -463,7 +458,7 @@ class NetworkPlotter:
|
|
463
458
|
|
464
459
|
# Calculate the bounding box around the network
|
465
460
|
center, radius = _calculate_bounding_box(
|
466
|
-
self.
|
461
|
+
self.graph.node_coordinates, radius_margin=perimeter_scale
|
467
462
|
)
|
468
463
|
# Calculate the best positions for labels around the perimeter
|
469
464
|
best_label_positions = _best_label_positions(
|
@@ -472,7 +467,7 @@ class NetworkPlotter:
|
|
472
467
|
# Annotate the network with labels
|
473
468
|
for idx, (domain, pos) in enumerate(best_label_positions.items()):
|
474
469
|
centroid = filtered_domain_centroids[domain]
|
475
|
-
annotations = self.
|
470
|
+
annotations = self.graph.trimmed_domain_to_term[domain].split(" ")[:max_words]
|
476
471
|
self.ax.annotate(
|
477
472
|
"\n".join(annotations),
|
478
473
|
xy=centroid,
|
@@ -527,17 +522,19 @@ class NetworkPlotter:
|
|
527
522
|
|
528
523
|
# Map node labels to IDs
|
529
524
|
node_ids = [
|
530
|
-
self.
|
525
|
+
self.graph.node_label_to_id_map.get(node)
|
531
526
|
for node in nodes
|
532
|
-
if node in self.
|
527
|
+
if node in self.graph.node_label_to_id_map
|
533
528
|
]
|
529
|
+
if not node_ids or len(node_ids) == 1:
|
530
|
+
raise ValueError("No nodes found in the network graph or insufficient nodes to plot.")
|
534
531
|
|
535
532
|
# Calculate the centroid of the provided nodes
|
536
533
|
centroid = self._calculate_domain_centroid(node_ids)
|
537
534
|
|
538
535
|
# Calculate the bounding box around the network
|
539
536
|
center, radius = _calculate_bounding_box(
|
540
|
-
self.
|
537
|
+
self.graph.node_coordinates, radius_margin=perimeter_scale
|
541
538
|
)
|
542
539
|
|
543
540
|
# Convert radial position to radians, adjusting for a 90-degree rotation
|
@@ -571,7 +568,7 @@ class NetworkPlotter:
|
|
571
568
|
tuple: A tuple containing the domain's central node coordinates.
|
572
569
|
"""
|
573
570
|
# Extract positions of all nodes in the domain
|
574
|
-
node_positions = self.
|
571
|
+
node_positions = self.graph.node_coordinates[nodes, :]
|
575
572
|
# Calculate the pairwise distance matrix between all nodes in the domain
|
576
573
|
distances_matrix = np.linalg.norm(node_positions[:, np.newaxis] - node_positions, axis=2)
|
577
574
|
# Sum the distances for each node to all other nodes in the domain
|
@@ -596,7 +593,7 @@ class NetworkPlotter:
|
|
596
593
|
np.ndarray: Array of RGBA colors adjusted for enrichment status.
|
597
594
|
"""
|
598
595
|
# Get the initial domain colors for each node
|
599
|
-
network_colors = self.
|
596
|
+
network_colors = self.graph.get_domain_colors(**kwargs, random_seed=random_seed)
|
600
597
|
if isinstance(nonenriched_color, str):
|
601
598
|
# Convert the non-enriched color from string to RGBA
|
602
599
|
nonenriched_color = mcolors.to_rgba(nonenriched_color)
|
@@ -623,14 +620,14 @@ class NetworkPlotter:
|
|
623
620
|
"""
|
624
621
|
# Merge all enriched nodes from the domain_to_nodes dictionary
|
625
622
|
enriched_nodes = set()
|
626
|
-
for _, nodes in self.
|
623
|
+
for _, nodes in self.graph.domain_to_nodes.items():
|
627
624
|
enriched_nodes.update(nodes)
|
628
625
|
|
629
626
|
# Initialize all node sizes to the non-enriched size
|
630
|
-
node_sizes = np.full(len(self.
|
627
|
+
node_sizes = np.full(len(self.graph.network.nodes), nonenriched_nodesize)
|
631
628
|
# Set the size for enriched nodes
|
632
629
|
for node in enriched_nodes:
|
633
|
-
if node in self.
|
630
|
+
if node in self.graph.network.nodes:
|
634
631
|
node_sizes[node] = enriched_nodesize
|
635
632
|
|
636
633
|
return node_sizes
|
@@ -675,12 +672,12 @@ class NetworkPlotter:
|
|
675
672
|
if isinstance(color, str):
|
676
673
|
# If a single color string is provided, convert it to RGBA and apply to all domains
|
677
674
|
rgba_color = np.array(matplotlib.colors.to_rgba(color))
|
678
|
-
return np.array([rgba_color for _ in self.
|
675
|
+
return np.array([rgba_color for _ in self.graph.domain_to_nodes])
|
679
676
|
|
680
677
|
# Generate colors for each domain using the provided arguments and random seed
|
681
|
-
node_colors = self.
|
678
|
+
node_colors = self.graph.get_domain_colors(**kwargs, random_seed=random_seed)
|
682
679
|
annotated_colors = []
|
683
|
-
for _, nodes in self.
|
680
|
+
for _, nodes in self.graph.domain_to_nodes.items():
|
684
681
|
if len(nodes) > 1:
|
685
682
|
# For domains with multiple nodes, choose the brightest color (sum of RGB values)
|
686
683
|
domain_colors = np.array([node_colors[node] for node in nodes])
|
risk/risk.py
CHANGED
@@ -27,49 +27,12 @@ class RISK(NetworkIO, AnnotationsIO):
|
|
27
27
|
and performing network-based statistical analysis, such as neighborhood significance testing.
|
28
28
|
"""
|
29
29
|
|
30
|
-
def __init__(
|
31
|
-
|
32
|
-
compute_sphere: bool = True,
|
33
|
-
surface_depth: float = 0.0,
|
34
|
-
min_edges_per_node: int = 0,
|
35
|
-
include_edge_weight: bool = True,
|
36
|
-
weight_label: str = "weight",
|
37
|
-
):
|
38
|
-
"""Initialize the RISK class with configuration settings.
|
39
|
-
|
40
|
-
Args:
|
41
|
-
compute_sphere (bool, optional): Whether to map nodes to a sphere. Defaults to True.
|
42
|
-
surface_depth (float, optional): Surface depth for the sphere. Defaults to 0.0.
|
43
|
-
min_edges_per_node (int, optional): Minimum number of edges per node. Defaults to 0.
|
44
|
-
include_edge_weight (bool, optional): Whether to include edge weights in calculations. Defaults to True.
|
45
|
-
weight_label (str, optional): Label for edge weights. Defaults to "weight".
|
46
|
-
"""
|
30
|
+
def __init__(self, *args, **kwargs):
|
31
|
+
"""Initialize the RISK class with configuration settings."""
|
47
32
|
# Initialize and log network parameters
|
48
33
|
params.initialize()
|
49
|
-
|
50
|
-
|
51
|
-
surface_depth=surface_depth,
|
52
|
-
min_edges_per_node=min_edges_per_node,
|
53
|
-
include_edge_weight=include_edge_weight,
|
54
|
-
weight_label=weight_label,
|
55
|
-
)
|
56
|
-
# Initialize parent classes
|
57
|
-
NetworkIO.__init__(
|
58
|
-
self,
|
59
|
-
compute_sphere=compute_sphere,
|
60
|
-
surface_depth=surface_depth,
|
61
|
-
min_edges_per_node=min_edges_per_node,
|
62
|
-
include_edge_weight=include_edge_weight,
|
63
|
-
weight_label=weight_label,
|
64
|
-
)
|
65
|
-
AnnotationsIO.__init__(self)
|
66
|
-
|
67
|
-
# Set class attributes
|
68
|
-
self.compute_sphere = compute_sphere
|
69
|
-
self.surface_depth = surface_depth
|
70
|
-
self.min_edges_per_node = min_edges_per_node
|
71
|
-
self.include_edge_weight = include_edge_weight
|
72
|
-
self.weight_label = weight_label
|
34
|
+
# Initialize the parent classes
|
35
|
+
super().__init__(*args, **kwargs)
|
73
36
|
|
74
37
|
@property
|
75
38
|
def params(self):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: risk-network
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.4b2
|
4
4
|
Summary: A Python package for biological network analysis
|
5
5
|
Author: Ira Horecka
|
6
6
|
Author-email: Ira Horecka <ira89@icloud.com>
|
@@ -684,14 +684,14 @@ Classifier: Intended Audience :: Science/Research
|
|
684
684
|
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
685
685
|
Classifier: Operating System :: OS Independent
|
686
686
|
Classifier: Programming Language :: Python :: 3
|
687
|
-
Classifier: Programming Language :: Python :: 3.
|
687
|
+
Classifier: Programming Language :: Python :: 3.8
|
688
688
|
Classifier: Programming Language :: Python :: 3 :: Only
|
689
689
|
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
690
690
|
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
691
691
|
Classifier: Topic :: Scientific/Engineering :: Visualization
|
692
692
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
693
693
|
Classifier: Development Status :: 4 - Beta
|
694
|
-
Requires-Python: >=3.
|
694
|
+
Requires-Python: >=3.8
|
695
695
|
Description-Content-Type: text/markdown
|
696
696
|
License-File: LICENSE
|
697
697
|
Requires-Dist: ipywidgets
|
@@ -716,7 +716,7 @@ Requires-Dist: tqdm
|
|
716
716
|
|
717
717
|
<p align="center">
|
718
718
|
<a href="https://pypi.python.org/pypi/risk-network"><img src="https://img.shields.io/pypi/v/risk-network.svg" alt="pypiv"></a>
|
719
|
-
<a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.
|
719
|
+
<a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.8+-blue.svg" alt="Python 3.8+"></a>
|
720
720
|
<a href="https://raw.githubusercontent.com/irahorecka/chrono24/main/LICENSE"><img src="https://img.shields.io/badge/License-GPLv3-blue.svg" alt="License: GPL v3"></a>
|
721
721
|
</p>
|
722
722
|
|
@@ -1,26 +1,26 @@
|
|
1
|
-
risk/__init__.py,sha256=
|
1
|
+
risk/__init__.py,sha256=k1uCNFu-aa2ozj1u_pYR_tKhWf_Snf43Y6DX8O9_d0I,122
|
2
2
|
risk/constants.py,sha256=AICk3x5qRQhls_ijTb4VdbdxU6mZ1aLGbAjLEdBwfJI,550
|
3
|
-
risk/risk.py,sha256=
|
3
|
+
risk/risk.py,sha256=Kaju0siA2piDWuawSB1iZcngm9BND_R7iJAqAS_55E0,14717
|
4
4
|
risk/annotations/__init__.py,sha256=vUpVvMRE5if01Ic8QY6M2Ae3EFGJHdugEe9PdEkAW4Y,138
|
5
5
|
risk/annotations/annotations.py,sha256=0-Yf2XPVdMzpttLLgLxtTTnH0Eed_Uv8VXMur6E6xKw,10481
|
6
|
-
risk/annotations/io.py,sha256=
|
6
|
+
risk/annotations/io.py,sha256=TMicRACfY8bNtmbvVrxHoh8zkOVLOIhZwWrpxUlR28Q,7988
|
7
7
|
risk/log/__init__.py,sha256=xuLImfxFlKpnVhzi_gDYlr2_c9cLkrw2c_3iEsXb1as,107
|
8
8
|
risk/log/console.py,sha256=im9DRExwf6wHlcn9fewoDcKIpo3vPcorZIaNAl-0csY,355
|
9
9
|
risk/log/params.py,sha256=Tbb-sovFTptGBqPDKafUA8KOpby4zFObutAT_Iti1hE,6302
|
10
10
|
risk/neighborhoods/__init__.py,sha256=tKKEg4lsbqFukpgYlUGxU_v_9FOqK7V0uvM9T2QzoL0,206
|
11
11
|
risk/neighborhoods/community.py,sha256=eL2IGT-8sbiJIyfyb_FGngev7pEMxw7tZb8YzbzOYw8,6512
|
12
12
|
risk/neighborhoods/domains.py,sha256=HwuChmZH0RGD9eQOvk2-ezQDJRUHHn93vhVgHb-kX6I,10192
|
13
|
-
risk/neighborhoods/neighborhoods.py,sha256=
|
13
|
+
risk/neighborhoods/neighborhoods.py,sha256=benMk6ZCufhi9FKo6ByaeOzwJ8y43vkFbCD-wUNaCAU,13828
|
14
14
|
risk/network/__init__.py,sha256=iEPeJdZfqp0toxtbElryB8jbz9_t_k4QQ3iDvKE8C_0,126
|
15
15
|
risk/network/geometry.py,sha256=euBMOVvxpj-0WZam40IbHdsT7E4WXpTwSxuGbmAGTDg,6757
|
16
|
-
risk/network/graph.py,sha256=
|
17
|
-
risk/network/io.py,sha256=
|
18
|
-
risk/network/plot.py,sha256
|
16
|
+
risk/network/graph.py,sha256=m3bFWU5528OEm246LPG5XP3l_30vaBiJv4AO4iq0pSA,11552
|
17
|
+
risk/network/io.py,sha256=Vn__hWla0EI9djIv7mWc1bFSTS2pRpUwOjPCqMWQOYI,19689
|
18
|
+
risk/network/plot.py,sha256=-8LyRqeQi4cxEVxNsTDCyHhmTfFuObLLaFbKQGZwHCI,38289
|
19
19
|
risk/stats/__init__.py,sha256=4s9gdJo5B1G_cQc0iMoeIBt5OrQNXkdtNXkAMFQkLxc,103
|
20
20
|
risk/stats/permutation.py,sha256=xgaZbaxo57t_FzPlpcb2nsq8oCzc_wj-zAm-xj3P2dA,3404
|
21
21
|
risk/stats/stats.py,sha256=7Z-1sJ5zvS3XDjG2UfOV0Y3c3xliYeB-6fk_UHNqfiE,16019
|
22
|
-
risk_network-0.0.
|
23
|
-
risk_network-0.0.
|
24
|
-
risk_network-0.0.
|
25
|
-
risk_network-0.0.
|
26
|
-
risk_network-0.0.
|
22
|
+
risk_network-0.0.4b2.dist-info/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
|
23
|
+
risk_network-0.0.4b2.dist-info/METADATA,sha256=B7fcNMOXnMjV5BuPE1t8UXb8cpk3NiuYmsdDzUKY7oo,43250
|
24
|
+
risk_network-0.0.4b2.dist-info/WHEEL,sha256=Mdi9PDNwEZptOjTlUcAth7XJDFtKrHYaQMPulZeBCiQ,91
|
25
|
+
risk_network-0.0.4b2.dist-info/top_level.txt,sha256=NX7C2PFKTvC1JhVKv14DFlFAIFnKc6Lpsu1ZfxvQwVw,5
|
26
|
+
risk_network-0.0.4b2.dist-info/RECORD,,
|
File without changes
|
File without changes
|