risk-network 0.0.7b10__tar.gz → 0.0.7b12__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.
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/PKG-INFO +1 -1
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/__init__.py +1 -1
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/annotations/annotations.py +1 -1
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/annotations/io.py +10 -10
- risk_network-0.0.7b12/risk/log/config.py +139 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/neighborhoods/domains.py +1 -1
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/network/plot.py +124 -17
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/risk.py +2 -9
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/stats/permutation/test_functions.py +2 -2
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk_network.egg-info/PKG-INFO +1 -1
- risk_network-0.0.7b10/risk/log/config.py +0 -49
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/LICENSE +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/MANIFEST.in +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/README.md +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/pyproject.toml +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/annotations/__init__.py +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/constants.py +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/log/__init__.py +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/log/params.py +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/neighborhoods/__init__.py +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/neighborhoods/community.py +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/neighborhoods/neighborhoods.py +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/network/__init__.py +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/network/geometry.py +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/network/graph.py +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/network/io.py +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/stats/__init__.py +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/stats/hypergeom.py +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/stats/permutation/__init__.py +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/stats/permutation/permutation.py +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/stats/poisson.py +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk/stats/stats.py +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk_network.egg-info/SOURCES.txt +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk_network.egg-info/dependency_links.txt +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk_network.egg-info/requires.txt +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/risk_network.egg-info/top_level.txt +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/setup.cfg +0 -0
- {risk_network-0.0.7b10 → risk_network-0.0.7b12}/setup.py +0 -0
@@ -25,12 +25,12 @@ class AnnotationsIO:
|
|
25
25
|
def __init__(self):
|
26
26
|
pass
|
27
27
|
|
28
|
-
def load_json_annotation(self,
|
28
|
+
def load_json_annotation(self, network: nx.Graph, filepath: str) -> Dict[str, Any]:
|
29
29
|
"""Load annotations from a JSON file and convert them to a DataFrame.
|
30
30
|
|
31
31
|
Args:
|
32
|
-
filepath (str): Path to the JSON annotations file.
|
33
32
|
network (NetworkX graph): The network to which the annotations are related.
|
33
|
+
filepath (str): Path to the JSON annotations file.
|
34
34
|
|
35
35
|
Returns:
|
36
36
|
dict: A dictionary containing ordered nodes, ordered annotations, and the annotations matrix.
|
@@ -49,8 +49,8 @@ class AnnotationsIO:
|
|
49
49
|
|
50
50
|
def load_excel_annotation(
|
51
51
|
self,
|
52
|
-
filepath: str,
|
53
52
|
network: nx.Graph,
|
53
|
+
filepath: str,
|
54
54
|
label_colname: str = "label",
|
55
55
|
nodes_colname: str = "nodes",
|
56
56
|
sheet_name: str = "Sheet1",
|
@@ -59,8 +59,8 @@ class AnnotationsIO:
|
|
59
59
|
"""Load annotations from an Excel file and associate them with the network.
|
60
60
|
|
61
61
|
Args:
|
62
|
-
filepath (str): Path to the Excel annotations file.
|
63
62
|
network (nx.Graph): The NetworkX graph to which the annotations are related.
|
63
|
+
filepath (str): Path to the Excel annotations file.
|
64
64
|
label_colname (str): Name of the column containing the labels (e.g., GO terms).
|
65
65
|
nodes_colname (str): Name of the column containing the nodes associated with each label.
|
66
66
|
sheet_name (str, optional): The name of the Excel sheet to load (default is 'Sheet1').
|
@@ -87,8 +87,8 @@ class AnnotationsIO:
|
|
87
87
|
|
88
88
|
def load_csv_annotation(
|
89
89
|
self,
|
90
|
-
filepath: str,
|
91
90
|
network: nx.Graph,
|
91
|
+
filepath: str,
|
92
92
|
label_colname: str = "label",
|
93
93
|
nodes_colname: str = "nodes",
|
94
94
|
nodes_delimiter: str = ";",
|
@@ -96,8 +96,8 @@ class AnnotationsIO:
|
|
96
96
|
"""Load annotations from a CSV file and associate them with the network.
|
97
97
|
|
98
98
|
Args:
|
99
|
-
filepath (str): Path to the CSV annotations file.
|
100
99
|
network (nx.Graph): The NetworkX graph to which the annotations are related.
|
100
|
+
filepath (str): Path to the CSV annotations file.
|
101
101
|
label_colname (str): Name of the column containing the labels (e.g., GO terms).
|
102
102
|
nodes_colname (str): Name of the column containing the nodes associated with each label.
|
103
103
|
nodes_delimiter (str, optional): Delimiter used to separate multiple nodes within the nodes column (default is ';').
|
@@ -121,8 +121,8 @@ class AnnotationsIO:
|
|
121
121
|
|
122
122
|
def load_tsv_annotation(
|
123
123
|
self,
|
124
|
-
filepath: str,
|
125
124
|
network: nx.Graph,
|
125
|
+
filepath: str,
|
126
126
|
label_colname: str = "label",
|
127
127
|
nodes_colname: str = "nodes",
|
128
128
|
nodes_delimiter: str = ";",
|
@@ -130,8 +130,8 @@ class AnnotationsIO:
|
|
130
130
|
"""Load annotations from a TSV file and associate them with the network.
|
131
131
|
|
132
132
|
Args:
|
133
|
-
filepath (str): Path to the TSV annotations file.
|
134
133
|
network (nx.Graph): The NetworkX graph to which the annotations are related.
|
134
|
+
filepath (str): Path to the TSV annotations file.
|
135
135
|
label_colname (str): Name of the column containing the labels (e.g., GO terms).
|
136
136
|
nodes_colname (str): Name of the column containing the nodes associated with each label.
|
137
137
|
nodes_delimiter (str, optional): Delimiter used to separate multiple nodes within the nodes column (default is ';').
|
@@ -153,12 +153,12 @@ class AnnotationsIO:
|
|
153
153
|
# Load the annotations into the provided network
|
154
154
|
return load_annotations(network, annotations_input)
|
155
155
|
|
156
|
-
def load_dict_annotation(self, content: Dict[str, Any]
|
156
|
+
def load_dict_annotation(self, network: nx.Graph, content: Dict[str, Any]) -> Dict[str, Any]:
|
157
157
|
"""Load annotations from a provided dictionary and convert them to a dictionary annotation.
|
158
158
|
|
159
159
|
Args:
|
160
|
-
content (dict): The annotations dictionary to load.
|
161
160
|
network (NetworkX graph): The network to which the annotations are related.
|
161
|
+
content (dict): The annotations dictionary to load.
|
162
162
|
|
163
163
|
Returns:
|
164
164
|
dict: A dictionary containing ordered nodes, ordered annotations, and the annotations matrix.
|
@@ -0,0 +1,139 @@
|
|
1
|
+
"""
|
2
|
+
risk/log/config
|
3
|
+
~~~~~~~~~~~~~~~
|
4
|
+
"""
|
5
|
+
|
6
|
+
import logging
|
7
|
+
|
8
|
+
|
9
|
+
def in_jupyter():
|
10
|
+
"""Check if the code is running in a Jupyter notebook environment.
|
11
|
+
|
12
|
+
Returns:
|
13
|
+
bool: True if running in a Jupyter notebook or QtConsole, False otherwise.
|
14
|
+
"""
|
15
|
+
try:
|
16
|
+
shell = get_ipython().__class__.__name__
|
17
|
+
if shell == "ZMQInteractiveShell": # Jupyter Notebook or QtConsole
|
18
|
+
return True
|
19
|
+
elif shell == "TerminalInteractiveShell": # Terminal running IPython
|
20
|
+
return False
|
21
|
+
except NameError:
|
22
|
+
return False # Not in Jupyter
|
23
|
+
|
24
|
+
|
25
|
+
# Define the MockLogger class to replicate logging behavior with print statements in Jupyter
|
26
|
+
class MockLogger:
|
27
|
+
"""MockLogger: A lightweight logger replacement using print statements in Jupyter.
|
28
|
+
|
29
|
+
The MockLogger class replicates the behavior of a standard logger using print statements
|
30
|
+
to display messages. This is primarily used in a Jupyter environment to show outputs
|
31
|
+
directly in the notebook. The class supports logging levels such as `info`, `debug`,
|
32
|
+
`warning`, and `error`, while the `verbose` attribute controls whether to display non-error messages.
|
33
|
+
"""
|
34
|
+
|
35
|
+
def __init__(self, verbose: bool = True):
|
36
|
+
"""Initialize the MockLogger with verbosity settings.
|
37
|
+
|
38
|
+
Args:
|
39
|
+
verbose (bool): If True, display all log messages (info, debug, warning).
|
40
|
+
If False, only display error messages. Defaults to True.
|
41
|
+
"""
|
42
|
+
self.verbose = verbose
|
43
|
+
|
44
|
+
def info(self, message: str) -> None:
|
45
|
+
"""Display an informational message.
|
46
|
+
|
47
|
+
Args:
|
48
|
+
message (str): The informational message to be printed.
|
49
|
+
"""
|
50
|
+
if self.verbose:
|
51
|
+
print(message)
|
52
|
+
|
53
|
+
def debug(self, message: str) -> None:
|
54
|
+
"""Display a debug message.
|
55
|
+
|
56
|
+
Args:
|
57
|
+
message (str): The debug message to be printed.
|
58
|
+
"""
|
59
|
+
if self.verbose:
|
60
|
+
print(message)
|
61
|
+
|
62
|
+
def warning(self, message: str) -> None:
|
63
|
+
"""Display a warning message.
|
64
|
+
|
65
|
+
Args:
|
66
|
+
message (str): The warning message to be printed.
|
67
|
+
"""
|
68
|
+
print(message)
|
69
|
+
|
70
|
+
def error(self, message: str) -> None:
|
71
|
+
"""Display an error message.
|
72
|
+
|
73
|
+
Args:
|
74
|
+
message (str): The error message to be printed.
|
75
|
+
"""
|
76
|
+
print(message)
|
77
|
+
|
78
|
+
def setLevel(self, level: int) -> None:
|
79
|
+
"""Adjust verbosity based on the logging level.
|
80
|
+
|
81
|
+
Args:
|
82
|
+
level (int): Logging level to control message display.
|
83
|
+
- logging.DEBUG sets verbose to True (show all messages).
|
84
|
+
- logging.WARNING sets verbose to False (show only warning, error, and critical messages).
|
85
|
+
"""
|
86
|
+
if level == logging.DEBUG:
|
87
|
+
self.verbose = True # Show all messages
|
88
|
+
elif level == logging.WARNING:
|
89
|
+
self.verbose = False # Suppress all except warning, error, and critical messages
|
90
|
+
|
91
|
+
|
92
|
+
# Set up logger based on environment
|
93
|
+
if not in_jupyter():
|
94
|
+
# Set up logger normally for .py files or terminal environments
|
95
|
+
logger = logging.getLogger("risk_logger")
|
96
|
+
logger.setLevel(logging.DEBUG)
|
97
|
+
console_handler = logging.StreamHandler()
|
98
|
+
console_handler.setLevel(logging.DEBUG)
|
99
|
+
console_handler.setFormatter(logging.Formatter("%(message)s"))
|
100
|
+
|
101
|
+
if not logger.hasHandlers():
|
102
|
+
logger.addHandler(console_handler)
|
103
|
+
else:
|
104
|
+
# If in Jupyter, use the MockLogger
|
105
|
+
logger = MockLogger()
|
106
|
+
|
107
|
+
|
108
|
+
def set_global_verbosity(verbose):
|
109
|
+
"""Set the global verbosity level for the logger.
|
110
|
+
|
111
|
+
Args:
|
112
|
+
verbose (bool): Whether to display all log messages (True) or only error messages (False).
|
113
|
+
|
114
|
+
Returns:
|
115
|
+
None
|
116
|
+
"""
|
117
|
+
if not isinstance(logger, MockLogger):
|
118
|
+
# For the regular logger, adjust logging levels
|
119
|
+
if verbose:
|
120
|
+
logger.setLevel(logging.DEBUG) # Show all messages
|
121
|
+
console_handler.setLevel(logging.DEBUG)
|
122
|
+
else:
|
123
|
+
logger.setLevel(logging.WARNING) # Show only warning, error, and critical messages
|
124
|
+
console_handler.setLevel(logging.WARNING)
|
125
|
+
else:
|
126
|
+
# For the MockLogger, set verbosity directly
|
127
|
+
logger.setLevel(logging.DEBUG if verbose else logging.WARNING)
|
128
|
+
|
129
|
+
|
130
|
+
def log_header(input_string: str) -> None:
|
131
|
+
"""Log the input string as a header with a line of dashes above and below it.
|
132
|
+
|
133
|
+
Args:
|
134
|
+
input_string (str): The string to be printed as a header.
|
135
|
+
"""
|
136
|
+
border = "-" * len(input_string)
|
137
|
+
logger.info(border)
|
138
|
+
logger.info(input_string)
|
139
|
+
logger.info(border)
|
@@ -46,7 +46,7 @@ def define_domains(
|
|
46
46
|
)
|
47
47
|
# Perform hierarchical clustering
|
48
48
|
Z = linkage(m, method=best_linkage, metric=best_metric)
|
49
|
-
logger.
|
49
|
+
logger.warning(
|
50
50
|
f"Linkage criterion: '{linkage_criterion}'\nLinkage method: '{best_linkage}'\nLinkage metric: '{best_metric}'"
|
51
51
|
)
|
52
52
|
logger.debug(f"Optimal linkage threshold: {round(best_threshold, 3)}")
|
@@ -10,10 +10,11 @@ import matplotlib.pyplot as plt
|
|
10
10
|
import networkx as nx
|
11
11
|
import numpy as np
|
12
12
|
import pandas as pd
|
13
|
+
from scipy import linalg
|
13
14
|
from scipy.ndimage import label
|
14
15
|
from scipy.stats import gaussian_kde
|
15
16
|
|
16
|
-
from risk.log import params
|
17
|
+
from risk.log import params, logger
|
17
18
|
from risk.network.graph import NetworkGraph
|
18
19
|
|
19
20
|
|
@@ -86,6 +87,83 @@ class NetworkPlotter:
|
|
86
87
|
|
87
88
|
return ax
|
88
89
|
|
90
|
+
def plot_title(
|
91
|
+
self,
|
92
|
+
title: Union[str, None] = None,
|
93
|
+
subtitle: Union[str, None] = None,
|
94
|
+
title_fontsize: int = 20,
|
95
|
+
subtitle_fontsize: int = 14,
|
96
|
+
font: str = "Arial",
|
97
|
+
title_color: str = "black",
|
98
|
+
subtitle_color: str = "gray",
|
99
|
+
title_y: float = 0.975,
|
100
|
+
title_space_offset: float = 0.075,
|
101
|
+
subtitle_offset: float = 0.025,
|
102
|
+
) -> None:
|
103
|
+
"""Plot title and subtitle on the network graph with customizable parameters.
|
104
|
+
|
105
|
+
Args:
|
106
|
+
title (str, optional): Title of the plot. Defaults to None.
|
107
|
+
subtitle (str, optional): Subtitle of the plot. Defaults to None.
|
108
|
+
title_fontsize (int, optional): Font size for the title. Defaults to 16.
|
109
|
+
subtitle_fontsize (int, optional): Font size for the subtitle. Defaults to 12.
|
110
|
+
font (str, optional): Font family used for both title and subtitle. Defaults to "Arial".
|
111
|
+
title_color (str, optional): Color of the title text. Defaults to "black".
|
112
|
+
subtitle_color (str, optional): Color of the subtitle text. Defaults to "gray".
|
113
|
+
title_y (float, optional): Y-axis position of the title. Defaults to 0.975.
|
114
|
+
title_space_offset (float, optional): Fraction of figure height to leave for the space above the plot. Defaults to 0.075.
|
115
|
+
subtitle_offset (float, optional): Offset factor to position the subtitle below the title. Defaults to 0.025.
|
116
|
+
"""
|
117
|
+
# Log the title and subtitle parameters
|
118
|
+
params.log_plotter(
|
119
|
+
title=title,
|
120
|
+
subtitle=subtitle,
|
121
|
+
title_fontsize=title_fontsize,
|
122
|
+
subtitle_fontsize=subtitle_fontsize,
|
123
|
+
title_subtitle_font=font,
|
124
|
+
title_color=title_color,
|
125
|
+
subtitle_color=subtitle_color,
|
126
|
+
subtitle_offset=subtitle_offset,
|
127
|
+
title_y=title_y,
|
128
|
+
title_space_offset=title_space_offset,
|
129
|
+
)
|
130
|
+
|
131
|
+
# Get the current figure and axis dimensions
|
132
|
+
fig = self.ax.figure
|
133
|
+
# Use a tight layout to ensure that title and subtitle do not overlap with the original plot
|
134
|
+
fig.tight_layout(
|
135
|
+
rect=[0, 0, 1, 1 - title_space_offset]
|
136
|
+
) # Leave space above the plot for title
|
137
|
+
|
138
|
+
# Plot title if provided
|
139
|
+
if title:
|
140
|
+
# Set the title using figure's suptitle to ensure centering
|
141
|
+
self.ax.figure.suptitle(
|
142
|
+
title,
|
143
|
+
fontsize=title_fontsize,
|
144
|
+
color=title_color,
|
145
|
+
fontname=font,
|
146
|
+
x=0.5, # Center the title horizontally
|
147
|
+
ha="center",
|
148
|
+
va="top",
|
149
|
+
y=title_y,
|
150
|
+
)
|
151
|
+
|
152
|
+
# Plot subtitle if provided
|
153
|
+
if subtitle:
|
154
|
+
# Calculate the subtitle's y position based on title's position and subtitle_offset
|
155
|
+
subtitle_y_position = title_y - subtitle_offset
|
156
|
+
self.ax.figure.text(
|
157
|
+
0.5, # Ensure horizontal centering for subtitle
|
158
|
+
subtitle_y_position,
|
159
|
+
subtitle,
|
160
|
+
ha="center",
|
161
|
+
va="top",
|
162
|
+
fontname=font,
|
163
|
+
fontsize=subtitle_fontsize,
|
164
|
+
color=subtitle_color,
|
165
|
+
)
|
166
|
+
|
89
167
|
def plot_circle_perimeter(
|
90
168
|
self,
|
91
169
|
scale: float = 1.0,
|
@@ -510,26 +588,52 @@ class NetworkPlotter:
|
|
510
588
|
# Extract the positions of the specified nodes
|
511
589
|
points = np.array([pos[n] for n in nodes])
|
512
590
|
if len(points) <= 1:
|
513
|
-
return # Not enough points to form a contour
|
591
|
+
return None # Not enough points to form a contour
|
514
592
|
|
593
|
+
# Check if the KDE forms a single connected component
|
515
594
|
connected = False
|
595
|
+
z = None # Initialize z to None to avoid UnboundLocalError
|
516
596
|
while not connected and bandwidth <= 100.0:
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
597
|
+
try:
|
598
|
+
# Perform KDE on the points with the given bandwidth
|
599
|
+
kde = gaussian_kde(points.T, bw_method=bandwidth)
|
600
|
+
xmin, ymin = points.min(axis=0) - bandwidth
|
601
|
+
xmax, ymax = points.max(axis=0) + bandwidth
|
602
|
+
x, y = np.mgrid[
|
603
|
+
xmin : xmax : complex(0, grid_size), ymin : ymax : complex(0, grid_size)
|
604
|
+
]
|
605
|
+
z = kde(np.vstack([x.ravel(), y.ravel()])).reshape(x.shape)
|
606
|
+
# Check if the KDE forms a single connected component
|
607
|
+
connected = _is_connected(z)
|
608
|
+
if not connected:
|
609
|
+
bandwidth += 0.05 # Increase bandwidth slightly and retry
|
610
|
+
except linalg.LinAlgError:
|
611
|
+
bandwidth += 0.05 # Increase bandwidth and retry
|
612
|
+
except Exception as e:
|
613
|
+
# Catch any other exceptions and log them
|
614
|
+
logger.error(f"Unexpected error when drawing KDE contour: {e}")
|
615
|
+
return None
|
616
|
+
|
617
|
+
# If z is still None, the KDE computation failed
|
618
|
+
if z is None:
|
619
|
+
logger.error("Failed to compute KDE. Skipping contour plot for these nodes.")
|
620
|
+
return None
|
529
621
|
|
530
622
|
# Define contour levels based on the density
|
531
623
|
min_density, max_density = z.min(), z.max()
|
624
|
+
if min_density == max_density:
|
625
|
+
logger.warning(
|
626
|
+
"Contour levels could not be created due to lack of variation in density."
|
627
|
+
)
|
628
|
+
return None
|
629
|
+
|
630
|
+
# Create contour levels based on the density values
|
532
631
|
contour_levels = np.linspace(min_density, max_density, levels)[1:]
|
632
|
+
if len(contour_levels) < 2 or not np.all(np.diff(contour_levels) > 0):
|
633
|
+
logger.error("Contour levels must be strictly increasing. Skipping contour plot.")
|
634
|
+
return None
|
635
|
+
|
636
|
+
# Set the contour color and linestyle
|
533
637
|
contour_colors = [color for _ in range(levels - 1)]
|
534
638
|
# Plot the filled contours using fill_alpha for transparency
|
535
639
|
if fill_alpha > 0:
|
@@ -554,6 +658,7 @@ class NetworkPlotter:
|
|
554
658
|
linewidths=linewidth,
|
555
659
|
alpha=alpha,
|
556
660
|
)
|
661
|
+
|
557
662
|
# Set linewidth for the contour lines to 0 for levels other than the base level
|
558
663
|
for i in range(1, len(contour_levels)):
|
559
664
|
c.collections[i].set_linewidth(0)
|
@@ -1090,14 +1195,16 @@ class NetworkPlotter:
|
|
1090
1195
|
return np.array(annotated_colors)
|
1091
1196
|
|
1092
1197
|
@staticmethod
|
1093
|
-
def savefig(*args, **kwargs) -> None:
|
1094
|
-
"""Save the current plot to a file.
|
1198
|
+
def savefig(*args, pad_inches: float = 0.5, dpi: int = 100, **kwargs) -> None:
|
1199
|
+
"""Save the current plot to a file with additional export options.
|
1095
1200
|
|
1096
1201
|
Args:
|
1097
1202
|
*args: Positional arguments passed to `plt.savefig`.
|
1203
|
+
pad_inches (float, optional): Padding around the figure when saving. Defaults to 0.5.
|
1204
|
+
dpi (int, optional): Dots per inch (DPI) for the exported image. Defaults to 300.
|
1098
1205
|
**kwargs: Keyword arguments passed to `plt.savefig`, such as filename and format.
|
1099
1206
|
"""
|
1100
|
-
plt.savefig(*args, bbox_inches="tight", **kwargs)
|
1207
|
+
plt.savefig(*args, bbox_inches="tight", pad_inches=pad_inches, dpi=dpi, **kwargs)
|
1101
1208
|
|
1102
1209
|
@staticmethod
|
1103
1210
|
def show(*args, **kwargs) -> None:
|
@@ -33,24 +33,17 @@ class RISK(NetworkIO, AnnotationsIO):
|
|
33
33
|
and performing network-based statistical analysis, such as neighborhood significance testing.
|
34
34
|
"""
|
35
35
|
|
36
|
-
def __init__(self,
|
36
|
+
def __init__(self, verbose: bool = True):
|
37
37
|
"""Initialize the RISK class with configuration settings.
|
38
38
|
|
39
39
|
Args:
|
40
40
|
verbose (bool): If False, suppresses all log messages to the console. Defaults to True.
|
41
|
-
*args: Variable length argument list.
|
42
|
-
**kwargs: Arbitrary keyword arguments.
|
43
|
-
|
44
|
-
Note:
|
45
|
-
- All *args and **kwargs are passed to NetworkIO's __init__ method.
|
46
|
-
- AnnotationsIO does not take any arguments and is initialized without them.
|
47
41
|
"""
|
48
42
|
# Set global verbosity for logging
|
49
43
|
set_global_verbosity(verbose)
|
50
44
|
# Initialize and log network parameters
|
51
45
|
params.initialize()
|
52
|
-
|
53
|
-
super().__init__(*args, **kwargs)
|
46
|
+
super().__init__()
|
54
47
|
|
55
48
|
@property
|
56
49
|
def params(self) -> params:
|
@@ -1,49 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
risk/log/config
|
3
|
-
~~~~~~~~~~~~~~~
|
4
|
-
"""
|
5
|
-
|
6
|
-
import logging
|
7
|
-
|
8
|
-
# Create a global logger
|
9
|
-
logger = logging.getLogger("risk_logger")
|
10
|
-
logger.setLevel(logging.DEBUG) # Start with the highest level; adjust as needed
|
11
|
-
# Create a console handler
|
12
|
-
console_handler = logging.StreamHandler()
|
13
|
-
console_handler.setLevel(logging.DEBUG) # Set the handler level (can be controlled later)
|
14
|
-
# Create a formatter and set it for the handler
|
15
|
-
formatter = logging.Formatter("%(message)s")
|
16
|
-
console_handler.setFormatter(formatter)
|
17
|
-
|
18
|
-
# Add the handler to the logger if it doesn't already exist
|
19
|
-
if not logger.hasHandlers():
|
20
|
-
logger.addHandler(console_handler)
|
21
|
-
|
22
|
-
|
23
|
-
def set_global_verbosity(verbose):
|
24
|
-
"""Set the global verbosity level for the logger.
|
25
|
-
|
26
|
-
Args:
|
27
|
-
verbose (bool): Whether to display all log messages (True) or only error messages (False).
|
28
|
-
|
29
|
-
Returns:
|
30
|
-
None
|
31
|
-
"""
|
32
|
-
if verbose:
|
33
|
-
logger.setLevel(logging.DEBUG) # Show all messages
|
34
|
-
console_handler.setLevel(logging.DEBUG)
|
35
|
-
else:
|
36
|
-
logger.setLevel(logging.ERROR) # Show only error messages
|
37
|
-
console_handler.setLevel(logging.ERROR)
|
38
|
-
|
39
|
-
|
40
|
-
def log_header(input_string: str) -> None:
|
41
|
-
"""Log the input string as a header with a line of dashes above and below it.
|
42
|
-
|
43
|
-
Args:
|
44
|
-
input_string (str): The string to be printed as a header.
|
45
|
-
"""
|
46
|
-
border = "-" * len(input_string)
|
47
|
-
logger.info(border)
|
48
|
-
logger.info(input_string)
|
49
|
-
logger.info(border)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|