def make_graph(r_path, nodes): """ Call shortest_path, which reads links_distance.txt and creates networkx graph object. Adds degrees for nodes with 0 connections, returns graph object. """ gg = shortest_path(r_path) # add degrees for nodes with 0 connections for i in range(nodes): if str(i) not in list(gg.nodes()): gg.add_node(str(i), weight=0) return gg
def make_graph(results_path, nodes): """ Call shortest_path, which reads links_distance.txt and creates networkx graph object. Adds degrees for nodes with 0 connections, returns graph object. """ G = shortest_path(results_path) # get nodes and degrees in dictionary node_and_degree = {} for node, val in G.degree(): node_and_degree[node] = val # add degrees for nodes with 0 connections for i in range(nodes): if str(i) not in node_and_degree: node_and_degree[str(i)] = 0 G.add_node(str(i), weight=0) return G
def plot_3d(data_name, center_node, n_hop, colormap): current_file_path = Path(__file__) results_path = str(current_file_path.parents[1]) + f'/results/{data_name}/' # open xyz text file and extract values xyz = open(results_path + 'xyz.txt', 'r') pos = {} for i, line in enumerate(xyz): a = line.split() pos[str(i)] = (float(a[0]), float(a[1]), float(a[2])) xyz.close() n_nodes = len(pos) # Create graph object based on links and distances txt files G = shortest_path(results_path) # get node degrees in sorted list node_and_degree = {} for node, val in G.degree(): node_and_degree[node] = val # add degrees for nodes with 0 connections for i in range(n_nodes): if str(i) not in node_and_degree: node_and_degree[str(i)] = 0 G.add_node(str(i), weight=0) x_center = pos[str(center_node)][0] y_center = pos[str(center_node)][1] z_center = pos[str(center_node)][2] frontier_list = [] local_n_list = [] local_n_list_reduced = [] ext_n_list = [] # Each frontier is a dictionary of local neighborhood for i in range(n_hop + 1): # includes 0-hop neighborhood frontier_list.append(nx.single_source_shortest_path(G, str(center_node), cutoff=i)) # get frontier keys, which are local neighborhood nodes local_n_list.append([str(x) for x in list(frontier_list[i].keys())]) local_n_size = len(local_n_list[-1]) # get list of external nodes for i in range(n_nodes): if str(i) not in local_n_list[-1]: ext_n_list.append(str(i)) # Create 'reduced' list, manually add 0, 1 hop neighbor nodes for i in range(0, 2): local_n_list_reduced.append(local_n_list[i]) # Remove lower level (-2 levels) hop nodes so each frontier only includes 'growth' for i in range(2, n_hop + 1): local_n_list_reduced.append([x for x in local_n_list[i] if x not in local_n_list[i - 2]]) # Plotting # Iterate over local nbrhood list to extract the xyz coordinates of each neighborhood node xi = [] yi = [] zi = [] for i in local_n_list[-1]: xi.append(pos[i][0]) yi.append(pos[i][1]) zi.append(pos[i][2]) # mode='markers+text' for labels nbr_nodes = go.Scatter3d(x=xi, y=yi, z=zi, mode='markers', marker=dict(color='red', size=1.7), text=local_n_list[-1], hoverinfo='text') nbr_nodes['showlegend'] = False # center node center = go.Scatter3d(x=[x_center], y=[y_center], z=[z_center], mode='markers', marker=dict(color='azure', size=4.5, line=dict(color='black', width=0.2)), text=str(center_node), hoverinfo='text', name=f'Center node') center['showlegend'] = False # Plot nodes external to local neighborhood xo = [] yo = [] zo = [] for i in ext_n_list: xo.append(pos[i][0]) yo.append(pos[i][1]) zo.append(pos[i][2]) ext_nodes = go.Scatter3d(x=xo, y=yo, z=zo, mode='markers', marker=dict(color='white', size=3, line=dict(color='blue', width=0.2)), text=ext_n_list, hoverinfo='text', name='External nodes') ext_nodes['showlegend'] = True # get link colors by hop path length link_colors = [] cmap = cm.get_cmap(colormap, n_hop) for i in range(cmap.N): rgb = cmap(i)[:3] link_colors.append(colors.rgb2hex(rgb)) link_colors.insert(0, '#000000') # insert color for 0-hop neighborhood # Plot local neighborhood edges # Iterate over list of edges to get the xyz, coordinates of connected nodes grow_edges = [] existing_links = [] for i, frontier in enumerate(local_n_list_reduced): x_grow = [] y_grow = [] z_grow = [] for j in G.edges(frontier): x = [pos[j[0]][0], pos[j[1]][0], None] y = [pos[j[0]][1], pos[j[1]][1], None] z = [pos[j[0]][2], pos[j[1]][2], None] if j[0] in frontier and j[1] in frontier and nx.shortest_path_length(G, str(center_node), j[0]) == i-1: x_grow += x y_grow += y z_grow += z existing_links.append([j[0], j[1]]) grow_edges.append(go.Scatter3d(x=x_grow, y=y_grow, z=z_grow, mode='lines', line=dict(color=link_colors[i], width=1.5), name=f'{i}-hop', hoverinfo='none')) # Plot edges not in local neighborhood x_ext = [] y_ext = [] z_ext = [] for j in G.edges([str(i) for i in range(n_nodes)]): x = [pos[j[0]][0], pos[j[1]][0], None] y = [pos[j[0]][1], pos[j[1]][1], None] z = [pos[j[0]][2], pos[j[1]][2], None] if [j[0], j[1]] not in existing_links and [j[1], j[0]] not in existing_links: x_ext += x y_ext += y z_ext += z ext_edges = go.Scatter3d(x=x_ext, y=y_ext, z=z_ext, mode='lines', line=dict(color='rgb(0, 0, 0)', width=0.4), hoverinfo='none', name='External links') # Plot earth u, v = np.mgrid[0:2*np.pi:30j, 0:np.pi:30j] X = 6371 * np.cos(u) * np.sin(v) Y = 6371 * np.sin(u) * np.sin(v) Z = 6371 * np.cos(v) cscale = [[0.0, "rgb(240, 240, 240)"], [0.111, "rgb(225, 225, 225)"], [0.222, "rgb(210, 210, 210)"], [0.333, "rgb(195, 195, 195)"], [0.444, "rgb(180, 180, 180)"], [0.555, "rgb(165, 165, 165)"], [0.666, "rgb(150, 150, 150)"], [0.777, "rgb(135, 135, 135)"], [0.888, "rgb(120, 120, 120)"], [1.0, "rgb(105, 105, 105)"]] contours = dict(x=dict(highlight=False), y=dict(highlight=False), z=dict(highlight=False)) sphere = go.Surface(x=X, y=Y, z=Z, colorscale=cscale, showscale=False, hoverinfo='none', contours=contours, reversescale=True) # Plot layout noaxis = dict(showbackground=False, showgrid=False, showticklabels=False, ticks='', title='', zeroline=False, showspikes=False) layout3d = dict(title=f'{data_name} network<br>' f'Node {center_node}: {local_n_size} nodes in local neighborhood', font=dict(family='Arial'), scene=dict(xaxis=noaxis, yaxis=noaxis, zaxis=noaxis)) data = [sphere, ext_nodes]#, ext_edges] #nbr_nodes, center, # data += grow_edges fig = dict(data=data, layout=layout3d) plotly.offline.plot(fig, filename=f'{results_path}/{data_name}_network.html')
def network(true_xyz, true_anchors, abs_xyz, abs_anchors, anchors, rmse, ln_size, results_path, hop_lim): anchors_str = [str(x) for x in anchors] n_nodes = true_xyz.shape[0] node_list = [str(i) for i in range(n_nodes)] # Create graph object based on links and distances txt files g = shortest_path(results_path) # get node degrees in sorted list node_and_degree = {node: val for node, val in g.degree()} # add degrees for nodes with 0 connections for i in range(n_nodes): if str(i) not in node_and_degree: node_and_degree[str(i)] = 0 g.add_node(str(i), weight=0) # Plotting # Iterate over local nbrhood list to extract the xyz coordinates of each # neighborhood node xa = [] ya = [] za = [] for i in true_anchors: xa.append(i[0]) ya.append(i[1]) za.append(i[2]) t_anchors = go.Scatter3d(x=xa, y=ya, z=za, mode='markers', marker=dict(color='dodgerblue', size=4, line=dict(color='black', width=0.2)), hoverinfo='text', name='True anchors', text=anchors_str) t_anchors['showlegend'] = True xr = [] yr = [] zr = [] for i in abs_anchors: xr.append(i[0]) yr.append(i[1]) zr.append(i[2]) m_anchors = go.Scatter3d(x=xr, y=yr, z=zr, mode='markers', marker=dict(color='salmon', size=4, line=dict(color='black', width=0.2)), hoverinfo='text', name='Mapped anchors', text=anchors_str) m_anchors['showlegend'] = True xo = [] yo = [] zo = [] for i in true_xyz: xo.append(i[0]) yo.append(i[1]) zo.append(i[2]) true_nodes = go.Scatter3d(x=xo, y=yo, z=zo, mode='markers', marker=dict(color='white', size=4, line=dict(color='darkblue', width=0.2)), text=node_list, hoverinfo='text', name='True nodes') true_nodes['showlegend'] = True # xo = [] # yo = [] # zo = [] # for i in abs_xyz: # xo.append(i[0]) # yo.append(i[1]) # zo.append(i[2]) # m_nodes = go.Scatter3d(x=xo, y=yo, z=zo, mode='markers', # marker=dict(color='white', size=4, # line=dict(color='red', width=0.2)), # text=node_list, hoverinfo='text', # name='Mapped nodes') # m_nodes['showlegend'] = True x_stem = [] y_stem = [] z_stem = [] for j in range(n_nodes): x = [true_xyz[j][0], abs_xyz[j][0], None] y = [true_xyz[j][1], abs_xyz[j][1], None] z = [true_xyz[j][2], abs_xyz[j][2], None] x_stem += x y_stem += y z_stem += z stems = go.Scatter3d(x=x_stem, y=y_stem, z=z_stem, mode='lines', line=dict(color='red', width=0.75), hoverinfo='none', name='Error') # # Plot edges x_ext = [] y_ext = [] z_ext = [] for j in g.edges([str(i) for i in range(n_nodes)]): x = [true_xyz[int(j[0])][0], true_xyz[int(j[1])][0], None] y = [true_xyz[int(j[0])][1], true_xyz[int(j[1])][1], None] z = [true_xyz[int(j[0])][2], true_xyz[int(j[1])][2], None] x_ext += x y_ext += y z_ext += z edges = go.Scatter3d(x=x_ext, y=y_ext, z=z_ext, mode='lines', line=dict(color='rgb(0, 0, 0)', width=0.4), hoverinfo='none', name='Links') # Plot earth u, v = np.mgrid[0:2 * np.pi:30j, 0:np.pi:30j] xx = 6371 * np.cos(u) * np.sin(v) yy = 6371 * np.sin(u) * np.sin(v) zz = 6371 * np.cos(v) cscale = [[0.0, "rgb(240, 240, 240)"], [0.111, "rgb(225, 225, 225)"], [0.222, "rgb(210, 210, 210)"], [0.333, "rgb(195, 195, 195)"], [0.444, "rgb(180, 180, 180)"], [0.555, "rgb(165, 165, 165)"], [0.666, "rgb(150, 150, 150)"], [0.777, "rgb(135, 135, 135)"], [0.888, "rgb(120, 120, 120)"], [1.0, "rgb(105, 105, 105)"]] contours = dict(x=dict(highlight=False), y=dict(highlight=False), z=dict(highlight=False)) sphere = go.Surface(x=xx, y=yy, z=zz, colorscale=cscale, showscale=False, hoverinfo='none', contours=contours, reversescale=True, name='Surface') sphere['showlegend'] = True # Plot layout noaxis = dict(showbackground=False, showticklabels=False, title='', showspikes=False) layout3d = dict(font=dict(family='Arial'), scene=dict(xaxis=noaxis, yaxis=noaxis, zaxis=noaxis)) data = [sphere, stems, true_nodes, t_anchors] fig = go.Figure(data=data, layout=layout3d) t_ = f'True and Mapped Positions<br>RMSE: {rmse:.2f} km<br>Anchors ' \ f'nodes: [{anchors[0]} - {anchors[1]} - {anchors[2]} - ' \ f'{anchors[3]}]<br> Average ln size: {ln_size:.2f} nodes' fig.update_layout(title_text=t_, title_font_size=20, title_x=0.5) plotly.offline.plot( fig, filename=f'{results_path}/{hop_lim}hop_map-p-refine.html')
def stats(data_name, n_sat, show_plots, save_figs): current_file_path = Path(__file__) results_path = str(current_file_path.parents[1]) + f'/results/{data_name}/' G = shortest_path(results_path) node_list = [int(x) for x in list(G.nodes)] avg_local_n_size_list = [-3] ln_min = [] ln_max = [] i = 1 while True: local_n_size_list = [] for j in node_list: # frontier is dictionary of local neighborhood frontier = nx.single_source_shortest_path(G, str(j), cutoff=i) # get frontier keys, which are local neighborhood nodes local_n = [int(x) for x in list(frontier.keys())] size_local_n = len(local_n) local_n_size_list.append(size_local_n) # calculate average size of local neighborhood (averaged over all nodes) avg_local_n_size = sum(local_n_size_list) / n_sat # Bar labels ln_min.append(min(local_n_size_list)) ln_max.append(max(local_n_size_list)) # when the network saturates, exit loop if avg_local_n_size == avg_local_n_size_list[-1]: break # otherwise, append avg to list else: if i == 1: avg_local_n_size_list[0] = avg_local_n_size else: avg_local_n_size_list.append(avg_local_n_size) i += 1 # avg_percent_list = [100*x/n_sat for x in avg_local_n_size_list] del ln_min[-1] del ln_max[-1] # Plotting plt.rcParams['axes.prop_cycle'] = plt.cycler(color=plt.cm.Set1.colors) plt.rcParams['font.sans-serif'] = 'Arial' # plt.rcParams.update({'font.size': 12}) fig, ax = plt.subplots() n_hops = np.arange(1, i) ax.plot(n_hops, avg_local_n_size_list, marker='.', linewidth=0.5, label='Mean') ax.set_xlabel('Local neighborhood hop limit [# of hops]') ax.set_ylabel('Local neighborhood size [# of nodes]') ax.set_title('Local Neighborhood Size vs Hop Limit' + '\n' + data_name) ax.set_xticks(n_hops) ax.grid(linestyle='--') ax.scatter(n_hops, ln_max, color='C1', marker=10, label='Max') ax.scatter(n_hops, ln_min, color='C2', marker=11, label='Min') for i in range(len(ln_min)): ax.text(n_hops[i] + .1, ln_min[i] - 15, str(ln_min[i]), verticalalignment='center') ax.text(n_hops[i] + .1, ln_max[i] + 10, str(ln_max[i]), verticalalignment='center') ax.text(n_hops[i] + .1, avg_local_n_size_list[i], str(round(avg_local_n_size_list[i], 1)), verticalalignment='center') ax.legend() ax.fill_between(n_hops, ln_min, ln_max, color='C3', alpha=0.1) ax.set_axisbelow(True) if save_figs: plt.savefig(f'{results_path}/path_length.svg') if show_plots: plt.show()
def plot_3d(data_name, center_node, n_hop, colormap): current_file_path = Path(__file__) results_path = str(current_file_path.parents[1]) + f'/results/{data_name}/' # open xy text file and extract values xy = open(results_path + 'xy.txt', 'r') pos = {} for i, line in enumerate(xy): a = line.split() pos[str(i)] = (float(a[0]), float(a[1])) xy.close() n_nodes = len(pos) # Create graph object based on links and distances txt files G = shortest_path(results_path) # get node degrees in sorted list node_and_degree = {} for node, val in G.degree(): node_and_degree[node] = val # add degrees for nodes with 0 connections for i in range(n_nodes): if str(i) not in node_and_degree: node_and_degree[str(i)] = 0 G.add_node(str(i), weight=0) x_center = pos[str(center_node)][0] y_center = pos[str(center_node)][1] frontier_list = [] local_n_list = [] local_n_list_reduced = [] # Each frontier is a dictionary of local neighborhood for i in range(n_hop + 1): # includes 0-hop neighborhood frontier_list.append( nx.single_source_shortest_path(G, str(center_node), cutoff=i)) # get frontier keys, which are local neighborhood nodes local_n_list.append([str(x) for x in list(frontier_list[i].keys())]) local_n_size = len(local_n_list[-1]) # Create 'reduced' list, manually add 0, 1 hop neighbor nodes for i in range(0, 2): local_n_list_reduced.append(local_n_list[i]) # Remove lower level (-2 levels) hop nodes so each frontier only includes 'growth' for i in range(2, n_hop + 1): local_n_list_reduced.append( [x for x in local_n_list[i] if x not in local_n_list[i - 2]]) # Plotting # Iterate over local nbrhood list to extract the xy coordinates of each neighborhood node xi = [] yi = [] zi = [] for i in local_n_list[-1]: xi.append(pos[i][0]) yi.append(pos[i][1]) # mode='markers+text' for labels nbr_nodes = go.Scatter(x=xi, y=yi, mode='markers', marker=dict(color='red', size=3), text=local_n_list[-1], hoverinfo='none', name='LN nodes') nbr_nodes['showlegend'] = True # center node center = go.Scatter(x=[x_center], y=[y_center], mode='markers', marker=dict(color='azure', size=6, line=dict(color='black', width=1)), text=str(center_node), hoverinfo='none', name=f'Center node') center['showlegend'] = False # Plot nodes external to local neighborhood xo = [] yo = [] all_nodes = [str(x) for x in list(range(n_nodes))] for i in all_nodes: xo.append(pos[i][0]) yo.append(pos[i][1]) ext_nodes = go.Scatter(x=xo, y=yo, mode='markers', marker=dict(color='black', size=2), text=all_nodes, hoverinfo='text', name='External nodes') ext_nodes['showlegend'] = True # get link colors by hop path length link_colors = [] cmap = cm.get_cmap(colormap, n_hop) for i in range(cmap.N): rgb = cmap(i)[:3] link_colors.append(colors.rgb2hex(rgb)) link_colors.insert(0, '#000000') # insert color for 0-hop neighborhood # Plot local neighborhood edges # Iterate over list of edges to get the xy, coordinates of connected nodes grow_edges = [] existing_links = [] for i, frontier in enumerate(local_n_list_reduced): x_grow = [] y_grow = [] for j in G.edges(frontier): x = [pos[j[0]][0], pos[j[1]][0], None] y = [pos[j[0]][1], pos[j[1]][1], None] if j[0] in frontier and j[ 1] in frontier and nx.shortest_path_length( G, str(center_node), j[0]) == i - 1: x_grow += x y_grow += y existing_links.append([j[0], j[1]]) grow_edges.append( go.Scatter(x=x_grow, y=y_grow, mode='lines', line=dict(color=link_colors[i], width=.7), name=f'{i}-hop', hoverinfo='none')) # Plot edges not in local neighborhood x_ext = [] y_ext = [] for j in G.edges([str(i) for i in range(n_nodes)]): x = [pos[j[0]][0], pos[j[1]][0], None] y = [pos[j[0]][1], pos[j[1]][1], None] # if [j[0], j[1]] not in existing_links and [j[1], j[0]] not in existing_links: x_ext += x y_ext += y ext_edges = go.Scatter(x=x_ext, y=y_ext, mode='lines', line=dict(color='rgb(0, 0, 0)', width=0.2), hoverinfo='none', name='External links') # Plot layout xaxis = dict(ticks='outside', title='', zeroline=False, showspikes=False, linecolor='grey') yaxis = dict( ticks='outside', title='', zeroline=False, showspikes=False, linecolor='grey', scaleanchor='x', scaleratio=1, ) layout = dict( title=f'{data_name} network<br>' f'Node {center_node}: {local_n_size} nodes in local neighborhood', font=dict(family='Arial'), plot_bgcolor='rgba(0, 0, 0, 0)', xaxis=xaxis, yaxis=yaxis) data = grow_edges # data = [] data.append(ext_edges) data.append(ext_nodes) data.append(nbr_nodes) data.append(center) fig = dict(data=data, layout=layout) plotly.offline.plot(fig, filename=f'{results_path}/{data_name}_network.html')
def plot_path(data_name, pair, n_hop, showLN): current_file_path = Path(__file__) results_path = str(current_file_path.parents[1]) + f'/results/{data_name}/' # open xyz text file and extract values xyz = open(results_path + 'xyz.txt', 'r') pos = {} for i, line in enumerate(xyz): a = line.split() pos[str(i)] = (float(a[0]), float(a[1]), float(a[2])) xyz.close() n_nodes = len(pos) # Create graph object based on links and distances txt files G = shortest_path(results_path) # add degrees for nodes with 0 connections for i in range(n_nodes): if str(i) not in list(G): G.add_node(str(i), weight=0) src = pair[0] dst = pair[1] flag = False hops_file = open(results_path + 'hops.txt', 'r') for line in hops_file: if line.split()[0] == str(src) and line.split()[1] == str(dst): split1 = line.split('[') split2 = split1[1].split(']') hop_path = split2[0].split(', ') flag = True break hops_file.close() if flag is False: print(f'Error! There is no path between node {src} and {dst}') return # Plotting # Iterate over path list to get xyz coordinates xi = [] yi = [] zi = [] for i in hop_path: xi.append(pos[i][0]) yi.append(pos[i][1]) zi.append(pos[i][2]) path_nodes = go.Scatter3d(x=xi, y=yi, z=zi, mode='markers', marker=dict(color='cyan', size=2), text=hop_path, hoverinfo='text', name='Path nodes', textfont=dict(color='red')) path_nodes['showlegend'] = True # src node x_src = pos[str(src)][0] y_src = pos[str(src)][1] z_src = pos[str(src)][2] src_trace = go.Scatter3d(x=[x_src], y=[y_src], z=[z_src], mode='markers', marker=dict(color='azure', size=5, line=dict(color='black', width=0.2)), text=str(src), hoverinfo='text', name='Source node') src_trace['showlegend'] = False # dst node x_dst = pos[str(dst)][0] y_dst = pos[str(dst)][1] z_dst = pos[str(dst)][2] dst_trace = go.Scatter3d(x=[x_dst], y=[y_dst], z=[z_dst], mode='markers', marker=dict(color='azure', size=5, line=dict(color='black', width=0.2)), text=str(dst), hoverinfo='text', name='Destination node') dst_trace['showlegend'] = False # Plot nodes external to path xo = [] yo = [] zo = [] node_list = list(range(n_nodes)) for i in node_list: xo.append(pos[str(i)][0]) yo.append(pos[str(i)][1]) zo.append(pos[str(i)][2]) ext_nodes = go.Scatter3d(x=xo, y=yo, z=zo, mode='markers', marker=dict(color='black', size=1.3), text=node_list, hoverinfo='text', name='External nodes') ext_nodes['showlegend'] = True # get link colors by hop path length path_colors = [] cmap = cm.get_cmap('plasma', len(hop_path)) for i in range(cmap.N): rgb = cmap(i)[:3] path_colors.append(colors.rgb2hex(rgb)) # Plot path edges # Iterate over list of edges to get the xyz, coordinates of connected nodes path_traces = [] path_links = [] for j in range(1, len(hop_path)): x = [pos[hop_path[j - 1]][0], pos[hop_path[j]][0], None] y = [pos[hop_path[j - 1]][1], pos[hop_path[j]][1], None] z = [pos[hop_path[j - 1]][2], pos[hop_path[j]][2], None] path_links.append([hop_path[j - 1], hop_path[j]]) path_traces.append( go.Scatter3d(x=x, y=y, z=z, mode='lines', line=dict(color=path_colors[j], width=4), name=f'Hop {j}', hoverinfo='none')) # Plot edges not in path x_ext = [] y_ext = [] z_ext = [] for j in G.edges([str(i) for i in range(n_nodes)]): x = [pos[j[0]][0], pos[j[1]][0], None] y = [pos[j[0]][1], pos[j[1]][1], None] z = [pos[j[0]][2], pos[j[1]][2], None] if [j[0], j[1]] not in path_links and [j[1], j[0]] not in path_links: x_ext += x y_ext += y z_ext += z ext_edges = go.Scatter3d(x=x_ext, y=y_ext, z=z_ext, mode='lines', line=dict(color='rgb(0, 0, 0)', width=0.4), hoverinfo='none', name='External links') # Plot earth u, v = np.mgrid[0:2 * np.pi:30j, 0:np.pi:30j] X = 6371 * np.cos(u) * np.sin(v) Y = 6371 * np.sin(u) * np.sin(v) Z = 6371 * np.cos(v) contours = dict(x=dict(highlight=False), y=dict(highlight=False), z=dict(highlight=False)) sphere = go.Surface(x=X, y=Y, z=Z, colorscale='Greys', showscale=False, hoverinfo='none', contours=contours, reversescale=True) # Plotting local neighborhood of destination node if showLN: frontier_list = [] local_n_list = [] local_n_list_reduced = [] # Each frontier is a dictionary of local neighborhood for i in range(n_hop + 1): # includes 0-hop neighborhood frontier_list.append( nx.single_source_shortest_path(G, str(dst), cutoff=i)) # get frontier keys, which are local neighborhood nodes local_n_list.append( [str(x) for x in list(frontier_list[i].keys())]) # Create 'reduced' list, manually add 0, 1 hop neighbor nodes for i in range(0, 2): local_n_list_reduced.append(local_n_list[i]) # Remove lower level (-2 levels) hop nodes so each frontier only includes 'growth' for i in range(2, n_hop + 1): local_n_list_reduced.append( [x for x in local_n_list[i] if x not in local_n_list[i - 2]]) # get link colors by hop link_colors = [] cmap = cm.get_cmap('GnBu', n_hop) for i in range(cmap.N): rgb = cmap(i)[:3] link_colors.append(colors.rgb2hex(rgb)) link_colors.insert(0, '#000000') # insert color for 0-hop neighborhood # Iterate over local nbrhood list to extract the xyz coordinates of each # neighborhood node xi = [] yi = [] zi = [] for i in local_n_list[-1]: xi.append(pos[i][0]) yi.append(pos[i][1]) zi.append(pos[i][2]) # mode='markers+text' for labels nbr_nodes = go.Scatter3d(x=xi, y=yi, z=zi, mode='markers', marker=dict(color='red', size=2), text=local_n_list[-1], hoverinfo='text', name='LN nodes') nbr_nodes['showlegend'] = True # Plot local neighborhood edges # Iterate over list of edges to get the xyz, coordinates of connected nodes grow_edges = [] for i, frontier in enumerate(local_n_list_reduced): x_grow = [] y_grow = [] z_grow = [] for j in G.edges(frontier): x = [pos[j[0]][0], pos[j[1]][0], None] y = [pos[j[0]][1], pos[j[1]][1], None] z = [pos[j[0]][2], pos[j[1]][2], None] if j[0] in frontier and j[ 1] in frontier and nx.shortest_path_length( G, str(dst), j[0]) == i - 1: x_grow += x y_grow += y z_grow += z grow_edges.append( go.Scatter3d(x=x_grow, y=y_grow, z=z_grow, mode='lines', line=dict(color=link_colors[i], width=1.5), name=f'{i}-hop', hoverinfo='none')) # Plot layout noaxis = dict(showbackground=False, showgrid=False, showticklabels=False, ticks='', title='', zeroline=False, showspikes=False) layout3d = dict(title=f'{data_name} network<br>' f'Path from node {src} - {dst}: {len(hop_path)-1} hops', font=dict(family='Arial'), scene=dict(xaxis=noaxis, yaxis=noaxis, zaxis=noaxis)) data = [ sphere, ext_nodes, path_nodes, nbr_nodes, src_trace, dst_trace, ext_edges ] if showLN: data += grow_edges data += path_traces fig = dict(data=data, layout=layout3d) plotly.offline.plot( fig, filename=f'{results_path}/{data_name}_{src}-{dst}_path.html')
def stats(data_name, n_sat, show_plots): current_file_path = Path(__file__) results_path = str(current_file_path.parents[1]) + f'/results/{data_name}/' hops_path = results_path + 'hops.txt' G = shortest_path(results_path) path_length = [] pairs = [] hops_file = open(hops_path, 'r') for line in hops_file: path_length.append(int(line.split()[2])) pairs.append(line.split()[0:2]) hops_file.close() test = 0 for pair in pairs: test += nx.shortest_path_length(G, pair[0], pair[1]) nx_avg_path_length = test / len(pairs) # Plotting plt.rcParams['axes.prop_cycle'] = plt.cycler(color=plt.cm.Paired.colors) plt.rcParams['font.sans-serif'] = 'Arial' # Path length distribution # fig, ax = plt.subplots() # histogram bins = np.arange(min(path_length), max(path_length) + 2) - 0.5 ax.hist(path_length, bins, color='C0', rwidth=0.7, edgecolor='black', linewidth=0.5, alpha=0.8) ax.set_ylabel('Number of connections') ax.grid(linestyle=':') ax.set_axisbelow(True) # gaussian fit ax2 = ax.twinx() ax2.set_ylabel('Probability distribution') ax2.yaxis.label.set_color('C9') x = np.arange(min(path_length), max(path_length) + .1, .1) (mu, sigma) = norm.fit(path_length) # scale = len(path_length) y = norm.pdf(x, mu, sigma) ax2.set_ylim(bottom=0, top=max(y) * 1.2) ax2.plot(x, y, 'C9--') s = r'$\mu = $' + f'{mu:.3f}' + '\n' + r'$\sigma = $' + f'{sigma:.3f}' s2 = 'NetworkX routing:' + '\n' + r'$\mu = $' + f'{nx_avg_path_length:.3f}' ax2.text(.95, .85, s, transform=ax.transAxes, va='baseline', ha='right', bbox=dict(facecolor='C0', alpha=0.7)) ax2.text(.95, .78, s2, transform=ax.transAxes, va='top', ha='right', bbox=dict(facecolor='C2', alpha=0.7)) ax2.tick_params(axis='y', labelcolor='C9') plt.xticks(range(min(path_length), max(path_length) + 1)) ax.set_xlabel('Number of hops') plt.title(f'Path length distribution: {data_name}') fig.tight_layout() # otherwise right y-label is clipped if show_plots: plt.show()
def plot_range(data_name, hop_limit, range_limit, show_plots): current_file_path = Path(__file__) results_path = str(current_file_path.parents[1]) + f'/results/{data_name}/' # Get satellite distances distance_table = {} distance_file = open(results_path + 'distance.txt', 'r') for i, line in enumerate(distance_file): distance_table[i] = [float(x) for x in line.split()] distance_file.close() n_nodes = len(distance_table) G = shortest_path(results_path) # get node degrees in sorted list node_and_degree = {} for node, val in G.degree(): node_and_degree[node] = val # add degrees for nodes with 0 connections for i in range(n_nodes): if str(i) not in node_and_degree: G.add_node(str(i), weight=0) # node_and_degree[str(i)] = 0 range_range = list(range(0, range_limit + 1, 200)) def percent_in_LN_range(node, hop_n): p_in_LN_range = [] in_range = [] for i in range_range: # get satellites within various ranges in_subrange = { j: dist for j, dist in enumerate(distance_table[node]) if dist <= i } # get local neighborhood nodes for n_hop limit frontier_list = nx.single_source_shortest_path(G, str(node), cutoff=hop_n) # get frontier keys, which are local neighborhood nodes frontier_keys = [int(x) for x in list(frontier_list.keys())] # get satellites that are in the LN AND within the range in_LN_subrange = [x for x in frontier_keys if x in in_subrange] p_in_LN_range.append(len(in_LN_subrange) / len(in_subrange) * 100) in_range.append(len(in_subrange)) return p_in_LN_range, in_range results = [] avg_results = [] pir = [] for h in range(hop_limit + 1): for node in range(n_nodes): rrr, pirrr = percent_in_LN_range(node, h) results.append(rrr) if h == 0: # only need to to in_range count once pir.append(pirrr) np_results = np.asarray(results) avg_results.append(np.mean(np_results, axis=0)) np_pir = np.asarray(pir) avg_np_pir = np.mean(np_pir, axis=0) # Plotting # plt.rcParams['axes.prop_cycle'] = plt.cycler(color=plt.cm.Set2.colors) plt.rcParams['font.sans-serif'] = 'Arial' fig, ax = plt.subplots() for i, curve in enumerate(avg_results): ax.plot(range_range, curve, linewidth=0.5, marker='.', label=f'{i}-hop local neighborhood') plt.xlabel('Range [km]') plt.ylabel('[Average %]') plt.title('Average percent nodes in LN and in range vs Range' + '\n' + data_name) ax.minorticks_on() ax.grid(which='major', linestyle='--') # ax.grid(which='minor', linestyle=':') ax.set_axisbelow(True) blank = [0] * len(range_range) ax.scatter(range_range, blank, c='r', marker=11, label='Average nodes in range') plt.legend() # axx = ax.twinx() # axx.set_ylabel('Average nodes in range') # axx.yaxis.label.set_color('red') # axx.tick_params(axis='y', labelcolor='red') # axx.scatter(range_range, avg_np_pir, marker='x', color='r') for i in range(len(range_range)): ax.text(range_range[i], blank[i] + 1, str(round(avg_np_pir[i], 1))) if show_plots: plt.show()