risk-network 0.0.8b7__py3-none-any.whl → 0.0.8b9__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.
@@ -0,0 +1,269 @@
1
+ """
2
+ risk/network/plot/network
3
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
4
+ """
5
+
6
+ from typing import Any, List, Tuple, Union
7
+
8
+ import networkx as nx
9
+ import numpy as np
10
+
11
+ from risk.log import params
12
+ from risk.network.graph import NetworkGraph
13
+ from risk.network.plot.utils import to_rgba
14
+
15
+
16
+ class Network:
17
+ """Class for plotting nodes and edges in a network graph."""
18
+
19
+ def __init__(self, graph: NetworkGraph, ax: Any = None) -> None:
20
+ """Initialize the NetworkPlotter class.
21
+
22
+ Args:
23
+ graph (NetworkGraph): The network data and attributes to be visualized.
24
+ ax (Any, optional): Axes object to plot the network graph. Defaults to None.
25
+ """
26
+ self.graph = graph
27
+ self.ax = ax
28
+
29
+ def plot_network(
30
+ self,
31
+ node_size: Union[int, np.ndarray] = 50,
32
+ node_shape: str = "o",
33
+ node_edgewidth: float = 1.0,
34
+ edge_width: float = 1.0,
35
+ node_color: Union[str, List, Tuple, np.ndarray] = "white",
36
+ node_edgecolor: Union[str, List, Tuple, np.ndarray] = "black",
37
+ edge_color: Union[str, List, Tuple, np.ndarray] = "black",
38
+ node_alpha: Union[float, None] = 1.0,
39
+ edge_alpha: Union[float, None] = 1.0,
40
+ ) -> None:
41
+ """Plot the network graph with customizable node colors, sizes, edge widths, and node edge widths.
42
+
43
+ Args:
44
+ node_size (int or np.ndarray, optional): Size of the nodes. Can be a single integer or an array of sizes. Defaults to 50.
45
+ node_shape (str, optional): Shape of the nodes. Defaults to "o".
46
+ node_edgewidth (float, optional): Width of the node edges. Defaults to 1.0.
47
+ edge_width (float, optional): Width of the edges. Defaults to 1.0.
48
+ node_color (str, list, tuple, or np.ndarray, optional): Color of the nodes. Can be a single color or an array of colors.
49
+ Defaults to "white".
50
+ node_edgecolor (str, list, tuple, or np.ndarray, optional): Color of the node edges. Defaults to "black".
51
+ edge_color (str, list, tuple, or np.ndarray, optional): Color of the edges. Defaults to "black".
52
+ node_alpha (float, None, optional): Alpha value (transparency) for the nodes. If provided, it overrides any existing alpha
53
+ values found in node_color. Defaults to 1.0. Annotated node_color alphas will override this value.
54
+ edge_alpha (float, None, optional): Alpha value (transparency) for the edges. If provided, it overrides any existing alpha
55
+ values found in edge_color. Defaults to 1.0.
56
+ """
57
+ # Log the plotting parameters
58
+ params.log_plotter(
59
+ network_node_size=(
60
+ "custom" if isinstance(node_size, np.ndarray) else node_size
61
+ ), # np.ndarray usually indicates custom sizes
62
+ network_node_shape=node_shape,
63
+ network_node_edgewidth=node_edgewidth,
64
+ network_edge_width=edge_width,
65
+ network_node_color=(
66
+ "custom" if isinstance(node_color, np.ndarray) else node_color
67
+ ), # np.ndarray usually indicates custom colors
68
+ network_node_edgecolor=node_edgecolor,
69
+ network_edge_color=edge_color,
70
+ network_node_alpha=node_alpha,
71
+ network_edge_alpha=edge_alpha,
72
+ )
73
+
74
+ # Convert colors to RGBA using the to_rgba helper function
75
+ # If node_colors was generated using get_annotated_node_colors, its alpha values will override node_alpha
76
+ node_color = to_rgba(
77
+ color=node_color, alpha=node_alpha, num_repeats=len(self.graph.network.nodes)
78
+ )
79
+ node_edgecolor = to_rgba(
80
+ color=node_edgecolor, alpha=1.0, num_repeats=len(self.graph.network.nodes)
81
+ )
82
+ edge_color = to_rgba(
83
+ color=edge_color, alpha=edge_alpha, num_repeats=len(self.graph.network.edges)
84
+ )
85
+
86
+ # Extract node coordinates from the network graph
87
+ node_coordinates = self.graph.node_coordinates
88
+
89
+ # Draw the nodes of the graph
90
+ nx.draw_networkx_nodes(
91
+ self.graph.network,
92
+ pos=node_coordinates,
93
+ node_size=node_size,
94
+ node_shape=node_shape,
95
+ node_color=node_color,
96
+ edgecolors=node_edgecolor,
97
+ linewidths=node_edgewidth,
98
+ ax=self.ax,
99
+ )
100
+ # Draw the edges of the graph
101
+ nx.draw_networkx_edges(
102
+ self.graph.network,
103
+ pos=node_coordinates,
104
+ width=edge_width,
105
+ edge_color=edge_color,
106
+ ax=self.ax,
107
+ )
108
+
109
+ def plot_subnetwork(
110
+ self,
111
+ nodes: Union[List, Tuple, np.ndarray],
112
+ node_size: Union[int, np.ndarray] = 50,
113
+ node_shape: str = "o",
114
+ node_edgewidth: float = 1.0,
115
+ edge_width: float = 1.0,
116
+ node_color: Union[str, List, Tuple, np.ndarray] = "white",
117
+ node_edgecolor: Union[str, List, Tuple, np.ndarray] = "black",
118
+ edge_color: Union[str, List, Tuple, np.ndarray] = "black",
119
+ node_alpha: Union[float, None] = None,
120
+ edge_alpha: Union[float, None] = None,
121
+ ) -> None:
122
+ """Plot a subnetwork of selected nodes with customizable node and edge attributes.
123
+
124
+ Args:
125
+ nodes (list, tuple, or np.ndarray): List of node labels to include in the subnetwork. Accepts nested lists.
126
+ node_size (int or np.ndarray, optional): Size of the nodes. Can be a single integer or an array of sizes. Defaults to 50.
127
+ node_shape (str, optional): Shape of the nodes. Defaults to "o".
128
+ node_edgewidth (float, optional): Width of the node edges. Defaults to 1.0.
129
+ edge_width (float, optional): Width of the edges. Defaults to 1.0.
130
+ node_color (str, list, tuple, or np.ndarray, optional): Color of the nodes. Defaults to "white".
131
+ node_edgecolor (str, list, tuple, or np.ndarray, optional): Color of the node edges. Defaults to "black".
132
+ edge_color (str, list, tuple, or np.ndarray, optional): Color of the edges. Defaults to "black".
133
+ node_alpha (float, None, optional): Transparency for the nodes. If provided, it overrides any existing alpha values
134
+ found in node_color. Defaults to 1.0.
135
+ edge_alpha (float, None, optional): Transparency for the edges. If provided, it overrides any existing alpha values
136
+ found in node_color. Defaults to 1.0.
137
+
138
+ Raises:
139
+ ValueError: If no valid nodes are found in the network graph.
140
+ """
141
+ # Flatten nested lists of nodes, if necessary
142
+ if any(isinstance(item, (list, tuple, np.ndarray)) for item in nodes):
143
+ nodes = [node for sublist in nodes for node in sublist]
144
+
145
+ # Filter to get node IDs and their coordinates
146
+ node_ids = [
147
+ self.graph.node_label_to_node_id_map.get(node)
148
+ for node in nodes
149
+ if node in self.graph.node_label_to_node_id_map
150
+ ]
151
+ if not node_ids:
152
+ raise ValueError("No nodes found in the network graph.")
153
+
154
+ # Check if node_color is a single color or a list of colors
155
+ if not isinstance(node_color, (str, tuple, np.ndarray)):
156
+ node_color = [
157
+ node_color[nodes.index(node)]
158
+ for node in nodes
159
+ if node in self.graph.node_label_to_node_id_map
160
+ ]
161
+
162
+ # Convert colors to RGBA using the to_rgba helper function
163
+ node_color = to_rgba(color=node_color, alpha=node_alpha, num_repeats=len(node_ids))
164
+ node_edgecolor = to_rgba(color=node_edgecolor, alpha=1.0, num_repeats=len(node_ids))
165
+ edge_color = to_rgba(
166
+ color=edge_color, alpha=edge_alpha, num_repeats=len(self.graph.network.edges)
167
+ )
168
+
169
+ # Get the coordinates of the filtered nodes
170
+ node_coordinates = {node_id: self.graph.node_coordinates[node_id] for node_id in node_ids}
171
+
172
+ # Draw the nodes in the subnetwork
173
+ nx.draw_networkx_nodes(
174
+ self.graph.network,
175
+ pos=node_coordinates,
176
+ nodelist=node_ids,
177
+ node_size=node_size,
178
+ node_shape=node_shape,
179
+ node_color=node_color,
180
+ edgecolors=node_edgecolor,
181
+ linewidths=node_edgewidth,
182
+ ax=self.ax,
183
+ )
184
+ # Draw the edges between the specified nodes in the subnetwork
185
+ subgraph = self.graph.network.subgraph(node_ids)
186
+ nx.draw_networkx_edges(
187
+ subgraph,
188
+ pos=node_coordinates,
189
+ width=edge_width,
190
+ edge_color=edge_color,
191
+ ax=self.ax,
192
+ )
193
+
194
+ def get_annotated_node_colors(
195
+ self,
196
+ cmap: str = "gist_rainbow",
197
+ color: Union[str, None] = None,
198
+ min_scale: float = 0.8,
199
+ max_scale: float = 1.0,
200
+ scale_factor: float = 1.0,
201
+ alpha: Union[float, None] = 1.0,
202
+ nonenriched_color: Union[str, List, Tuple, np.ndarray] = "white",
203
+ nonenriched_alpha: Union[float, None] = 1.0,
204
+ random_seed: int = 888,
205
+ ) -> np.ndarray:
206
+ """Adjust the colors of nodes in the network graph based on enrichment.
207
+
208
+ Args:
209
+ cmap (str, optional): Colormap to use for coloring the nodes. Defaults to "gist_rainbow".
210
+ color (str or None, optional): Color to use for the nodes. If None, the colormap will be used. Defaults to None.
211
+ min_scale (float, optional): Minimum scale for color intensity. Defaults to 0.8.
212
+ max_scale (float, optional): Maximum scale for color intensity. Defaults to 1.0.
213
+ scale_factor (float, optional): Factor for adjusting the color scaling intensity. Defaults to 1.0.
214
+ alpha (float, None, optional): Alpha value for enriched nodes. If provided, it overrides any existing alpha values
215
+ found in color. Defaults to 1.0.
216
+ nonenriched_color (str, list, tuple, or np.ndarray, optional): Color for non-enriched nodes. Defaults to "white".
217
+ nonenriched_alpha (float, None, optional): Alpha value for non-enriched nodes. If provided, it overrides any existing
218
+ alpha values found in nonenriched_color. Defaults to 1.0.
219
+ random_seed (int, optional): Seed for random number generation. Defaults to 888.
220
+
221
+ Returns:
222
+ np.ndarray: Array of RGBA colors adjusted for enrichment status.
223
+ """
224
+ # Get the initial domain colors for each node, which are returned as RGBA
225
+ network_colors = self.graph.get_domain_colors(
226
+ cmap=cmap,
227
+ color=color,
228
+ min_scale=min_scale,
229
+ max_scale=max_scale,
230
+ scale_factor=scale_factor,
231
+ random_seed=random_seed,
232
+ )
233
+ # Apply the alpha value for enriched nodes
234
+ network_colors[:, 3] = alpha # Apply the alpha value to the enriched nodes' A channel
235
+ # Convert the non-enriched color to RGBA using the to_rgba helper function
236
+ nonenriched_color = to_rgba(color=nonenriched_color, alpha=nonenriched_alpha)
237
+ # Adjust node colors: replace any fully black nodes (RGB == 0) with the non-enriched color and its alpha
238
+ adjusted_network_colors = np.where(
239
+ np.all(network_colors[:, :3] == 0, axis=1, keepdims=True), # Check RGB values only
240
+ np.array(nonenriched_color), # Apply the non-enriched color with alpha
241
+ network_colors, # Keep the original colors for enriched nodes
242
+ )
243
+ return adjusted_network_colors
244
+
245
+ def get_annotated_node_sizes(
246
+ self, enriched_size: int = 50, nonenriched_size: int = 25
247
+ ) -> np.ndarray:
248
+ """Adjust the sizes of nodes in the network graph based on whether they are enriched or not.
249
+
250
+ Args:
251
+ enriched_size (int): Size for enriched nodes. Defaults to 50.
252
+ nonenriched_size (int): Size for non-enriched nodes. Defaults to 25.
253
+
254
+ Returns:
255
+ np.ndarray: Array of node sizes, with enriched nodes larger than non-enriched ones.
256
+ """
257
+ # Merge all enriched nodes from the domain_id_to_node_ids_map dictionary
258
+ enriched_nodes = set()
259
+ for _, node_ids in self.graph.domain_id_to_node_ids_map.items():
260
+ enriched_nodes.update(node_ids)
261
+
262
+ # Initialize all node sizes to the non-enriched size
263
+ node_sizes = np.full(len(self.graph.network.nodes), nonenriched_size)
264
+ # Set the size for enriched nodes
265
+ for node in enriched_nodes:
266
+ if node in self.graph.network.nodes:
267
+ node_sizes[node] = enriched_size
268
+
269
+ return node_sizes
@@ -0,0 +1,134 @@
1
+ """
2
+ risk/network/plot/plotter
3
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
4
+ """
5
+
6
+ from typing import List, Tuple, Union
7
+
8
+ import matplotlib.pyplot as plt
9
+ import numpy as np
10
+
11
+ from risk.log import params
12
+ from risk.network.graph import NetworkGraph
13
+ from risk.network.plot.canvas import Canvas
14
+ from risk.network.plot.contour import Contour
15
+ from risk.network.plot.labels import Labels
16
+ from risk.network.plot.network import Network
17
+ from risk.network.plot.utils import calculate_bounding_box, to_rgba
18
+
19
+
20
+ class NetworkPlotter(Canvas, Network, Contour, Labels):
21
+ """A class for visualizing network graphs with customizable options.
22
+
23
+ The NetworkPlotter class uses a NetworkGraph object and provides methods to plot the network with
24
+ flexible node and edge properties. It also supports plotting labels, contours, drawing the network's
25
+ perimeter, and adjusting background colors.
26
+ """
27
+
28
+ def __init__(
29
+ self,
30
+ graph: NetworkGraph,
31
+ figsize: Tuple = (10, 10),
32
+ background_color: Union[str, List, Tuple, np.ndarray] = "white",
33
+ background_alpha: Union[float, None] = 1.0,
34
+ pad: float = 0.3,
35
+ ) -> None:
36
+ """Initialize the NetworkPlotter with a NetworkGraph object and plotting parameters.
37
+
38
+ Args:
39
+ graph (NetworkGraph): The network data and attributes to be visualized.
40
+ figsize (tuple, optional): Size of the figure in inches (width, height). Defaults to (10, 10).
41
+ background_color (str, list, tuple, np.ndarray, optional): Background color of the plot. Defaults to "white".
42
+ background_alpha (float, None, optional): Transparency level of the background color. If provided, it overrides
43
+ any existing alpha values found in background_color. Defaults to 1.0.
44
+ pad (float, optional): Padding value to adjust the axis limits. Defaults to 0.3.
45
+ """
46
+ self.graph = graph
47
+ # Initialize the plot with the specified parameters
48
+ self.ax = self._initialize_plot(
49
+ graph=graph,
50
+ figsize=figsize,
51
+ background_color=background_color,
52
+ background_alpha=background_alpha,
53
+ pad=pad,
54
+ )
55
+ super().__init__(graph=graph, ax=self.ax)
56
+
57
+ def _initialize_plot(
58
+ self,
59
+ graph: NetworkGraph,
60
+ figsize: Tuple,
61
+ background_color: Union[str, List, Tuple, np.ndarray],
62
+ background_alpha: Union[float, None],
63
+ pad: float,
64
+ ) -> plt.Axes:
65
+ """Set up the plot with figure size and background color.
66
+
67
+ Args:
68
+ graph (NetworkGraph): The network data and attributes to be visualized.
69
+ figsize (tuple): Size of the figure in inches (width, height).
70
+ background_color (str): Background color of the plot.
71
+ background_alpha (float, None, optional): Transparency level of the background color. If provided, it overrides any
72
+ existing alpha values found in background_color.
73
+ pad (float, optional): Padding value to adjust the axis limits.
74
+
75
+ Returns:
76
+ plt.Axes: The axis object for the plot.
77
+ """
78
+ # Log the plotter settings
79
+ params.log_plotter(
80
+ figsize=figsize,
81
+ background_color=background_color,
82
+ background_alpha=background_alpha,
83
+ pad=pad,
84
+ )
85
+
86
+ # Extract node coordinates from the network graph
87
+ node_coordinates = graph.node_coordinates
88
+ # Calculate the center and radius of the bounding box around the network
89
+ center, radius = calculate_bounding_box(node_coordinates)
90
+
91
+ # Create a new figure and axis for plotting
92
+ fig, ax = plt.subplots(figsize=figsize)
93
+ fig.tight_layout() # Adjust subplot parameters to give specified padding
94
+ # Set axis limits based on the calculated bounding box and radius
95
+ ax.set_xlim([center[0] - radius - pad, center[0] + radius + pad])
96
+ ax.set_ylim([center[1] - radius - pad, center[1] + radius + pad])
97
+ ax.set_aspect("equal") # Ensure the aspect ratio is equal
98
+
99
+ # Set the background color of the plot
100
+ # Convert color to RGBA using the to_rgba helper function
101
+ fig.patch.set_facecolor(to_rgba(color=background_color, alpha=background_alpha))
102
+ ax.invert_yaxis() # Invert the y-axis to match typical image coordinates
103
+ # Remove axis spines for a cleaner look
104
+ for spine in ax.spines.values():
105
+ spine.set_visible(False)
106
+
107
+ # Hide axis ticks and labels
108
+ ax.set_xticks([])
109
+ ax.set_yticks([])
110
+ ax.patch.set_visible(False) # Hide the axis background
111
+
112
+ return ax
113
+
114
+ @staticmethod
115
+ def savefig(*args, pad_inches: float = 0.5, dpi: int = 100, **kwargs) -> None:
116
+ """Save the current plot to a file with additional export options.
117
+
118
+ Args:
119
+ *args: Positional arguments passed to `plt.savefig`.
120
+ pad_inches (float, optional): Padding around the figure when saving. Defaults to 0.5.
121
+ dpi (int, optional): Dots per inch (DPI) for the exported image. Defaults to 300.
122
+ **kwargs: Keyword arguments passed to `plt.savefig`, such as filename and format.
123
+ """
124
+ plt.savefig(*args, bbox_inches="tight", pad_inches=pad_inches, dpi=dpi, **kwargs)
125
+
126
+ @staticmethod
127
+ def show(*args, **kwargs) -> None:
128
+ """Display the current plot.
129
+
130
+ Args:
131
+ *args: Positional arguments passed to `plt.show`.
132
+ **kwargs: Keyword arguments passed to `plt.show`.
133
+ """
134
+ plt.show(*args, **kwargs)
@@ -0,0 +1,153 @@
1
+ """
2
+ risk/network/plot/utils
3
+ ~~~~~~~~~~~~~~~~~~~~~~~
4
+ """
5
+
6
+ from typing import List, Tuple, Union
7
+
8
+ import matplotlib.colors as mcolors
9
+ import numpy as np
10
+
11
+ from risk.network.graph import NetworkGraph
12
+
13
+
14
+ def get_annotated_domain_colors(
15
+ graph: NetworkGraph,
16
+ cmap: str = "gist_rainbow",
17
+ color: Union[str, None] = None,
18
+ min_scale: float = 0.8,
19
+ max_scale: float = 1.0,
20
+ scale_factor: float = 1.0,
21
+ random_seed: int = 888,
22
+ ) -> np.ndarray:
23
+ """Get colors for the domains based on node annotations, or use a specified color.
24
+
25
+ Args:
26
+ graph (NetworkGraph): The network data and attributes to be visualized.
27
+ cmap (str, optional): Colormap to use for generating domain colors. Defaults to "gist_rainbow".
28
+ color (str or None, optional): Color to use for the domains. If None, the colormap will be used. Defaults to None.
29
+ min_scale (float, optional): Minimum scale for color intensity when generating domain colors.
30
+ Defaults to 0.8.
31
+ max_scale (float, optional): Maximum scale for color intensity when generating domain colors.
32
+ Defaults to 1.0.
33
+ scale_factor (float, optional): Factor for adjusting the contrast in the colors generated based on
34
+ enrichment. Higher values increase the contrast. Defaults to 1.0.
35
+ random_seed (int, optional): Seed for random number generation to ensure reproducibility. Defaults to 888.
36
+
37
+ Returns:
38
+ np.ndarray: Array of RGBA colors for each domain.
39
+ """
40
+ # Generate domain colors based on the enrichment data
41
+ node_colors = graph.get_domain_colors(
42
+ cmap=cmap,
43
+ color=color,
44
+ min_scale=min_scale,
45
+ max_scale=max_scale,
46
+ scale_factor=scale_factor,
47
+ random_seed=random_seed,
48
+ )
49
+ annotated_colors = []
50
+ for _, node_ids in graph.domain_id_to_node_ids_map.items():
51
+ if len(node_ids) > 1:
52
+ # For multi-node domains, choose the brightest color based on RGB sum
53
+ domain_colors = np.array([node_colors[node] for node in node_ids])
54
+ brightest_color = domain_colors[
55
+ np.argmax(domain_colors[:, :3].sum(axis=1)) # Sum the RGB values
56
+ ]
57
+ annotated_colors.append(brightest_color)
58
+ else:
59
+ # Single-node domains default to white (RGBA)
60
+ default_color = np.array([1.0, 1.0, 1.0, 1.0])
61
+ annotated_colors.append(default_color)
62
+
63
+ return np.array(annotated_colors)
64
+
65
+
66
+ def calculate_bounding_box(
67
+ node_coordinates: np.ndarray, radius_margin: float = 1.05
68
+ ) -> Tuple[np.ndarray, float]:
69
+ """Calculate the bounding box of the network based on node coordinates.
70
+
71
+ Args:
72
+ node_coordinates (np.ndarray): Array of node coordinates (x, y).
73
+ radius_margin (float, optional): Margin factor to apply to the bounding box radius. Defaults to 1.05.
74
+
75
+ Returns:
76
+ tuple: Center of the bounding box and the radius (adjusted by the radius margin).
77
+ """
78
+ # Find minimum and maximum x, y coordinates
79
+ x_min, y_min = np.min(node_coordinates, axis=0)
80
+ x_max, y_max = np.max(node_coordinates, axis=0)
81
+ # Calculate the center of the bounding box
82
+ center = np.array([(x_min + x_max) / 2, (y_min + y_max) / 2])
83
+ # Calculate the radius of the bounding box, adjusted by the margin
84
+ radius = max(x_max - x_min, y_max - y_min) / 2 * radius_margin
85
+ return center, radius
86
+
87
+
88
+ def to_rgba(
89
+ color: Union[str, List, Tuple, np.ndarray],
90
+ alpha: Union[float, None] = None,
91
+ num_repeats: Union[int, None] = None,
92
+ ) -> np.ndarray:
93
+ """Convert color(s) to RGBA format, applying alpha and repeating as needed.
94
+
95
+ Args:
96
+ color (Union[str, list, tuple, np.ndarray]): The color(s) to convert. Can be a string, list, tuple, or np.ndarray.
97
+ alpha (float, None, optional): Alpha value (transparency) to apply. If provided, it overrides any existing alpha values
98
+ found in color.
99
+ num_repeats (int, None, optional): If provided, the color(s) will be repeated this many times. Defaults to None.
100
+
101
+ Returns:
102
+ np.ndarray: Array of RGBA colors repeated `num_repeats` times, if applicable.
103
+ """
104
+
105
+ def convert_to_rgba(c: Union[str, List, Tuple, np.ndarray]) -> np.ndarray:
106
+ """Convert a single color to RGBA format, handling strings, hex, and RGB/RGBA lists."""
107
+ # Note: if no alpha is provided, the default alpha value is 1.0 by mcolors.to_rgba
108
+ if isinstance(c, str):
109
+ # Convert color names or hex values (e.g., 'red', '#FF5733') to RGBA
110
+ rgba = np.array(mcolors.to_rgba(c))
111
+ elif isinstance(c, (list, tuple, np.ndarray)) and len(c) in [3, 4]:
112
+ # Convert RGB (3) or RGBA (4) values to RGBA format
113
+ rgba = np.array(mcolors.to_rgba(c))
114
+ else:
115
+ raise ValueError(
116
+ f"Invalid color format: {c}. Must be a valid string or RGB/RGBA sequence."
117
+ )
118
+
119
+ if alpha is not None: # Override alpha if provided
120
+ rgba[3] = alpha
121
+ return rgba
122
+
123
+ # If color is a 2D array of RGBA values, convert it to a list of lists
124
+ if isinstance(color, np.ndarray) and color.ndim == 2 and color.shape[1] == 4:
125
+ color = [list(c) for c in color]
126
+
127
+ # Handle a single color (string or RGB/RGBA list/tuple)
128
+ if isinstance(color, (str, list, tuple)) and not any(
129
+ isinstance(c, (list, tuple, np.ndarray)) for c in color
130
+ ):
131
+ rgba_color = convert_to_rgba(color)
132
+ if num_repeats:
133
+ return np.tile(
134
+ rgba_color, (num_repeats, 1)
135
+ ) # Repeat the color if num_repeats is provided
136
+ return np.array([rgba_color]) # Return a single color wrapped in a numpy array
137
+
138
+ # Handle a list/array of colors
139
+ elif isinstance(color, (list, tuple, np.ndarray)):
140
+ rgba_colors = np.array(
141
+ [convert_to_rgba(c) for c in color]
142
+ ) # Convert each color in the list to RGBA
143
+ # Handle repetition if num_repeats is provided
144
+ if num_repeats:
145
+ repeated_colors = np.array(
146
+ [rgba_colors[i % len(rgba_colors)] for i in range(num_repeats)]
147
+ )
148
+ return repeated_colors
149
+
150
+ return rgba_colors
151
+
152
+ else:
153
+ raise ValueError("Color must be a valid RGB/RGBA or array of RGB/RGBA colors.")
risk/risk.py CHANGED
@@ -356,6 +356,7 @@ class RISK(NetworkIO, AnnotationsIO):
356
356
  figsize: Tuple = (10, 10),
