risk-network 0.0.8b26__py3-none-any.whl → 0.0.9b26__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.
Files changed (46) hide show
  1. risk/__init__.py +2 -2
  2. risk/annotations/__init__.py +2 -2
  3. risk/annotations/annotations.py +74 -47
  4. risk/annotations/io.py +47 -31
  5. risk/log/__init__.py +4 -2
  6. risk/log/{config.py → console.py} +5 -3
  7. risk/log/{params.py → parameters.py} +17 -42
  8. risk/neighborhoods/__init__.py +3 -5
  9. risk/neighborhoods/api.py +446 -0
  10. risk/neighborhoods/community.py +255 -77
  11. risk/neighborhoods/domains.py +62 -31
  12. risk/neighborhoods/neighborhoods.py +156 -160
  13. risk/network/__init__.py +1 -3
  14. risk/network/geometry.py +65 -57
  15. risk/network/graph/__init__.py +6 -0
  16. risk/network/graph/api.py +194 -0
  17. risk/network/{graph.py → graph/network.py} +87 -37
  18. risk/network/graph/summary.py +254 -0
  19. risk/network/io.py +56 -47
  20. risk/network/plotter/__init__.py +6 -0
  21. risk/network/plotter/api.py +54 -0
  22. risk/network/{plot → plotter}/canvas.py +7 -4
  23. risk/network/{plot → plotter}/contour.py +22 -19
  24. risk/network/{plot → plotter}/labels.py +69 -74
  25. risk/network/{plot → plotter}/network.py +170 -34
  26. risk/network/{plot/utils/color.py → plotter/utils/colors.py} +104 -112
  27. risk/network/{plot → plotter}/utils/layout.py +8 -5
  28. risk/risk.py +11 -500
  29. risk/stats/__init__.py +8 -4
  30. risk/stats/binom.py +51 -0
  31. risk/stats/chi2.py +69 -0
  32. risk/stats/hypergeom.py +27 -17
  33. risk/stats/permutation/__init__.py +1 -1
  34. risk/stats/permutation/permutation.py +44 -38
  35. risk/stats/permutation/test_functions.py +25 -17
  36. risk/stats/poisson.py +15 -9
  37. risk/stats/stats.py +15 -13
  38. risk/stats/zscore.py +68 -0
  39. {risk_network-0.0.8b26.dist-info → risk_network-0.0.9b26.dist-info}/METADATA +9 -5
  40. risk_network-0.0.9b26.dist-info/RECORD +44 -0
  41. {risk_network-0.0.8b26.dist-info → risk_network-0.0.9b26.dist-info}/WHEEL +1 -1
  42. risk/network/plot/__init__.py +0 -6
  43. risk/network/plot/plotter.py +0 -137
  44. risk_network-0.0.8b26.dist-info/RECORD +0 -37
  45. {risk_network-0.0.8b26.dist-info → risk_network-0.0.9b26.dist-info}/LICENSE +0 -0
  46. {risk_network-0.0.8b26.dist-info → risk_network-0.0.9b26.dist-info}/top_level.txt +0 -0
@@ -3,18 +3,26 @@ risk/network/plot/network
3
3
  ~~~~~~~~~~~~~~~~~~~~~~~~~
4
4
  """
5
5
 
6
- from typing import Any, List, Tuple, Union
6
+ from typing import Any, Dict, List, Tuple, Union
7
7
 
8
+ import matplotlib.pyplot as plt
8
9
  import networkx as nx
9
10
  import numpy as np
10
11
 
11
12
  from risk.log import params
12
- from risk.network.graph import NetworkGraph
13
- from risk.network.plot.utils.color import get_domain_colors, to_rgba
13
+ from risk.network.graph.network import NetworkGraph
14
+ from risk.network.plotter.canvas import Canvas
15
+ from risk.network.plotter.contour import Contour
16
+ from risk.network.plotter.labels import Labels
17
+ from risk.network.plotter.utils.colors import get_domain_colors, to_rgba
18
+ from risk.network.plotter.utils.layout import calculate_bounding_box
14
19
 
15
20
 
16
21
  class Network:
17
- """Class for plotting nodes and edges in a network graph."""
22
+ """A class for plotting network graphs with customizable options.
23
+
24
+ The Network class provides methods to plot network graphs with flexible node and edge properties.
25
+ """
18
26
 
19
27
  def __init__(self, graph: NetworkGraph, ax: Any = None) -> None:
20
28
  """Initialize the NetworkPlotter class.
