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

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 

10 

11 

12def draw_degree_distr(net, mode=None, cumulative=0, survival=1, log_log=0): 

13 if not net.directed: 

14 mode = 'all' 

15 

16 fig, ax = create_default_figure(10, 8) 

17 ax.set_title('Degree distribution', color='white') 

18 

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) 

26 

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') 

31 

32 ax.legend(handles=[degree], fontsize=16) 

33 

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] 

44 

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') 

53 

54 ax.legend(handles=[degree, outdegree, indegree], fontsize=16) 

55 

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)) 

59 

60 if ax is None: 

61 fig, ax = create_default_figure(12,10) 

62 

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) 

69 

70 

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 

76 

77 

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) 

82 

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]) 

86 

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) 

95 

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 

101 

102 if nodesize is None: 

103 nodesize = np.sqrt(net.scaled_outdeg) * 500 + 50 

104 

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) 

108 

109 text = 'eigenvector ' + str(i + 1) + ' lambda ' + str(np.round(eigvals[i], 3)) 

110 ax.set_title(text) 

111 

112 ncolors = get_vector_coloring(vec) 

113 options = { 

114 'node_color': ncolors, 

115 'node_size': nodesize, 

116 'cmap': mpl.colormaps[cmap] 

117 } 

118 

119 nodes = nx.draw_networkx_nodes(net.graph, pos, ax=ax, **options) 

120 

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) 

125 

126 cmappable = ScalarMappable(color_normalize(0, 1), cmap=cmap) 

127 fig.colorbar(cmappable, ax=ax) 

128 ax.set_axis_off() 

129 

130 plt.tight_layout() 

131 plt.show() 

132 

133 

134def draw_net(net, colors=None, nodesize=None, ax=None): 

135 if ax is None: 

136 fig, ax = plt.subplots(figsize=(16, 12)) 

137 

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 

144 

145 if nodesize is None: 

146 nodesize = np.sqrt(net.scaled_outdeg) * 100 + 10 

147 

148 node_options = { 

149 'node_size': nodesize, 

150 'cmap': cm.get_cmap('Spectral'), 

151 } 

152 edge_options = {} 

153 

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) 

156 

157 plt.show() 

158 

159 

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) 

167 

168 if ax is None: 

169 fig, ax = plt.subplots(figsize=(10, 10)) 

170 

171 if not dtype is None: 

172 ax.matshow(mat.astype(dtype).A) 

173 else: 

174 ax.matshow(mat.A) 

175 

176 

177def plot_lem_embedding(net, ndim, colors=None): 

178 

179 if net.lem_emb is None: 

180 net.construct_lem_embedding(ndim) 

181 

182 if colors is None: 

183 colors = np.zeros(net.lem_emb.shape[1]) 

184 colors = range(net.lem_emb.shape[1]) 

185 

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) 

192 

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) 

199 

200 legend = ax.legend(*scatter.legend_elements(), 

201 loc="upper left", title="Classes") 

202 

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)