357
357
  background_color: str = "white",
358
358
  background_alpha: Union[float, None] = 1.0,
359
+ pad: float = 0.3,
359
360
  ) -> NetworkPlotter:
360
361
  """Get a NetworkPlotter object for plotting.
361
362
 
@@ -365,16 +366,12 @@ class RISK(NetworkIO, AnnotationsIO):
365
366
  background_color (str, optional): Background color of the plot. Defaults to "white".
366
367
  background_alpha (float, None, optional): Transparency level of the background color. If provided, it overrides
367
368
  any existing alpha values found in background_color. Defaults to 1.0.
369
+ pad (float, optional): Padding value to adjust the axis limits. Defaults to 0.3.
368
370
 
369
371
  Returns:
370
372
  NetworkPlotter: A NetworkPlotter object configured with the given parameters.
371
373
  """
372
374
  log_header("Loading plotter")
373
- # Log the plotter settings
374
- params.log_plotter(
375
- figsize=figsize,
376
- background_color=background_color,
377
- )
378
375
 
379
376
  # Initialize and return a NetworkPlotter object
380
377
  return NetworkPlotter(
@@ -382,6 +379,7 @@ class RISK(NetworkIO, AnnotationsIO):
382
379
  figsize=figsize,
383
380
  background_color=background_color,
384
381
  background_alpha=background_alpha,
382
+ pad=pad,
385
383
  )