@@ -203,11 +211,12 @@ class Network:
203
211
  max_scale: float = 1.0,
204
212
  scale_factor: float = 1.0,
205
213
  alpha: Union[float, None] = 1.0,
206
- nonenriched_color: Union[str, List, Tuple, np.ndarray] = "white",
207
- nonenriched_alpha: Union[float, None] = 1.0,
214
+ nonsignificant_color: Union[str, List, Tuple, np.ndarray] = "white",
215
+ nonsignificant_alpha: Union[float, None] = 1.0,
216
+ ids_to_colors: Union[Dict[int, Any], None] = None,
208
217
  random_seed: int = 888,
209
218
  ) -> np.ndarray:
210
- """Adjust the colors of nodes in the network graph based on enrichment.
219
+ """Adjust the colors of nodes in the network graph based on significance.
211
220
 
212
221
  Args:
213
222
  cmap (str, optional): Colormap to use for coloring the nodes. Defaults to "gist_rainbow".
@@ -218,16 +227,17 @@ class Network:
218
227
  min_scale (float, optional): Minimum scale for color intensity. Defaults to 0.8.
219
228
  max_scale (float, optional): Maximum scale for color intensity. Defaults to 1.0.
220
229
  scale_factor (float, optional): Factor for adjusting the color scaling intensity. Defaults to 1.0.
221
- alpha (float, None, optional): Alpha value for enriched nodes. If provided, it overrides any existing alpha values found in `color`.
230
+ alpha (float, None, optional): Alpha value for significant nodes. If provided, it overrides any existing alpha values found in `color`.
222
231
  Defaults to 1.0.
223
- nonenriched_color (str, List, Tuple, or np.ndarray, optional): Color for non-enriched nodes. Can be a single color or an array of colors.
232
+ 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
233
  Defaults to "white".
225
- nonenriched_alpha (float, None, optional): Alpha value for non-enriched nodes. If provided, it overrides any existing alpha values found
226
- in `nonenriched_color`. Defaults to 1.0.
234
+ nonsignificant_alpha (float, None, optional): Alpha value for non-significant nodes. If provided, it overrides any existing alpha values found
235
+ in `nonsignificant_color`. Defaults to 1.0.
236
+ ids_to_colors (Dict[int, Any], None, optional): Mapping of domain IDs to specific colors. Defaults to None.
227
237
  random_seed (int, optional): Seed for random number generation. Defaults to 888.
228
238
 
229
239
  Returns:
230
- np.ndarray: Array of RGBA colors adjusted for enrichment status.
240
+ np.ndarray: Array of RGBA colors adjusted for significance status.
231
241
  """
232
242
  # Get the initial domain colors for each node, which are returned as RGBA
233
243
  network_colors = get_domain_colors(
@@ -239,50 +249,176 @@ class Network:
239
249
  min_scale=min_scale,
240
250
  max_scale=max_scale,
241
251
  scale_factor=scale_factor,
252
+ ids_to_colors=ids_to_colors,
242
253
  random_seed=random_seed,
243
254
  )
244
- # Apply the alpha value for enriched nodes
245
- network_colors[:, 3] = alpha # Apply the alpha value to the enriched nodes' A channel
246
- # Convert the non-enriched color to RGBA using the to_rgba helper function
247
- nonenriched_color_rgba = to_rgba(
248
- color=nonenriched_color, alpha=nonenriched_alpha, num_repeats=1
255
+ # Apply the alpha value for significant nodes
256
+ network_colors[:, 3] = alpha # Apply the alpha value to the significant nodes' A channel
257
+ # Convert the non-significant color to RGBA using the to_rgba helper function
258
+ nonsignificant_color_rgba = to_rgba(
259
+ color=nonsignificant_color, alpha=nonsignificant_alpha, num_repeats=1
249
260
  ) # num_repeats=1 for a single color
250
- # Adjust node colors: replace any nodes where all three RGB values are equal and less than 0.1
261
+ # Adjust node colors: replace any nodes where all three RGB values are equal and less than or equal to 0.1
251
262
  # 0.1 is a predefined threshold for the minimum color intensity
252
263
  adjusted_network_colors = np.where(
253
264
  (
254
- np.all(network_colors[:, :3] < 0.1, axis=1)
265
+ np.all(network_colors[:, :3] <= 0.1, axis=1)
255
266
  & np.all(network_colors[:, :3] == network_colors[:, 0:1], axis=1)
256
267
  )[:, None],
257
268
  np.tile(
258
- np.array(nonenriched_color_rgba), (network_colors.shape[0], 1)
259
- ), # Replace with the full RGBA non-enriched color
269
+ np.array(nonsignificant_color_rgba), (network_colors.shape[0], 1)
270
+ ), # Replace with the full RGBA non-significant color
260
271
  network_colors, # Keep the original colors where no match is found
261
272
  )
262
273
  return adjusted_network_colors
263
274
 
264
275
  def get_annotated_node_sizes(
265
- self, enriched_size: int = 50, nonenriched_size: int = 25
276
+ self, significant_size: int = 50, nonsignificant_size: int = 25
266
277
  ) -> np.ndarray:
267
- """Adjust the sizes of nodes in the network graph based on whether they are enriched or not.
278
+ """Adjust the sizes of nodes in the network graph based on whether they are significant or not.
268
279
 
269
280
  Args:
270
- enriched_size (int): Size for enriched nodes. Defaults to 50.
271
- nonenriched_size (int): Size for non-enriched nodes. Defaults to 25.
281
+ significant_size (int): Size for significant nodes. Defaults to 50.
282
+ nonsignificant_size (int): Size for non-significant nodes. Defaults to 25.
272
283
 
273
284
  Returns:
274
- np.ndarray: Array of node sizes, with enriched nodes larger than non-enriched ones.
285
+ np.ndarray: Array of node sizes, with significant nodes larger than non-significant ones.
275
286
  """
