risk-network 0.0.7b1__tar.gz → 0.0.7b2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/PKG-INFO +1 -1
  2. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/__init__.py +1 -1
  3. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/network/graph.py +95 -40
  4. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk_network.egg-info/PKG-INFO +1 -1
  5. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/LICENSE +0 -0
  6. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/MANIFEST.in +0 -0
  7. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/README.md +0 -0
  8. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/pyproject.toml +0 -0
  9. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/annotations/__init__.py +0 -0
  10. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/annotations/annotations.py +0 -0
  11. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/annotations/io.py +0 -0
  12. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/constants.py +0 -0
  13. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/log/__init__.py +0 -0
  14. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/log/console.py +0 -0
  15. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/log/params.py +0 -0
  16. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/neighborhoods/__init__.py +0 -0
  17. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/neighborhoods/community.py +0 -0
  18. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/neighborhoods/domains.py +0 -0
  19. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/neighborhoods/neighborhoods.py +0 -0
  20. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/network/__init__.py +0 -0
  21. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/network/geometry.py +0 -0
  22. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/network/io.py +0 -0
  23. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/network/plot.py +0 -0
  24. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/risk.py +0 -0
  25. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/stats/__init__.py +0 -0
  26. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/stats/fisher_exact.py +0 -0
  27. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/stats/hypergeom.py +0 -0
  28. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/stats/permutation/__init__.py +0 -0
  29. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/stats/permutation/permutation.py +0 -0
  30. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/stats/permutation/test_functions.py +0 -0
  31. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk/stats/stats.py +0 -0
  32. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk_network.egg-info/SOURCES.txt +0 -0
  33. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk_network.egg-info/dependency_links.txt +0 -0
  34. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk_network.egg-info/requires.txt +0 -0
  35. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/risk_network.egg-info/top_level.txt +0 -0
  36. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/setup.cfg +0 -0
  37. {risk_network-0.0.7b1 → risk_network-0.0.7b2}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: risk-network
3
- Version: 0.0.7b1
3
+ Version: 0.0.7b2
4
4
  Summary: A Python package for biological network analysis
5
5
  Author: Ira Horecka
6
6
  Author-email: Ira Horecka <ira89@icloud.com>
@@ -7,4 +7,4 @@ RISK: RISK Infers Spatial Kinships
7
7
 
8
8
  from risk.risk import RISK
9
9
 
10
- __version__ = "0.0.7-beta.1"
10
+ __version__ = "0.0.7-beta.2"
@@ -55,10 +55,9 @@ class NetworkGraph:
55
55
  self.node_label_to_node_id_map = node_label_to_node_id_map
56
56
  # NOTE: Below this point, instance attributes (i.e., self) will be used!
57
57
  self.domain_id_to_node_labels_map = self._create_domain_id_to_node_labels_map()
58
- # self.network and self.node_coordinates are properly declared in _initialize_network
59
- self.network = None
60
- self.node_coordinates = None
61
- self._initialize_network(network)
58
+ # Unfold the network's 3D coordinates to 2D and extract node coordinates
59
+ self.network = _unfold_sphere_to_plane(network)
60
+ self.node_coordinates = _extract_node_coordinates(self.network)
62
61
 
63
62
  def _create_domain_id_to_node_ids_map(self, domains: pd.DataFrame) -> Dict[str, Any]:
64
63
  """Create a mapping from domains to the list of node IDs belonging to each domain.
@@ -109,19 +108,6 @@ class NetworkGraph:
109
108
 
110
109
  return domain_id_to_label_map
111
110
 
112
- def _initialize_network(self, G: nx.Graph) -> None:
113
- """Initialize the network by unfolding it and extracting node coordinates.
114
-
115
- Args:
116
- G (nx.Graph): The input network graph with 3D node coordinates.
117
- """
118
- # Unfold the network's 3D coordinates to 2D
119
- G_2d = _unfold_sphere_to_plane(G)
120
- # Assign the unfolded graph to self.network
121
- self.network = G_2d
122
- # Extract 2D coordinates of nodes
123
- self.node_coordinates = _extract_node_coordinates(G_2d)
124
-
125
111
  def get_domain_colors(
126
112
  self,
127
113
  cmap: str = "gist_rainbow",
@@ -200,14 +186,15 @@ class NetworkGraph:
200
186
  Returns:
201
187
  dict: A dictionary mapping domain keys to their corresponding RGBA colors.
202
188
  """
