Coverage for src/driada/network/drawing.py: 12.03%
133 statements
« prev ^ index » next coverage.py v7.9.2, created at 2025-07-25 15:40 +0300
« prev ^ index » next coverage.py v7.9.2, created at 2025-07-25 15:40 +0300
1from ..utils.plot import *
2from .matrix_utils import *
3import numpy as np
4import networkx as nx
5from itertools import combinations
6from matplotlib import cm
7import matplotlib as mpl
8from matplotlib.cm import ScalarMappable
9from matplotlib.colors import Normalize as color_normalize
12def draw_degree_distr(net, mode=None, cumulative=0, survival=1, log_log=0):
13 if not net.directed:
14 mode = 'all'
16 fig, ax = create_default_figure(10, 8)
17 ax.set_title('Degree distribution', color='white')
19 if mode is not None:
20 distr = net.get_degree_distr(mode=mode)
21 if cumulative:
22 if survival:
23 distr = 1 - np.cumsum(distr)
24 else:
25 distr = np.cumsum(distr)
27 if log_log:
28 degree, = ax.loglog(distr[:-1], linewidth=2, c='k', label='degree')
29 else:
30 degree, = ax.plot(distr, linewidth=2, c='k', label='degree')
32 ax.legend(handles=[degree], fontsize=16)
34 else:
35 distr = net.get_degree_distr(mode='all')
36 outdistr = net.get_degree_distr(mode='out')
37 indistr = net.get_degree_distr(mode='in')
38 distrlist = [distr, outdistr, indistr]
39 if cumulative:
40 if survival:
41 distrlist = [1 - np.cumsum(d) for d in distrlist]
42 else:
43 distrlist = [np.cumsum(d) for d in distrlist]
45 if log_log:
46 degree, = ax.loglog(distrlist[0][:-1], linewidth=2, c='k', label='degree')
47 outdegree, = ax.loglog(distrlist[1][:-1], linewidth=2, c='b', label='outdegree')
48 indegree, = ax.loglog(distrlist[2][:-1], linewidth=2, c='r', label='indegree')
49 else:
50 degree, = ax.plot(distrlist[0], linewidth=2, c='k', label='degree')
51 outdegree, = ax.plot(distrlist[1], linewidth=2, c='b', label='outdegree')
52 indegree, = ax.plot(distrlist[2], linewidth=2, c='r', label='indegree')
54 ax.legend(handles=[degree, outdegree, indegree], fontsize=16)
56def draw_spectrum(net, mode='adj', ax=None, colors=None, cmap='plasma', nbins=None):
57 spectrum = net.get_spectrum(mode)
58 data = np.array(sorted(list(set(spectrum)), key=np.abs))
60 if ax is None:
61 fig, ax = create_default_figure(12,10)
63 if net.directed:
64 ax.scatter(data.real, data.imag, cmap=cmap, c=colors)
65 else:
66 if nbins is None:
67 nbins = len(spectrum) / 10
68 ax.hist(data.real, bins=nbins)
71def get_vector_coloring(vec, cmap='plasma'):
72 cmap = plt.get_cmap(cmap)
73 vec = np.array(vec).ravel()
74 colors = cmap((vec-min(vec))/(max(vec)-min(vec)))
75 return colors
78def draw_eigenvectors(net, left_ind, right_ind, mode='adj', nodesize=None,
79 cmap='plasma', draw_edges=True, edge_options={}):
80 spectrum = net.get_spectrum(mode)
81 eigenvectors = net.get_eigenvectors(mode)
83 vecs = eigenvectors[:, left_ind: right_ind + 1]
84 # vecs = np.abs(net.eigenvectors[:, left_ind: right_ind+1])
85 eigvals = np.real(spectrum[left_ind: right_ind + 1])
87 npics = vecs.shape[1]
88 pics_in_a_row = int(np.ceil(np.sqrt(npics)))
89 pics_in_a_col = int(np.ceil(1.0 * npics / pics_in_a_row))
90 fig, axs = plt.subplots(nrows=pics_in_a_col, ncols=pics_in_a_row, figsize=(8 * pics_in_a_row, 8 * pics_in_a_col))
91 for ax in axs.ravel():
92 ax.set_axis_off()
93 plt.subplots_adjust(left=0.1, bottom=0.1, right=0.9, top=0.9,
94 hspace=0.2, wspace=0.1)
96 if net.pos is None:
97 pos = nx.layout.spring_layout(net.graph)
98 # pos = nx.drawing.layout.circular_layout(net.graph)
99 else:
100 pos = net.pos
102 if nodesize is None:
103 nodesize = np.sqrt(net.scaled_outdeg) * 500 + 50
105 for i in range(npics):
106 vec = vecs[:, i]
107 ax = fig.add_subplot(pics_in_a_col, pics_in_a_row, i + 1)
109 text = 'eigenvector ' + str(i + 1) + ' lambda ' + str(np.round(eigvals[i], 3))
110 ax.set_title(text)
112 ncolors = get_vector_coloring(vec)
113 options = {
114 'node_color': ncolors,
115 'node_size': nodesize,
116 'cmap': mpl.colormaps[cmap]
117 }
119 nodes = nx.draw_networkx_nodes(net.graph, pos, ax=ax, **options)
121 if draw_edges:
122 edges = nx.draw_networkx_edges(net.graph, pos, **edge_options)
123 # pc, = mpl.collections.PatchCollection(nodes, cmap = options['cmap'])
124 # pc.set_array(edge_colors)
126 cmappable = ScalarMappable(color_normalize(0, 1), cmap=cmap)
127 fig.colorbar(cmappable, ax=ax)
128 ax.set_axis_off()
130 plt.tight_layout()
131 plt.show()
134def draw_net(net, colors=None, nodesize=None, ax=None):
135 if ax is None:
136 fig, ax = plt.subplots(figsize=(16, 12))
138 if net.pos is None:
139 print('Node positions not found, auto layout was constructed')
140 pos = nx.layout.spring_layout(net.graph)
141 # pos = nx.drawing.layout.circular_layout(net.graph)
142 else:
143 pos = net.pos
145 if nodesize is None:
146 nodesize = np.sqrt(net.scaled_outdeg) * 100 + 10
148 node_options = {
149 'node_size': nodesize,
150 'cmap': cm.get_cmap('Spectral'),
151 }
152 edge_options = {}
154 nodes = nx.draw_networkx_nodes(net.graph, pos, node_color=colors, ax=ax, **node_options)
155 edges = nx.draw_networkx_edges(net.graph, pos, ax=ax, **edge_options)
157 plt.show()
160def show_mat(net, dtype=None, mode='adj', ax=None):
161 mat = getattr(net, mode)
162 if mat is None:
163 if mode in ['lap', 'lap_out']:
164 mat = get_laplacian(net.adj)
165 elif mode == 'nlap':
166 mat = get_norm_laplacian(net.adj)
168 if ax is None:
169 fig, ax = plt.subplots(figsize=(10, 10))
171 if not dtype is None:
172 ax.matshow(mat.astype(dtype).A)
173 else:
174 ax.matshow(mat.A)
177def plot_lem_embedding(net, ndim, colors=None):
179 if net.lem_emb is None:
180 net.construct_lem_embedding(ndim)
182 if colors is None:
183 colors = np.zeros(net.lem_emb.shape[1])
184 colors = range(net.lem_emb.shape[1])
186 psize = 10
187 data = net.lem_emb.A
188 pairs = list(combinations(np.arange(ndim), 2))
189 npics = len(pairs)
190 pics_in_a_row = np.ceil(np.sqrt(npics))
191 pics_in_a_col = np.ceil(1.0 * npics / pics_in_a_row)
193 fig = plt.figure(figsize=(20, 20))
194 fig.suptitle('Projections')
195 for i in range(len(pairs)):
196 ax = fig.add_subplot(pics_in_a_row, pics_in_a_col, i + 1)
197 i1, i2 = pairs[i]
198 scatter = ax.scatter(data[i1, :], data[i2, :], c=colors, s=psize)
200 legend = ax.legend(*scatter.legend_elements(),
201 loc="upper left", title="Classes")
203 ax.text(min(data[i1, :]), min(data[i2, :]), 'axes ' + str(i1 + 1) + ' vs.' + str(i2 + 1),
204 bbox={'facecolor': 'red', 'alpha': 0.5, 'pad': 10})
205 # ax.add_artist(legend)