386
384
 
387
385
  def _load_neighborhoods(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: risk-network
3
- Version: 0.0.8b7
3
+ Version: 0.0.8b9
4
4
  Summary: A Python package for biological network analysis
5
5
  Author: Ira Horecka
6
6
  Author-email: Ira Horecka <ira89@icloud.com>
@@ -1,6 +1,6 @@
1
- risk/__init__.py,sha256=Ld6-5HUuOVDCaSGqPvt7caqDuDx8YQ6yDSV1MrTjnCQ,112
1
+ risk/__init__.py,sha256=ZdYPjV9cVMzz6tSQJbYp9MnzLO53YJLS50zbeWZ1SSI,112
2
2
  risk/constants.py,sha256=XInRaH78Slnw_sWgAsBFbUHkyA0h0jL0DKGuQNbOvjM,550
3
- risk/risk.py,sha256=uZH7GuADCAAkDIx-rPlS6O_is6tUU2Hg28P8xpR-d9g,21240
3
+ risk/risk.py,sha256=slJXca_a726_D7oXwe765HaKTv3ZrOvhttyrWdCGPkA,21231
4
4
  risk/annotations/__init__.py,sha256=vUpVvMRE5if01Ic8QY6M2Ae3EFGJHdugEe9PdEkAW4Y,138
5
5
  risk/annotations/annotations.py,sha256=ySc_N3nXnKx5RnOpFaEkM6zvTbswbrRcfFLzM0KdOck,11391
6
6
  risk/annotations/io.py,sha256=TTXVJQgUGAlKpnGBcx7Dow146IGyozA03nSbl3S7M5M,9475
@@ -15,7 +15,13 @@ risk/network/__init__.py,sha256=iEPeJdZfqp0toxtbElryB8jbz9_t_k4QQ3iDvKE8C_0,126
15
15
  risk/network/geometry.py,sha256=H1yGVVqgbfpzBzJwEheDLfvGLSA284jGQQTn612L4Vc,6759
16
16
  risk/network/graph.py,sha256=EwD4-1THC5YNdP6PY01Oe35k2QYYqtZpxWraPVH6wa4,16426
17
17
  risk/network/io.py,sha256=kY7HqmL3wa1NnqHu61_G8IpT21qpBijpAZ4ixmsseJA,22911
18
- risk/network/plot/base.py,sha256=8Wbrm2Es8cGYGGGOoJqzeUfuDlNlgJ4_6IEIIfMShN8,85611
18
+ risk/network/plot/__init__.py,sha256=MfmaXJgAZJgXZ2wrhK8pXwzETlcMaLChhWXKAozniAo,98
19
+ risk/network/plot/canvas.py,sha256=-Y2shCy4Udp-stB9tBXGZRTASQZiv8RVqVcQ5lBhVu0,10291
20
+ risk/network/plot/contour.py,sha256=YPG8Uz0VlJ4skLdGaTH_FmQN6A_ArK8XSTNo1LzkSws,14276
21
+ risk/network/plot/labels.py,sha256=o_V_eWQZB_otjXpw6aAwEPp1Uu-auQNcxQYpGBOL7uU,40777
22
+ risk/network/plot/network.py,sha256=83ZXjGGrgRprWvDldWfhRe6SFXTv_QoI20OWzyEmVJU,12593
23
+ risk/network/plot/plotter.py,sha256=rQV4Db6Ud86FJm11uaBvgSuzpmGsrZxnsRnUKjg6w84,5572
24
+ risk/network/plot/utils.py,sha256=jZgI8EysSjviQmdYAceZk2MwJXcdeFAkYp-odZNqV0k,6316
19
25
  risk/stats/__init__.py,sha256=WcgoETQ-hS0LQqKRsAMIPtP15xZ-4eul6VUBuUx4Wzc,220
20
26
  risk/stats/hypergeom.py,sha256=o6Qnj31gCAKxr2uQirXrbv7XvdDJGEq69MFW-ubx_hA,2272
21
27
  risk/stats/poisson.py,sha256=8x9hB4DCukq4gNIlIKO-c_jYG1-BTwTX53oLauFyfj8,1793
@@ -23,8 +29,8 @@ risk/stats/stats.py,sha256=kvShov-94W6ffgDUTb522vB9hDJQSyTsYif_UIaFfSM,7059
23
29
  risk/stats/permutation/__init__.py,sha256=neJp7FENC-zg_CGOXqv-iIvz1r5XUKI9Ruxhmq7kDOI,105
24
30
  risk/stats/permutation/permutation.py,sha256=D84Rcpt6iTQniK0PfQGcw9bLcHbMt9p-ARcurUnIXZQ,10095
25
31
  risk/stats/permutation/test_functions.py,sha256=lftOude6hee0pyR80HlBD32522JkDoN5hrKQ9VEbuoY,2345
26
- risk_network-0.0.8b7.dist-info/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
27
- risk_network-0.0.8b7.dist-info/METADATA,sha256=wOm-_aHavf5zpMp_UjqIBx2NPl4nR_2YtS1cfFn6UBA,47450
28
- risk_network-0.0.8b7.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
29
- risk_network-0.0.8b7.dist-info/top_level.txt,sha256=NX7C2PFKTvC1JhVKv14DFlFAIFnKc6Lpsu1ZfxvQwVw,5
30
- risk_network-0.0.8b7.dist-info/RECORD,,
32
+ risk_network-0.0.8b9.dist-info/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
33
+ risk_network-0.0.8b9.dist-info/METADATA,sha256=Sq_d-xGJT_RHwo6lxwl0s9ydoIeNTRW-1vrG1V-NknA,47450
34
+ risk_network-0.0.8b9.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
35
+ risk_network-0.0.8b9.dist-info/top_level.txt,sha256=NX7C2PFKTvC1JhVKv14DFlFAIFnKc6Lpsu1ZfxvQwVw,5
36
+ risk_network-0.0.8b9.dist-info/RECORD,,