276
- # Merge all enriched nodes from the domain_id_to_node_ids_map dictionary
277
- enriched_nodes = set()
287
+ # Merge all significant nodes from the domain_id_to_node_ids_map dictionary
288
+ significant_nodes = set()
278
289
  for _, node_ids in self.graph.domain_id_to_node_ids_map.items():
279
- enriched_nodes.update(node_ids)
290
+ significant_nodes.update(node_ids)
280
291
 
281
- # Initialize all node sizes to the non-enriched size
282
- node_sizes = np.full(len(self.graph.network.nodes), nonenriched_size)
283
- # Set the size for enriched nodes
284
- for node in enriched_nodes:
292
+ # Initialize all node sizes to the non-significant size
293
+ node_sizes = np.full(len(self.graph.network.nodes), nonsignificant_size)
294
+ # Set the size for significant nodes
295
+ for node in significant_nodes:
285
296
  if node in self.graph.network.nodes:
286
- node_sizes[node] = enriched_size
297
+ node_sizes[node] = significant_size
287
298
 
288
299
  return node_sizes
300
+
301
+
302
+ class NetworkPlotter(Canvas, Network, Contour, Labels):
303
+ """A class for visualizing network graphs with customizable options.
304
+
305
+ The NetworkPlotter class uses a NetworkGraph object and provides methods to plot the network with
306
+ flexible node and edge properties. It also supports plotting labels, contours, drawing the network's
307
+ perimeter, and adjusting background colors.
308
+ """
309
+
310
+ def __init__(
311
+ self,
312
+ graph: NetworkGraph,
313
+ figsize: Tuple = (10, 10),
314
+ background_color: Union[str, List, Tuple, np.ndarray] = "white",
315
+ background_alpha: Union[float, None] = 1.0,
316
+ pad: float = 0.3,
317
+ ) -> None:
318
+ """Initialize the NetworkPlotter with a NetworkGraph object and plotting parameters.
319
+
320
+ Args:
321
+ graph (NetworkGraph): The network data and attributes to be visualized.
322
+ figsize (Tuple, optional): Size of the figure in inches (width, height). Defaults to (10, 10).
323
+ background_color (str, List, Tuple, np.ndarray, optional): Background color of the plot. Defaults to "white".
324
+ background_alpha (float, None, optional): Transparency level of the background color. If provided, it overrides
325
+ any existing alpha values found in background_color. Defaults to 1.0.
326
+ pad (float, optional): Padding value to adjust the axis limits. Defaults to 0.3.
327
+ """
328
+ self.graph = graph
329
+ # Initialize the plot with the specified parameters
330
+ self.ax = self._initialize_plot(
331
+ graph=graph,
332
+ figsize=figsize,
333
+ background_color=background_color,
334
+ background_alpha=background_alpha,
335
+ pad=pad,
336
+ )
337
+ super().__init__(graph=graph, ax=self.ax)
338
+
339
+ def _initialize_plot(
340
+ self,
341
+ graph: NetworkGraph,
342
+ figsize: Tuple,
343
+ background_color: Union[str, List, Tuple, np.ndarray],
344
+ background_alpha: Union[float, None],
345
+ pad: float,
346
+ ) -> plt.Axes:
347
+ """Set up the plot with figure size and background color.
348
+
349
+ Args:
350
+ graph (NetworkGraph): The network data and attributes to be visualized.
351
+ figsize (Tuple): Size of the figure in inches (width, height).
352
+ background_color (str, List, Tuple, or np.ndarray): Background color of the plot. Can be a single color or an array of colors.
353
+ background_alpha (float, None, optional): Transparency level of the background color. If provided, it overrides any existing
354
+ alpha values found in `background_color`.
355
+ pad (float, optional): Padding value to adjust the axis limits.
356
+
357
+ Returns:
358
+ plt.Axes: The axis object for the plot.
359
+ """
360
+ # Log the plotter settings
361
+ params.log_plotter(
362
+ figsize=figsize,
363
+ background_color=background_color,
364
+ background_alpha=background_alpha,
365
+ pad=pad,
366
+ )
367
+
368
+ # Extract node coordinates from the network graph
369
+ node_coordinates = graph.node_coordinates
370
+ # Calculate the center and radius of the bounding box around the network
371
+ center, radius = calculate_bounding_box(node_coordinates)
372
+
373
+ # Create a new figure and axis for plotting
374
+ fig, ax = plt.subplots(figsize=figsize)
375
+ fig.tight_layout() # Adjust subplot parameters to give specified padding
376
+ # Set axis limits based on the calculated bounding box and radius
377
+ ax.set_xlim([center[0] - radius - pad, center[0] + radius + pad])
378
+ ax.set_ylim([center[1] - radius - pad, center[1] + radius + pad])
379
+ ax.set_aspect("equal") # Ensure the aspect ratio is equal
380
+
381
+ # Set the background color of the plot
382
+ # Convert color to RGBA using the to_rgba helper function
383
+ fig.patch.set_facecolor(
384
+ to_rgba(color=background_color, alpha=background_alpha, num_repeats=1)
385
+ ) # num_repeats=1 for single color
386
+ ax.invert_yaxis() # Invert the y-axis to match typical image coordinates
387
+ # Remove axis spines for a cleaner look
388
+ for spine in ax.spines.values():
389
+ spine.set_visible(False)
390
+
391
+ # Hide axis ticks and labels
392
+ ax.set_xticks([])
393
+ ax.set_yticks([])
394
+ ax.patch.set_visible(False) # Hide the axis background
395
+
396
+ return ax
397
+
398
+ @staticmethod
399
+ def savefig(*args, pad_inches: float = 0.5, dpi: int = 100, **kwargs) -> None:
400
+ """Save the current plot to a file with additional export options.
401
+
402
+ Args:
403
+ *args: Positional arguments passed to `plt.savefig`.
404
+ pad_inches (float, optional): Padding around the figure when saving. Defaults to 0.5.
405
+ dpi (int, optional): Dots per inch (DPI) for the exported image. Defaults to 300.
406
+ **kwargs: Keyword arguments passed to `plt.savefig`, such as filename and format.
407
+ """
408
+ # Ensure user-provided kwargs take precedence
409
+ kwargs.setdefault("dpi", dpi)
410
+ kwargs.setdefault("pad_inches", pad_inches)
411
+ # Ensure the plot is saved with tight bounding box if not specified
412
+ kwargs.setdefault("bbox_inches", "tight")
413
+ # Call plt.savefig with combined arguments
414
+ plt.savefig(*args, **kwargs)
415
+
416
+ @staticmethod
417
+ def show(*args, **kwargs) -> None:
418
+ """Display the current plot.
419
+
420
+ Args:
421
+ *args: Positional arguments passed to `plt.show`.
422
+ **kwargs: Keyword arguments passed to `plt.show`.
423
+ """
424
+ plt.show(*args, **kwargs)