203
- # Exclude non-numeric domain columns
204
- numeric_domains = [
205
- col for col in self.domains.columns if isinstance(col, (int, np.integer))
206
- ]
207
- domains = np.sort(numeric_domains)
189
+ # Get colors for each domain based on node positions
208
190
  domain_colors = _get_colors(
209
- num_colors_to_generate=len(domains), cmap=cmap, color=color, random_seed=random_seed
191
+ self.network,
192
+ self.domain_id_to_node_ids_map,
193
+ cmap=cmap,
194
+ color=color,
195
+ random_seed=random_seed,
210
196
  )
197
+ self.network, self.domain_id_to_node_ids_map
211
198
  return dict(zip(self.domain_id_to_node_ids_map.keys(), domain_colors))
212
199
 
213
200
 
@@ -300,35 +287,103 @@ def _extract_node_coordinates(G: nx.Graph) -> np.ndarray:
300
287
 
301
288
 
302
289
  def _get_colors(
303
- num_colors_to_generate: int = 10,
290
+ network,
291
+ domain_id_to_node_ids_map,
304
292
  cmap: str = "gist_rainbow",
305
293
  color: Union[str, None] = None,
306
294
  random_seed: int = 888,
307
295
  ) -> List[Tuple]:
308
- """Generate a list of RGBA colors from a specified colormap or use a direct color string.
296
+ """Generate a list of RGBA colors based on domain centroids, ensuring that domains
297
+ close in space get maximally separated colors, while keeping some randomness.
309
298
 
310
299
  Args:
311
- num_colors_to_generate (int): The number of colors to generate. Defaults to 10.
300
+ network (NetworkX graph): The graph representing the network.
301
+ domain_id_to_node_ids_map (dict): Mapping from domain IDs to lists of node IDs.
312
302
  cmap (str, optional): The name of the colormap to use. Defaults to "gist_rainbow".
313
303
  color (str or None, optional): A specific color to use for all generated colors.
314
304
  random_seed (int): Seed for random number generation. Defaults to 888.
315
- Defaults to None.
316
305
 
317
306
  Returns:
318
- list of tuple: List of RGBA colors.
307
+ List[Tuple]: List of RGBA colors.
319
308
  """
320
- # Set random seed for reproducibility
321
309
  random.seed(random_seed)
310
+ # Determine the number of colors to generate based on the number of domains
311
+ num_colors_to_generate = len(domain_id_to_node_ids_map)
322
312
  if color:
323
- # If a direct color is provided, generate a list with that color
313
+ # Generate all colors as the same specified color
324
314
  rgba = matplotlib.colors.to_rgba(color)
325
- rgbas = [rgba] * num_colors_to_generate
326
- else:
327
- colormap = matplotlib.colormaps.get_cmap(cmap)
328
- # Generate evenly distributed color positions
329
- color_positions = np.linspace(0, 1, num_colors_to_generate)
330
- random.shuffle(color_positions) # Shuffle the positions to randomize colors
331
- # Generate colors based on shuffled positions
332
- rgbas = [colormap(pos) for pos in color_positions]
333
-
334
- return rgbas
315
+ return [rgba] * num_colors_to_generate
316
+
317
+ # Load colormap
318
+ colormap = matplotlib.colormaps.get_cmap(cmap)
319
+ # Step 1: Calculate centroids for each domain
320
+ centroids = _calculate_centroids(network, domain_id_to_node_ids_map)
321
+ # Step 2: Calculate pairwise distances between centroids
322
+ centroid_array = np.array(centroids)
323
+ dist_matrix = np.linalg.norm(centroid_array[:, None] - centroid_array, axis=-1)
324
+ # Step 3: Generate positions in the colormap, with a focus on centroids that are close
325
+ remaining_indices = set(range(num_colors_to_generate))
326
+ # Assign distant colors to close centroids
327
+ color_positions = _assign_distant_colors(
328
+ remaining_indices, dist_matrix, colormap, num_colors_to_generate
329
+ )
330
+ # Step 4: Add some random jitter to color positions to avoid overly systematic results
331
+ jitter = np.random.uniform(-0.05, 0.05, size=num_colors_to_generate)
332
+ color_positions = np.clip(color_positions + jitter, 0, 1)
333
+
334
+ # Step 5: Generate colors based on positions
335
+ return [colormap(pos) for pos in color_positions]
336
+
337
+
338
+ def _calculate_centroids(network, domain_id_to_node_ids_map):
339
+ """Calculate the centroid for each domain based on node x and y coordinates in the network.
340
+
341
+ Args:
342
+ network (NetworkX graph): The graph representing the network.
343
+ domain_id_to_node_ids_map (dict): Mapping from domain IDs to lists of node IDs.
344
+
345
+ Returns:
346
+ List[Tuple[float, float]]: List of centroids (x, y) for each domain.
347
+ """
348
+ centroids = []
349
+ for domain_id, node_ids in domain_id_to_node_ids_map.items():
350
+ # Extract x and y coordinates from the network nodes
351
+ node_positions = np.array(
352
+ [[network.nodes[node_id]["x"], network.nodes[node_id]["y"]] for node_id in node_ids]
353
+ )
354
+ # Compute the centroid as the mean of the x and y coordinates
355
+ centroid = np.mean(node_positions, axis=0)
356
+ centroids.append(tuple(centroid))
357
+
358
+ return centroids
359
+
360
+
361
+ def _assign_distant_colors(remaining_indices, dist_matrix, colormap, num_colors_to_generate):
362
+ """Assign colors to centroids that are close in space, ensuring stark color differences.
363
+
364
+ Args:
365
+ remaining_indices (set): Indices of centroids left to color.
366
+ dist_matrix (ndarray): Matrix of pairwise centroid distances.
367
+ colormap (Colormap): The colormap used to assign colors.
368
+ num_colors_to_generate (int): Number of colors to generate.
369
+
370
+ Returns:
371
+ np.array: Array of color positions in the colormap.
372
+ """
373
+ color_positions = np.zeros(num_colors_to_generate)
374
+ # Convert the set to a list to index over it
375
+ remaining_indices = list(remaining_indices)
376
+ # Sort remaining indices by centroid proximity (based on sum of distances to others)
377
+ proximity_order = sorted(remaining_indices, key=lambda idx: np.sum(dist_matrix[idx]))
378
+ # Assign colors starting with the most distant points in proximity order
379
+ for i, idx in enumerate(proximity_order):
380
+ color_positions[idx] = i / num_colors_to_generate
381
+
382
+ # Adjust colors so that centroids close to one another are maximally distant on the color spectrum
383
+ half_spectrum = int(num_colors_to_generate / 2)
384
+ for i in range(half_spectrum):
385
+ # Split the spectrum so that close centroids are assigned distant colors
386
+ color_positions[proximity_order[i]] = (i * 2) / num_colors_to_generate
387
+ color_positions[proximity_order[-(i + 1)]] = ((i * 2) + 1) / num_colors_to_generate
388
+
389
+ return color_positions
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: risk-network
3
- Version: 0.0.7b1
3
+ Version: 0.0.7b2
4
4
  Summary: A Python package for biological network analysis
5
5
  Author: Ira Horecka
6
6
  Author-email: Ira Horecka <ira89@icloud.com>
File without changes
File without changes
File without changes
File without changes