risk-network 0.0.8b27__py3-none-any.whl → 0.0.9b1__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/annotations.py +39 -38
- risk/log/enrichment.py +18 -0
- risk/neighborhoods/domains.py +15 -15
- risk/neighborhoods/neighborhoods.py +101 -89
- risk/network/graph.py +25 -25
- risk/network/plot/contour.py +1 -1
- risk/network/plot/labels.py +1 -1
- risk/network/plot/network.py +28 -28
- risk/network/plot/utils/color.py +27 -27
- risk/risk.py +20 -18
- risk/stats/stats.py +13 -13
- {risk_network-0.0.8b27.dist-info → risk_network-0.0.9b1.dist-info}/METADATA +1 -1
- {risk_network-0.0.8b27.dist-info → risk_network-0.0.9b1.dist-info}/RECORD +17 -16
- {risk_network-0.0.8b27.dist-info → risk_network-0.0.9b1.dist-info}/LICENSE +0 -0
- {risk_network-0.0.8b27.dist-info → risk_network-0.0.9b1.dist-info}/WHEEL +0 -0
- {risk_network-0.0.8b27.dist-info → risk_network-0.0.9b1.dist-info}/top_level.txt +0 -0
risk/network/graph.py
CHANGED
@@ -15,9 +15,9 @@ class NetworkGraph:
|
|
15
15
|
"""A class to represent a network graph and process its nodes and edges.
|
16
16
|
|
17
17
|
The NetworkGraph class provides functionality to handle and manipulate a network graph,
|
18
|
-
including managing domains, annotations, and node
|
18
|
+
including managing domains, annotations, and node significance data. It also includes methods
|
19
19
|
for transforming and mapping graph coordinates, as well as generating colors based on node
|
20
|
-
|
20
|
+
significance.
|
21
21
|
"""
|
22
22
|
|
23
23
|
def __init__(
|
@@ -27,7 +27,7 @@ class NetworkGraph:
|
|
27
27
|
domains: pd.DataFrame,
|
28
28
|
trimmed_domains: pd.DataFrame,
|
29
29
|
node_label_to_node_id_map: Dict[str, Any],
|
30
|
-
|
30
|
+
node_significance_sums: np.ndarray,
|
31
31
|
):
|
32
32
|
"""Initialize the NetworkGraph object.
|
33
33
|
|
@@ -37,7 +37,7 @@ class NetworkGraph:
|
|
37
37
|
domains (pd.DataFrame): DataFrame containing domain data for the network nodes.
|
38
38
|
trimmed_domains (pd.DataFrame): DataFrame containing trimmed domain data for the network nodes.
|
39
39
|
node_label_to_node_id_map (Dict[str, Any]): A dictionary mapping node labels to their corresponding IDs.
|
40
|
-
|
40
|
+
node_significance_sums (np.ndarray): Array containing the significant sums for the nodes.
|
41
41
|
"""
|
42
42
|
self.top_annotations = top_annotations
|
43
43
|
self.domain_id_to_node_ids_map = self._create_domain_id_to_node_ids_map(domains)
|
@@ -49,13 +49,13 @@ class NetworkGraph:
|
|
49
49
|
trimmed_domains
|
50
50
|
)
|
51
51
|
self.trimmed_domains = trimmed_domains
|
52
|
-
self.
|
53
|
-
self.
|
54
|
-
self.
|
52
|
+
self.node_significance_sums = node_significance_sums
|
53
|
+
self.node_id_to_domain_ids_and_significance_map = (
|
54
|
+
self._create_node_id_to_domain_ids_and_significances(domains)
|
55
55
|
)
|
56
56
|
self.node_id_to_node_label_map = {v: k for k, v in node_label_to_node_id_map.items()}
|
57
|
-
self.
|
58
|
-
zip(node_label_to_node_id_map.keys(),
|
57
|
+
self.node_label_to_significance_map = dict(
|
58
|
+
zip(node_label_to_node_id_map.keys(), node_significance_sums)
|
59
59
|
)
|
60
60
|
self.node_label_to_node_id_map = node_label_to_node_id_map
|
61
61
|
# NOTE: Below this point, instance attributes (i.e., self) will be used!
|
@@ -103,25 +103,25 @@ class NetworkGraph:
|
|
103
103
|
def _create_domain_id_to_domain_info_map(
|
104
104
|
trimmed_domains: pd.DataFrame,
|
105
105
|
) -> Dict[int, Dict[str, Any]]:
|
106
|
-
"""Create a mapping from domain IDs to their corresponding full description and
|
106
|
+
"""Create a mapping from domain IDs to their corresponding full description and significance score.
|
107
107
|
|
108
108
|
Args:
|
109
|
-
trimmed_domains (pd.DataFrame): DataFrame containing domain IDs, full descriptions, and
|
109
|
+
trimmed_domains (pd.DataFrame): DataFrame containing domain IDs, full descriptions, and significance scores.
|
110
110
|
|
111
111
|
Returns:
|
112
|
-
Dict[int, Dict[str, Any]]: A dictionary mapping domain IDs (int) to a dictionary with 'full_descriptions' and '
|
112
|
+
Dict[int, Dict[str, Any]]: A dictionary mapping domain IDs (int) to a dictionary with 'full_descriptions' and 'significance_scores'.
|
113
113
|
"""
|
114
114
|
return {
|
115
115
|
int(id_): {
|
116
116
|
"full_descriptions": trimmed_domains.at[id_, "full_descriptions"],
|
117
|
-
"
|
117
|
+
"significance_scores": trimmed_domains.at[id_, "significance_scores"],
|
118
118
|
}
|
119
119
|
for id_ in trimmed_domains.index
|
120
120
|
}
|
121
121
|
|
122
122
|
@staticmethod
|
123
|
-
def
|
124
|
-
"""Creates a dictionary mapping each node ID to its corresponding domain IDs and
|
123
|
+
def _create_node_id_to_domain_ids_and_significances(domains: pd.DataFrame) -> Dict[int, Dict]:
|
124
|
+
"""Creates a dictionary mapping each node ID to its corresponding domain IDs and significance values.
|
125
125
|
|
126
126
|
Args:
|
127
127
|
domains (pd.DataFrame): A DataFrame containing domain information for each node. Assumes the last
|
@@ -129,28 +129,28 @@ class NetworkGraph:
|
|
129
129
|
|
130
130
|
Returns:
|
131
131
|
Dict[int, Dict]: A dictionary where the key is the node ID (index of the DataFrame), and the value is another dictionary
|
132
|
-
with 'domain' (a list of domain IDs with non-zero
|
133
|
-
(a dict of domain IDs and their corresponding
|
132
|
+
with 'domain' (a list of domain IDs with non-zero significance) and 'significance'
|
133
|
+
(a dict of domain IDs and their corresponding significance values).
|
134
134
|
"""
|
135
135
|
# Initialize an empty dictionary to store the result
|
136
|
-
|
136
|
+
node_id_to_domain_ids_and_significances = {}
|
137
137
|
# Get the list of domain columns (excluding 'all domains' and 'primary domain')
|
138
138
|
domain_columns = domains.columns[
|
139
139
|
:-2
|
140
140
|
] # The last two columns are 'all domains' and 'primary domain'
|
141
141
|
# Iterate over each row in the dataframe
|
142
142
|
for idx, row in domains.iterrows():
|
143
|
-
# Get the domains (column names) where the
|
143
|
+
# Get the domains (column names) where the significance score is greater than 0
|
144
144
|
all_domains = domain_columns[row[domain_columns] > 0].tolist()
|
145
|
-
# Get the
|
146
|
-
|
145
|
+
# Get the significance values for those domains
|
146
|
+
significance_values = row[all_domains].to_dict()
|
147
147
|
# Store the result in the dictionary with index as the key
|
148
|
-
|
149
|
-
"domains": all_domains, # The column names where
|
150
|
-
"
|
148
|
+
node_id_to_domain_ids_and_significances[idx] = {
|
149
|
+
"domains": all_domains, # The column names where significance > 0
|
150
|
+
"significances": significance_values, # The actual significance values for those columns
|
151
151
|
}
|
152
152
|
|
153
|
-
return
|
153
|
+
return node_id_to_domain_ids_and_significances
|
154
154
|
|
155
155
|
def _create_domain_id_to_node_labels_map(self) -> Dict[int, List[str]]:
|
156
156
|
"""Create a map from domain IDs to node labels.
|
risk/network/plot/contour.py
CHANGED
@@ -294,7 +294,7 @@ class Contour:
|
|
294
294
|
Controls the dimmest colors. Defaults to 0.8.
|
295
295
|
max_scale (float, optional): Maximum intensity scale for the colors generated by the colormap.
|
296
296
|
Controls the brightest colors. Defaults to 1.0.
|
297
|
-
scale_factor (float, optional): Exponent for adjusting color scaling based on
|
297
|
+
scale_factor (float, optional): Exponent for adjusting color scaling based on significance scores.
|
298
298
|
A higher value increases contrast by dimming lower scores more. Defaults to 1.0.
|
299
299
|
random_seed (int, optional): Seed for random number generation to ensure reproducibility. Defaults to 888.
|
300
300
|
|
risk/network/plot/labels.py
CHANGED
@@ -659,7 +659,7 @@ class Labels:
|
|
659
659
|
Controls the dimmest colors. Defaults to 0.8.
|
660
660
|
max_scale (float, optional): Maximum intensity scale for the colors generated by the colormap.
|
661
661
|
Controls the brightest colors. Defaults to 1.0.
|
662
|
-
scale_factor (float, optional): Exponent for adjusting color scaling based on
|
662
|
+
scale_factor (float, optional): Exponent for adjusting color scaling based on significance scores.
|
663
663
|
A higher value increases contrast by dimming lower scores more. Defaults to 1.0.
|
664
664
|
random_seed (int, optional): Seed for random number generation to ensure reproducibility. Defaults to 888.
|
665
665
|
|
risk/network/plot/network.py
CHANGED
@@ -203,11 +203,11 @@ class Network:
|
|
203
203
|
max_scale: float = 1.0,
|
204
204
|
scale_factor: float = 1.0,
|
205
205
|
alpha: Union[float, None] = 1.0,
|
206
|
-
|
207
|
-
|
206
|
+
nonsignificant_color: Union[str, List, Tuple, np.ndarray] = "white",
|
207
|
+
nonsignificant_alpha: Union[float, None] = 1.0,
|
208
208
|
random_seed: int = 888,
|
209
209
|
) -> np.ndarray:
|
210
|
-
"""Adjust the colors of nodes in the network graph based on
|
210
|
+
"""Adjust the colors of nodes in the network graph based on significance.
|
211
211
|
|
212
212
|
Args:
|
213
213
|
cmap (str, optional): Colormap to use for coloring the nodes. Defaults to "gist_rainbow".
|
@@ -218,16 +218,16 @@ class Network:
|
|
218
218
|
min_scale (float, optional): Minimum scale for color intensity. Defaults to 0.8.
|
219
219
|
max_scale (float, optional): Maximum scale for color intensity. Defaults to 1.0.
|
220
220
|
scale_factor (float, optional): Factor for adjusting the color scaling intensity. Defaults to 1.0.
|
221
|
-
alpha (float, None, optional): Alpha value for
|
221
|
+
alpha (float, None, optional): Alpha value for significant nodes. If provided, it overrides any existing alpha values found in `color`.
|
222
222
|
Defaults to 1.0.
|
223
|
-
|
223
|
+
nonsignificant_color (str, List, Tuple, or np.ndarray, optional): Color for non-significant nodes. Can be a single color or an array of colors.
|
224
224
|
Defaults to "white".
|
225
|
-
|
226
|
-
in `
|
225
|
+
nonsignificant_alpha (float, None, optional): Alpha value for non-significant nodes. If provided, it overrides any existing alpha values found
|
226
|
+
in `nonsignificant_color`. Defaults to 1.0.
|
227
227
|
random_seed (int, optional): Seed for random number generation. Defaults to 888.
|
228
228
|
|
229
229
|
Returns:
|
230
|
-
np.ndarray: Array of RGBA colors adjusted for
|
230
|
+
np.ndarray: Array of RGBA colors adjusted for significance status.
|
231
231
|
"""
|
232
232
|
# Get the initial domain colors for each node, which are returned as RGBA
|
233
233
|
network_colors = get_domain_colors(
|
@@ -241,11 +241,11 @@ class Network:
|
|
241
241
|
scale_factor=scale_factor,
|
242
242
|
random_seed=random_seed,
|
243
243
|
)
|
244
|
-
# Apply the alpha value for
|
245
|
-
network_colors[:, 3] = alpha # Apply the alpha value to the
|
246
|
-
# Convert the non-
|
247
|
-
|
248
|
-
color=
|
244
|
+
# Apply the alpha value for significant nodes
|
245
|
+
network_colors[:, 3] = alpha # Apply the alpha value to the significant nodes' A channel
|
246
|
+
# Convert the non-significant color to RGBA using the to_rgba helper function
|
247
|
+
nonsignificant_color_rgba = to_rgba(
|
248
|
+
color=nonsignificant_color, alpha=nonsignificant_alpha, num_repeats=1
|
249
249
|
) # num_repeats=1 for a single color
|
250
250
|
# Adjust node colors: replace any nodes where all three RGB values are equal and less than 0.1
|
251
251
|
# 0.1 is a predefined threshold for the minimum color intensity
|
@@ -255,34 +255,34 @@ class Network:
|
|
255
255
|
& np.all(network_colors[:, :3] == network_colors[:, 0:1], axis=1)
|
256
256
|
)[:, None],
|
257
257
|
np.tile(
|
258
|
-
np.array(
|
259
|
-
), # Replace with the full RGBA non-
|
258
|
+
np.array(nonsignificant_color_rgba), (network_colors.shape[0], 1)
|
259
|
+
), # Replace with the full RGBA non-significant color
|
260
260
|
network_colors, # Keep the original colors where no match is found
|
261
261
|
)
|
262
262
|
return adjusted_network_colors
|
263
263
|
|
264
264
|
def get_annotated_node_sizes(
|
265
|
-
self,
|
265
|
+
self, significant_size: int = 50, nonsignificant_size: int = 25
|
266
266
|
) -> np.ndarray:
|
267
|
-
"""Adjust the sizes of nodes in the network graph based on whether they are
|
267
|
+
"""Adjust the sizes of nodes in the network graph based on whether they are significant or not.
|
268
268
|
|
269
269
|
Args:
|
270
|
-
|
271
|
-
|
270
|
+
significant_size (int): Size for significant nodes. Defaults to 50.
|
271
|
+
nonsignificant_size (int): Size for non-significant nodes. Defaults to 25.
|
272
272
|
|
273
273
|
Returns:
|
274
|
-
np.ndarray: Array of node sizes, with
|
274
|
+
np.ndarray: Array of node sizes, with significant nodes larger than non-significant ones.
|
275
275
|
"""
|
276
|
-
# Merge all
|
277
|
-
|
276
|
+
# Merge all significant nodes from the domain_id_to_node_ids_map dictionary
|
277
|
+
significant_nodes = set()
|
278
278
|
for _, node_ids in self.graph.domain_id_to_node_ids_map.items():
|
279
|
-
|
279
|
+
significant_nodes.update(node_ids)
|
280
280
|
|
281
|
-
# Initialize all node sizes to the non-
|
282
|
-
node_sizes = np.full(len(self.graph.network.nodes),
|
283
|
-
# Set the size for
|
284
|
-
for node in
|
281
|
+
# Initialize all node sizes to the non-significant size
|
282
|
+
node_sizes = np.full(len(self.graph.network.nodes), nonsignificant_size)
|
283
|
+
# Set the size for significant nodes
|
284
|
+
for node in significant_nodes:
|
285
285
|
if node in self.graph.network.nodes:
|
286
|
-
node_sizes[node] =
|
286
|
+
node_sizes[node] = significant_size
|
287
287
|
|
288
288
|
return node_sizes
|
risk/network/plot/utils/color.py
CHANGED
@@ -35,14 +35,14 @@ def get_annotated_domain_colors(
|
|
35
35
|
blend_gamma (float, optional): Gamma correction factor for perceptual color blending. Defaults to 2.2.
|
36
36
|
min_scale (float, optional): Minimum scale for color intensity when generating domain colors. Defaults to 0.8.
|
37
37
|
max_scale (float, optional): Maximum scale for color intensity when generating domain colors. Defaults to 1.0.
|
38
|
-
scale_factor (float, optional): Factor for adjusting the contrast in the colors generated based on
|
38
|
+
scale_factor (float, optional): Factor for adjusting the contrast in the colors generated based on significance. Higher values
|
39
39
|
increase the contrast. Defaults to 1.0.
|
40
40
|
random_seed (int, optional): Seed for random number generation to ensure reproducibility. Defaults to 888.
|
41
41
|
|
42
42
|
Returns:
|
43
43
|
np.ndarray: Array of RGBA colors for each domain.
|
44
44
|
"""
|
45
|
-
# Generate domain colors based on the
|
45
|
+
# Generate domain colors based on the significance data
|
46
46
|
node_colors = get_domain_colors(
|
47
47
|
graph=graph,
|
48
48
|
cmap=cmap,
|
@@ -82,7 +82,7 @@ def get_domain_colors(
|
|
82
82
|
scale_factor: float = 1.0,
|
83
83
|
random_seed: int = 888,
|
84
84
|
) -> np.ndarray:
|
85
|
-
"""Generate composite colors for domains based on
|
85
|
+
"""Generate composite colors for domains based on significance or specified colors.
|
86
86
|
|
87
87
|
Args:
|
88
88
|
graph (NetworkGraph): The network data and attributes to be visualized.
|
@@ -95,12 +95,12 @@ def get_domain_colors(
|
|
95
95
|
Defaults to 0.8.
|
96
96
|
max_scale (float, optional): Maximum intensity scale for the colors generated by the colormap. Controls the brightest colors.
|
97
97
|
Defaults to 1.0.
|
98
|
-
scale_factor (float, optional): Exponent for adjusting the color scaling based on
|
98
|
+
scale_factor (float, optional): Exponent for adjusting the color scaling based on significance scores. Higher values increase
|
99
99
|
contrast by dimming lower scores more. Defaults to 1.0.
|
100
100
|
random_seed (int, optional): Seed for random number generation to ensure reproducibility of color assignments. Defaults to 888.
|
101
101
|
|
102
102
|
Returns:
|
103
|
-
np.ndarray: Array of RGBA colors generated for each domain, based on
|
103
|
+
np.ndarray: Array of RGBA colors generated for each domain, based on significance or the specified color.
|
104
104
|
"""
|
105
105
|
# Get colors for each domain
|
106
106
|
domain_colors = _get_domain_colors(graph=graph, cmap=cmap, color=color, random_seed=random_seed)
|
@@ -111,7 +111,7 @@ def get_domain_colors(
|
|
111
111
|
# Transform colors to ensure proper alpha values and intensity
|
112
112
|
transformed_colors = _transform_colors(
|
113
113
|
node_colors,
|
114
|
-
graph.
|
114
|
+
graph.node_significance_sums,
|
115
115
|
min_scale=min_scale,
|
116
116
|
max_scale=max_scale,
|
117
117
|
scale_factor=scale_factor,
|
@@ -151,7 +151,7 @@ def _get_domain_colors(
|
|
151
151
|
def _get_composite_node_colors(
|
152
152
|
graph, domain_colors: np.ndarray, blend_colors: bool = False, blend_gamma: float = 2.2
|
153
153
|
) -> np.ndarray:
|
154
|
-
"""Generate composite colors for nodes based on domain colors and
|
154
|
+
"""Generate composite colors for nodes based on domain colors and significance values, with optional color blending.
|
155
155
|
|
156
156
|
Args:
|
157
157
|
graph (NetworkGraph): The network data and attributes to be visualized.
|
@@ -177,26 +177,26 @@ def _get_composite_node_colors(
|
|
177
177
|
|
178
178
|
# If blending is required
|
179
179
|
else:
|
180
|
-
for node, node_info in graph.
|
180
|
+
for node, node_info in graph.node_id_to_domain_ids_and_significance_map.items():
|
181
181
|
domains = node_info["domains"] # List of domain IDs
|
182
|
-
|
183
|
-
# Filter domains and
|
184
|
-
|
185
|
-
(domain_id,
|
186
|
-
for domain_id,
|
182
|
+
significances = node_info["significances"] # List of significance values
|
183
|
+
# Filter domains and significances to keep only those with corresponding colors in domain_colors
|
184
|
+
filtered_domains_significances = [
|
185
|
+
(domain_id, significance)
|
186
|
+
for domain_id, significance in zip(domains, significances)
|
187
187
|
if domain_id in domain_colors
|
188
188
|
]
|
189
189
|
# If no valid domains exist, skip this node
|
190
|
-
if not
|
190
|
+
if not filtered_domains_significances:
|
191
191
|
continue
|
192
192
|
|
193
|
-
# Unpack filtered domains and
|
194
|
-
filtered_domains,
|
193
|
+
# Unpack filtered domains and significances
|
194
|
+
filtered_domains, filtered_significances = zip(*filtered_domains_significances)
|
195
195
|
# Get the colors corresponding to the valid filtered domains
|
196
196
|
colors = [domain_colors[domain_id] for domain_id in filtered_domains]
|
197
197
|
# Blend the colors using the given gamma (default is 2.2 if None)
|
198
198
|
gamma = blend_gamma if blend_gamma is not None else 2.2
|
199
|
-
composite_color = _blend_colors_perceptually(colors,
|
199
|
+
composite_color = _blend_colors_perceptually(colors, filtered_significances, gamma)
|
200
200
|
# Assign the composite color to the node
|
201
201
|
composite_colors[node] = composite_color
|
202
202
|
|
@@ -282,21 +282,21 @@ def _assign_distant_colors(dist_matrix, num_colors_to_generate):
|
|
282
282
|
|
283
283
|
|
284
284
|
def _blend_colors_perceptually(
|
285
|
-
colors: Union[List, Tuple, np.ndarray],
|
285
|
+
colors: Union[List, Tuple, np.ndarray], significances: List[float], gamma: float = 2.2
|
286
286
|
) -> Tuple[float, float, float, float]:
|
287
287
|
"""Blends a list of RGBA colors using gamma correction for perceptually uniform color mixing.
|
288
288
|
|
289
289
|
Args:
|
290
290
|
colors (List, Tuple, np.ndarray): List of RGBA colors. Can be a list, tuple, or NumPy array of RGBA values.
|
291
|
-
|
291
|
+
significances (List[float]): Corresponding list of significance values.
|
292
292
|
gamma (float, optional): Gamma correction factor, default is 2.2 (typical for perceptual blending).
|
293
293
|
|
294
294
|
Returns:
|
295
295
|
Tuple[float, float, float, float]: The blended RGBA color.
|
296
296
|
"""
|
297
|
-
# Normalize
|
298
|
-
|
299
|
-
proportions = [
|
297
|
+
# Normalize significances so they sum up to 1 (proportions)
|
298
|
+
total_significance = sum(significances)
|
299
|
+
proportions = [significance / total_significance for significance in significances]
|
300
300
|
# Convert colors to gamma-corrected space (apply gamma correction to RGB channels)
|
301
301
|
gamma_corrected_colors = [[channel**gamma for channel in color[:3]] for color in colors]
|
302
302
|
# Blend the colors in gamma-corrected space
|
@@ -310,17 +310,17 @@ def _blend_colors_perceptually(
|
|
310
310
|
|
311
311
|
def _transform_colors(
|
312
312
|
colors: np.ndarray,
|
313
|
-
|
313
|
+
significance_sums: np.ndarray,
|
314
314
|
min_scale: float = 0.8,
|
315
315
|
max_scale: float = 1.0,
|
316
316
|
scale_factor: float = 1.0,
|
317
317
|
) -> np.ndarray:
|
318
|
-
"""Transform colors using power scaling to emphasize high
|
318
|
+
"""Transform colors using power scaling to emphasize high significance sums more. Black colors are replaced with
|
319
319
|
very dark grey to avoid issues with color scaling (rgb(0.1, 0.1, 0.1)).
|
320
320
|
|
321
321
|
Args:
|
322
322
|
colors (np.ndarray): An array of RGBA colors.
|
323
|
-
|
323
|
+
significance_sums (np.ndarray): An array of significance sums corresponding to the colors.
|
324
324
|
min_scale (float, optional): Minimum scale for color intensity. Defaults to 0.8.
|
325
325
|
max_scale (float, optional): Maximum scale for color intensity. Defaults to 1.0.
|
326
326
|
scale_factor (float, optional): Exponent for scaling, where values > 1 increase contrast by dimming small
|
@@ -340,8 +340,8 @@ def _transform_colors(
|
|
340
340
|
is_black = np.all(colors[:, :3] == black_color, axis=1)
|
341
341
|
colors[is_black, :3] = dark_grey
|
342
342
|
|
343
|
-
# Normalize the
|
344
|
-
normalized_sums =
|
343
|
+
# Normalize the significance sums to the range [0, 1]
|
344
|
+
normalized_sums = significance_sums / np.max(significance_sums)
|
345
345
|
# Apply power scaling to dim lower values and emphasize higher values
|
346
346
|
scaled_sums = normalized_sums**scale_factor
|
347
347
|
# Linearly scale the normalized sums to the range [min_scale, max_scale]
|
risk/risk.py
CHANGED
@@ -259,9 +259,9 @@ class RISK(NetworkIO, AnnotationsIO):
|
|
259
259
|
network: nx.Graph,
|
260
260
|
annotations: Dict[str, Any],
|
261
261
|
neighborhoods: Dict[str, Any],
|
262
|
-
tail: str = "right",
|
263
|
-
pval_cutoff: float = 0.01,
|
264
|
-
fdr_cutoff: float = 0.9999,
|
262
|
+
tail: str = "right",
|
263
|
+
pval_cutoff: float = 0.01,
|
264
|
+
fdr_cutoff: float = 0.9999,
|
265
265
|
impute_depth: int = 0,
|
266
266
|
prune_threshold: float = 0.0,
|
267
267
|
linkage_criterion: str = "distance",
|
@@ -275,7 +275,7 @@ class RISK(NetworkIO, AnnotationsIO):
|
|
275
275
|
Args:
|
276
276
|
network (nx.Graph): The network graph.
|
277
277
|
annotations (pd.DataFrame): DataFrame containing annotation data for the network.
|
278
|
-
neighborhoods (Dict[str, Any]): Neighborhood
|
278
|
+
neighborhoods (Dict[str, Any]): Neighborhood significance data.
|
279
279
|
tail (str, optional): Type of significance tail ("right", "left", "both"). Defaults to "right".
|
280
280
|
pval_cutoff (float, optional): p-value cutoff for significance. Defaults to 0.01.
|
281
281
|
fdr_cutoff (float, optional): FDR cutoff for significance. Defaults to 0.9999.
|
@@ -360,10 +360,10 @@ class RISK(NetworkIO, AnnotationsIO):
|
|
360
360
|
max_cluster_size=max_cluster_size,
|
361
361
|
)
|
362
362
|
|
363
|
-
# Prepare node mapping and
|
363
|
+
# Prepare node mapping and significance sums for the final NetworkGraph object
|
364
364
|
ordered_nodes = annotations["ordered_nodes"]
|
365
365
|
node_label_to_id = dict(zip(ordered_nodes, range(len(ordered_nodes))))
|
366
|
-
|
366
|
+
node_significance_sums = processed_neighborhoods["node_significance_sums"]
|
367
367
|
|
368
368
|
# Return the fully initialized NetworkGraph object
|
369
369
|
return NetworkGraph(
|
@@ -372,7 +372,7 @@ class RISK(NetworkIO, AnnotationsIO):
|
|
372
372
|
domains=domains,
|
373
373
|
trimmed_domains=trimmed_domains,
|
374
374
|
node_label_to_node_id_map=node_label_to_id,
|
375
|
-
|
375
|
+
node_significance_sums=node_significance_sums,
|
376
376
|
)
|
377
377
|
|
378
378
|
def load_plotter(
|
@@ -467,7 +467,7 @@ class RISK(NetworkIO, AnnotationsIO):
|
|
467
467
|
Args:
|
468
468
|
network (nx.Graph): The network graph.
|
469
469
|
annotations (Dict[str, Any]): Annotations data for the network.
|
470
|
-
neighborhoods (Dict[str, Any]): Neighborhood
|
470
|
+
neighborhoods (Dict[str, Any]): Neighborhood significance data.
|
471
471
|
min_cluster_size (int, optional): Minimum size for clusters. Defaults to 5.
|
472
472
|
max_cluster_size (int, optional): Maximum size for clusters. Defaults to 1000.
|
473
473
|
|
@@ -476,16 +476,18 @@ class RISK(NetworkIO, AnnotationsIO):
|
|
476
476
|
"""
|
477
477
|
# Extract necessary data from annotations and neighborhoods
|
478
478
|
ordered_annotations = annotations["ordered_annotations"]
|
479
|
-
|
480
|
-
|
481
|
-
|
479
|
+
neighborhood_significance_sums = neighborhoods["neighborhood_significance_counts"]
|
480
|
+
significant_significance_matrix = neighborhoods["significant_significance_matrix"]
|
481
|
+
significant_binary_significance_matrix = neighborhoods[
|
482
|
+
"significant_binary_significance_matrix"
|
483
|
+
]
|
482
484
|
# Call external function to define top annotations
|
483
485
|
return define_top_annotations(
|
484
486
|
network=network,
|
485
487
|
ordered_annotation_labels=ordered_annotations,
|
486
|
-
|
487
|
-
|
488
|
-
|
488
|
+
neighborhood_significance_sums=neighborhood_significance_sums,
|
489
|
+
significant_significance_matrix=significant_significance_matrix,
|
490
|
+
significant_binary_significance_matrix=significant_binary_significance_matrix,
|
489
491
|
min_cluster_size=min_cluster_size,
|
490
492
|
max_cluster_size=max_cluster_size,
|
491
493
|
)
|
@@ -498,7 +500,7 @@ class RISK(NetworkIO, AnnotationsIO):
|
|
498
500
|
linkage_method: str,
|
499
501
|
linkage_metric: str,
|
500
502
|
) -> pd.DataFrame:
|
501
|
-
"""Define domains in the network based on
|
503
|
+
"""Define domains in the network based on significance data.
|
502
504
|
|
503
505
|
Args:
|
504
506
|
neighborhoods (Dict[str, Any]): Enrichment data for neighborhoods.
|
@@ -510,12 +512,12 @@ class RISK(NetworkIO, AnnotationsIO):
|
|
510
512
|
Returns:
|
511
513
|
pd.DataFrame: Matrix of defined domains.
|
512
514
|
"""
|
513
|
-
# Extract the significant
|
514
|
-
|
515
|
+
# Extract the significant significance matrix from the neighborhoods data
|
516
|
+
significant_neighborhoods_significance = neighborhoods["significant_significance_matrix"]
|
515
517
|
# Call external function to define domains based on the extracted data
|
516
518
|
return define_domains(
|
517
519
|
top_annotations=top_annotations,
|
518
|
-
|
520
|
+
significant_neighborhoods_significance=significant_neighborhoods_significance,
|
519
521
|
linkage_criterion=linkage_criterion,
|
520
522
|
linkage_method=linkage_method,
|
521
523
|
linkage_metric=linkage_metric,
|
risk/stats/stats.py
CHANGED
@@ -44,7 +44,7 @@ def calculate_significance_matrices(
|
|
44
44
|
enrichment_pvals, enrichment_qvals, pval_cutoff=pval_cutoff, fdr_cutoff=fdr_cutoff
|
45
45
|
)
|
46
46
|
# Compute the enrichment matrix using both q-values and p-values
|
47
|
-
enrichment_matrix = (
|
47
|
+
enrichment_matrix = (enrichment_pvals**0.5) * (enrichment_qvals**2)
|
48
48
|
else:
|
49
49
|
# Compute threshold matrices based on p-value cutoffs only
|
50
50
|
depletion_alpha_threshold_matrix = _compute_threshold_matrix(
|
@@ -62,7 +62,7 @@ def calculate_significance_matrices(
|
|
62
62
|
log_enrichment_matrix = -np.log10(enrichment_matrix)
|
63
63
|
|
64
64
|
# Select the appropriate significance matrices based on the specified tail
|
65
|
-
|
65
|
+
significance_matrix, significant_binary_significance_matrix = _select_significance_matrices(
|
66
66
|
tail,
|
67
67
|
log_depletion_matrix,
|
68
68
|
depletion_alpha_threshold_matrix,
|
@@ -71,14 +71,14 @@ def calculate_significance_matrices(
|
|
71
71
|
)
|
72
72
|
|
73
73
|
# Filter the enrichment matrix using the binary significance matrix
|
74
|
-
|
75
|
-
|
74
|
+
significant_significance_matrix = np.where(
|
75
|
+
significant_binary_significance_matrix == 1, significance_matrix, 0
|
76
76
|
)
|
77
77
|
|
78
78
|
return {
|
79
|
-
"
|
80
|
-
"
|
81
|
-
"
|
79
|
+
"significance_matrix": significance_matrix,
|
80
|
+
"significant_significance_matrix": significant_significance_matrix,
|
81
|
+
"significant_binary_significance_matrix": significant_binary_significance_matrix,
|
82
82
|
}
|
83
83
|
|
84
84
|
|
@@ -109,15 +109,15 @@ def _select_significance_matrices(
|
|
109
109
|
|
110
110
|
if tail == "left":
|
111
111
|
# Select depletion matrix and corresponding alpha threshold for left-tail analysis
|
112
|
-
|
112
|
+
significance_matrix = -log_depletion_matrix
|
113
113
|
alpha_threshold_matrix = depletion_alpha_threshold_matrix
|
114
114
|
elif tail == "right":
|
115
115
|
# Select enrichment matrix and corresponding alpha threshold for right-tail analysis
|
116
|
-
|
116
|
+
significance_matrix = log_enrichment_matrix
|
117
117
|
alpha_threshold_matrix = enrichment_alpha_threshold_matrix
|
118
118
|
elif tail == "both":
|
119
119
|
# Select the matrix with the highest absolute values while preserving the sign
|
120
|
-
|
120
|
+
significance_matrix = np.where(
|
121
121
|
np.abs(log_depletion_matrix) >= np.abs(log_enrichment_matrix),
|
122
122
|
-log_depletion_matrix,
|
123
123
|
log_enrichment_matrix,
|
@@ -129,10 +129,10 @@ def _select_significance_matrices(
|
|
129
129
|
|
130
130
|
# Create a binary significance matrix where valid indices meet the alpha threshold
|
131
131
|
valid_idxs = ~np.isnan(alpha_threshold_matrix)
|
132
|
-
|
133
|
-
|
132
|
+
significant_binary_significance_matrix = np.zeros(alpha_threshold_matrix.shape)
|
133
|
+
significant_binary_significance_matrix[valid_idxs] = alpha_threshold_matrix[valid_idxs]
|
134
134
|
|
135
|
-
return
|
135
|
+
return significance_matrix, significant_binary_significance_matrix
|
136
136
|
|
137
137
|
|
138
138
|
def _compute_threshold_matrix(
|
@@ -1,37 +1,38 @@
|
|
1
|
-
risk/__init__.py,sha256=
|
1
|
+
risk/__init__.py,sha256=7yr2460_NPFOQzQdsQIZ9NxTv-tlleTl5DPCHWKAOvg,112
|
2
2
|
risk/constants.py,sha256=XInRaH78Slnw_sWgAsBFbUHkyA0h0jL0DKGuQNbOvjM,550
|
3
|
-
risk/risk.py,sha256=
|
3
|
+
risk/risk.py,sha256=HVH8zXQuTWuckswsaqm7uM8u34FL4SYa_082Fjvp6xQ,23790
|
4
4
|
risk/annotations/__init__.py,sha256=kXgadEXaCh0z8OyhOhTj7c3qXGmWgOhaSZ4gSzSb59U,147
|
5
|
-
risk/annotations/annotations.py,sha256=
|
5
|
+
risk/annotations/annotations.py,sha256=m3WeCdE1a2undpSl_Q2I17drD95r2McKtpzhiiSdxHY,13143
|
6
6
|
risk/annotations/io.py,sha256=powWzeimVdE0WCwlBCXyu5otMyZZHQujC0DS3m5DC0c,9505
|
7
7
|
risk/log/__init__.py,sha256=xKeU9uK1AnVk7Yt9GTp-E-dn7Ealow2igEXZZnQRa2c,135
|
8
8
|
risk/log/console.py,sha256=C52s3FgQ2e9kQWcXL8m7rs_pnKXt5Yy8PBHmQkOTiNo,4537
|
9
|
+
risk/log/enrichment.py,sha256=blDqaUo5KtHn0VxkvxuAIBbwlsTrdFeQxfOyOfvUmZE,346
|
9
10
|
risk/log/params.py,sha256=qSTktJ3OazldTzgtDGZkh0s30vu5kiXPkiNGLdSFDvg,6416
|
10
11
|
risk/neighborhoods/__init__.py,sha256=tKKEg4lsbqFukpgYlUGxU_v_9FOqK7V0uvM9T2QzoL0,206
|
11
12
|
risk/neighborhoods/community.py,sha256=MAgIblbuisEPwVU6mFZd4Yd9NUKlaHK99suw51r1Is0,7065
|
12
|
-
risk/neighborhoods/domains.py,sha256=
|
13
|
-
risk/neighborhoods/neighborhoods.py,sha256=
|
13
|
+
risk/neighborhoods/domains.py,sha256=_Womb95Ik8i4gfnx9zpLGXyZ4dyZmqTk2XlsC6qSeTI,11722
|
14
|
+
risk/neighborhoods/neighborhoods.py,sha256=KDT3zelogaioNH0HrtZrel_RQAphHCxnj3jv_XYX0sI,22229
|
14
15
|
risk/network/__init__.py,sha256=iEPeJdZfqp0toxtbElryB8jbz9_t_k4QQ3iDvKE8C_0,126
|
15
16
|
risk/network/geometry.py,sha256=gFtYUj9j9aul4paKq_qSGJn39Nazxu_MXv8m-tYYtrk,6840
|
16
|
-
risk/network/graph.py,sha256
|
17
|
+
risk/network/graph.py,sha256=S9f8zBPBubfqBDTZJr4Fb9Ne-SPIWBdyMU4VRDtVoM4,9662
|
17
18
|
risk/network/io.py,sha256=-NJ9Tg1s-DxhlDbwQGO4o87rbMqO4-BzShgnIgFoRRE,22962
|
18
19
|
risk/network/plot/__init__.py,sha256=MfmaXJgAZJgXZ2wrhK8pXwzETlcMaLChhWXKAozniAo,98
|
19
20
|
risk/network/plot/canvas.py,sha256=TlCpNtvoceizAumNr9I02JcBrBO6FiAFAa2ZC0bx3SU,13356
|
20
|
-
risk/network/plot/contour.py,sha256=
|
21
|
-
risk/network/plot/labels.py,sha256=
|
22
|
-
risk/network/plot/network.py,sha256=
|
21
|
+
risk/network/plot/contour.py,sha256=2ZVOlduo4Y4yIpXDJMIKO-v7eULcJ2QacQyOc7pUAxE,15267
|
22
|
+
risk/network/plot/labels.py,sha256=YqeOhE7nah16kK3L88JnOJVqE6WWj7lm23niVdEc8cU,45504
|
23
|
+
risk/network/plot/network.py,sha256=_yyOUoxJ_jelZV3TMCCTcGnt014TBYMUfecSLOiUb7E,13788
|
23
24
|
risk/network/plot/plotter.py,sha256=iTPMiTnTTatM_-q1Ox_bjt5Pvv-Lo8gceiYB6TVzDcw,5770
|
24
|
-
risk/network/plot/utils/color.py,sha256=
|
25
|
+
risk/network/plot/utils/color.py,sha256=rGOx4WAdjyaeWFALybkKzJabm9VSmsWb5_hsb__pcNg,19701
|
25
26
|
risk/network/plot/utils/layout.py,sha256=RnJq0yODpoheZnDl7KKFPQeXrnrsS3FLIdxupoYVZq4,3553
|
26
27
|
risk/stats/__init__.py,sha256=WcgoETQ-hS0LQqKRsAMIPtP15xZ-4eul6VUBuUx4Wzc,220
|
27
28
|
risk/stats/hypergeom.py,sha256=oc39f02ViB1vQ-uaDrxG_tzAT6dxQBRjc88EK2EGn78,2282
|
28
29
|
risk/stats/poisson.py,sha256=polLgwS08MTCNzupYdmMUoEUYrJOjAbcYtYwjlfeE5Y,1803
|
29
|
-
risk/stats/stats.py,sha256=
|
30
|
+
risk/stats/stats.py,sha256=z8NrhiVj4BzJ250bVLfytpmfC7RzYu7mBuIZD_l0aCA,7222
|
30
31
|
risk/stats/permutation/__init__.py,sha256=neJp7FENC-zg_CGOXqv-iIvz1r5XUKI9Ruxhmq7kDOI,105
|
31
32
|
risk/stats/permutation/permutation.py,sha256=meBNSrbRa9P8WJ54n485l0H7VQJlMSfHqdN4aCKYCtQ,10105
|
32
33
|
risk/stats/permutation/test_functions.py,sha256=lftOude6hee0pyR80HlBD32522JkDoN5hrKQ9VEbuoY,2345
|
33
|
-
risk_network-0.0.
|
34
|
-
risk_network-0.0.
|
35
|
-
risk_network-0.0.
|
36
|
-
risk_network-0.0.
|
37
|
-
risk_network-0.0.
|
34
|
+
risk_network-0.0.9b1.dist-info/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
|
35
|
+
risk_network-0.0.9b1.dist-info/METADATA,sha256=3c5uAqoFdzK2gIz7kl1FYYE2uEZLv0LEeQ6_Fad3QgQ,47497
|
36
|
+
risk_network-0.0.9b1.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
37
|
+
risk_network-0.0.9b1.dist-info/top_level.txt,sha256=NX7C2PFKTvC1JhVKv14DFlFAIFnKc6Lpsu1ZfxvQwVw,5
|
38
|
+
risk_network-0.0.9b1.dist-info/RECORD,,
|