def visualize( network, port=9853, verbose=False, config=None, plot_in_cell_below=True, is_test=False, ): """ Visualize a network interactively using Ulf Aslak's d3 web app. Saves the network as json, saves the passed config and runs a local HTTP server which then runs the web app. Parameters ---------- network : networkx.Graph or networkx.DiGraph or node-link dictionary The network to visualize port : int, default : 9853 The port at which to run the server locally. verbose : bool, default : False Be chatty. config : dict, default : None, In the default configuration, each key-value-pair will be overwritten with the key-value-pair provided in `config`. The default configuration is .. code:: python default_config = { # Input/output 'zoom': 1, # Physics 'node_charge': -45, 'node_gravity': 0.1, 'link_distance': 15, 'link_distance_variation': 0, 'node_collision': True, 'wiggle_nodes': False, 'freeze_nodes': False, # Nodes 'node_fill_color': '#79aaa0', 'node_stroke_color': '#555555', 'node_label_color': '#000000', 'display_node_labels': False, 'scale_node_size_by_strength': False, 'node_size': 5, 'node_stroke_width': 1, 'node_size_variation': 0.5, # Links 'link_color': '#7c7c7c', 'link_width': 2, 'link_alpha': 0.5, 'link_width_variation': 0.5, # Thresholding 'display_singleton_nodes': True, 'min_link_weight_percentile': 0, 'max_link_weight_percentile': 1 } When started from a Jupyter notebook, this will show a reproduced matplotlib figure of the stylized network in a cell below. Only works if ``verbose = False``. is_test : bool, default : False If ``True``, the interactive environment will post its visualization to Python automatically after 5 seconds. Returns ------- network_properties : dict contains all necessary information to redraw the figure which was created in the interactive visualization config : dict contains all configurational values of the interactive visualization """ this_config = deepcopy(default_config) if config is not None: this_config.update(config) path = netwulf_user_folder mkdirp_customdir() web_dir = pathlib.Path(path) # copy the html and js files for the visualizations prepare_visualization_directory() # create a json-file based on the current time file_id = "tmp_{:x}".format(int(time.time() * 1000)) + ".json" filename = file_id configname = "config_" + filename filepath = str(web_dir / filename) configpath = str(web_dir / configname) with open(filepath, 'w') as f: if type(network) in [nx.Graph, nx.DiGraph]: network = nx.node_link_data(network) if 'graph' in network: network.update(network['graph']) del network['graph'] json.dump(network, f, iterable_as_array=True, default=_json_default) with open(configpath, 'w') as f: json.dump(this_config, f, default=_json_default) # change directory to this directory if verbose: print("changing directory to", str(web_dir)) print("starting server here ...", str(web_dir)) cwd = os.getcwd() os.chdir(str(web_dir)) server = NetwulfHTTPServer( ("127.0.0.1", port), NetwulfHTTPRequestHandler, [filepath, configpath], verbose=verbose, ) # ========= start server ============ thread = threading.Thread(None, server.run) thread.start() url = "http://localhost:" + str( port) + "/?data=" + filename + "&config=" + configname if is_test: url += "&pytest" webbrowser.open(url) try: while not server.end_requested: time.sleep(0.1) is_keyboard_interrupted = False except KeyboardInterrupt: is_keyboard_interrupted = True server.end_requested = True if verbose: print('stopping server ...') server.stop_this() thread.join(0.2) posted_network_properties = server.posted_network_properties posted_config = server.posted_config if verbose: print('changing directory back to', cwd) os.chdir(cwd) # see whether or not the whole thing was started from a jupyter notebook and if yes, # actually re-draw the figure and display it env = os.environ try: is_jupyter = 'jupyter' in pathlib.PurePath(env['_']).name except: # this should actually be a key error # apparently this is how it has to be on Windows is_jupyter = 'JPY_PARENT_PID' in env if is_jupyter and plot_in_cell_below and not is_keyboard_interrupted: if verbose: print('recreating layout in matplotlib ...') fig, ax = wulf.draw_netwulf(posted_network_properties) return posted_network_properties, posted_config
B = 10 L = 3 N = B**L k = 12 mus = [-1, -.5, -.05, 1] for imu, mu in enumerate(mus): path = Path('data') / ('kleinberg_1d_imu_{}.json'.format(imu)) if not path.exists(): G = sixd.to_networkx_graph( *sixd.random_geometric_kleinberg_network(N, k, mu)) nw, cfg = wulf.visualize(G, config={ 'node_fill_color': '#efefef', 'node_collision': False, 'wiggle_nodes': False, 'scale_node_size_by_strength': True, 'node_size': 8, 'node_stroke_width': 2, 'node_stroke_color': '#000000', }) wulf.save(str(path), nw, cfg, G) else: nw, cfg, G = wulf.load(str(path)) plt.figure() fig, ax = wulf.draw_netwulf(nw) plt.show()
import matplotlib as matplotlib matplotlib.use("Agg", force=True) import networkx as nx import netwulf as wulf import matplotlib.pyplot as plt g = nx.read_graphml("g") stylized_network, config = wulf.visualize(g) fig, ax = wulf.draw_netwulf(stylized_network) plt.show()
def make_model_network(combined_analysis_output_dir, adj_mat_dir, drop_eqless=0.00, colour_by_motif=False, use_nearest_neighbour=False, use_adjacent_neighbour=False): if use_nearest_neighbour: output_name = "nearest_neighbour_vis.pdf" elif use_adjacent_neighbour: output_name = "adjacent_neighbour_vis.pdf" if use_nearest_neighbour and use_adjacent_neighbour: print("use only one of nearest or adjacent neighbour") exit() model_space_report_path = combined_analysis_output_dir + "combined_model_space_report_with_motifs.csv" adj_matrix_path_template = adj_mat_dir + "model_#REF#_adj_mat.csv" model_space_report_df = pd.read_csv(model_space_report_path) model_space_report_df = model_space_report_df.sort_values('model_idx') model_idxs = model_space_report_df['model_idx'].values model_marginals = model_space_report_df['model_marginal_mean'].values flat_adj_mats = [] # Load and flatten all adj mats for m_idx in model_idxs: model_self_limiting_count = 0 adj_mat_path = adj_matrix_path_template.replace("#REF#", str(m_idx)) adj_mat_df = pd.read_csv(adj_mat_path, index_col=0) flat_adj_mats.append(adj_mat_df.values.flatten()) model_connectivity = np.zeros(shape=(len(flat_adj_mats), len(flat_adj_mats))) for m_idx in model_idxs: if use_nearest_neighbour: neighbours = find_nearest_neighbours(flat_adj_mats[m_idx], flat_adj_mats) elif use_adjacent_neighbour: neighbours = find_adjacent_neighbours(flat_adj_mats[m_idx], flat_adj_mats) for n in neighbours: model_connectivity[m_idx, n] = 1 graph = nx.convert_matrix.from_numpy_matrix(model_connectivity) max_marginal = np.max(model_marginals) min_marginal = 0 scale_max = 50 scale_min = 10 node_sizes = [ min_max_scaling(scale_min, scale_max, min_marginal, max_marginal, x) for x in model_marginals ] if colour_by_motif: col_blue = '#1d71b8' # SL blue col_red = '#ac182b' # OL red col_grey = '#706f6f' # Mixed grey model_space_report_df = make_model_motif_colours(model_space_report_df, col_SL_only=col_blue, col_OL_only=col_red, col_mixed=col_grey) node_colours = model_space_report_df['node_type'].values else: node_colours = ['#73ba65' for _ in model_idxs] # #1d71b8 # #ac182b - OL red # #706f6f - grey for n, data in graph.nodes(data=True): data['size'] = node_sizes[n] data['color'] = node_colours[n] print(data) vis_config = two_species_vis_parameters() graph, config = netwulf.visualize(graph, config=vis_config, plot_in_cell_below=False, is_test=False) if colour_by_motif: output_name = output_name + "_col" output_name = output_name + ".pdf" output_path = combined_analysis_output_dir + output_name print("plotting network... ") fig, ax = netwulf.draw_netwulf(graph, figsize=15.0) fig.tight_layout() plt.savefig(output_path)
def main(): parser = OptionParser() parser.add_option( "-m", "--model", type="string", dest="ntype", help="Possible network types: 'ring', 'random', 'ws', 'ba'.") parser.add_option("-n", "--nodes", type="int", dest="N", help="Number of nodes in the network.") parser.add_option("-p", "--prob", type="float", dest="p", help="Probability used in generating models.") parser.add_option("--m0", type="int", dest="m0", help="Starting connected nodes for BA model.") parser.add_option("-a", "--advanced", action="store_true", dest="a", default=False, help="Add policymakers and journalists to the model.") parser.add_option( "-s", "--scilinks", type="float", dest="s", help="Percentage of the scientists connected with the other nodes.") (options, args) = parser.parse_args() default_config = { # Input/output 'zoom': 2, # Physics 'node_charge': -45, 'node_gravity': 0.1, 'link_distance': 15, 'link_distance_variation': 0, 'node_collision': True, 'wiggle_nodes': True, 'freeze_nodes': False, # Nodes 'node_fill_color': '#4e4fd4', 'node_stroke_color': '#555555', 'node_label_color': '#000000', 'display_node_labels': True, 'scale_node_size_by_strength': True, 'node_size': 8, 'node_stroke_width': 1.5, 'node_size_variation': 0.8, # Links 'link_color': '#7c7c7c', 'link_width': 2, 'link_alpha': 0.5, 'link_width_variation': 0.5, # Thresholding 'display_singleton_nodes': True, 'min_link_weight_percentile': 0, 'max_link_weight_percentile': 1 } if VERBOSE: print(options) # Sanity check working fine # sanity_check() # Default values p = 0.11 N = 20 m0 = 2 s = 0.25 if options.p: p = options.p if options.N: N = options.N if options.m0: m0 = options.m0 if options.s: s = options.s # Scientists only simulation if options.ntype and not options.a: if options.ntype == 'ring': # Ring Lattice nodes, G, config = generate_ring_lattice(N=N) _network, _ = visualize(G, config=default_config, plot_in_cell_below=False) fig, ax = draw_netwulf(_network) plt.savefig( f"results/{EXPERIMENT}_{options.ntype}_{N}_{p}_{m0}.png") filename = f"{EXPERIMENT}_{options.ntype}_{N}_{p}_{m0}_graph" run_simulation(filename, nodes) if options.ntype == 'random': # Random Network nodes, G, config = generate_random_network(N=N, p=p) _network, _ = visualize(G, config=default_config, plot_in_cell_below=False) fig, ax = draw_netwulf(_network) plt.savefig( f"results/{EXPERIMENT}_{options.ntype}_{N}_{p}_{m0}.png") filename = f"{EXPERIMENT}_{options.ntype}_{N}_{p}_{m0}_graph" run_simulation(filename, nodes) if options.ntype == 'ws': # Watts-Strogatz Network nodes, G, config = generate_watts_strogatz_network(N=N, p=p) _network, _ = visualize(G, config=default_config, plot_in_cell_below=False) fig, ax = draw_netwulf(_network) plt.savefig( f"results/{EXPERIMENT}_{options.ntype}_{N}_{p}_{m0}.png") filename = f"{EXPERIMENT}_{options.ntype}_{N}_{p}_{m0}_graph" run_simulation(filename, nodes) if options.ntype == 'ba': # Barabasi-Albert Network nodes, G, config = generate_barabasi_albert_network(N=N, m0=m0, m=m0) # visualize(G, config=default_config) _network, _ = visualize(G, config=default_config, plot_in_cell_below=False) # fig, ax = draw_netwulf(_network, figsize=(10, 10)) fig, ax = draw_netwulf(_network) # plt.show() plt.savefig( f"results/{EXPERIMENT}_{options.ntype}_{N}_{p}_{m0}.png") filename = f"{EXPERIMENT}_{options.ntype}_{N}_{p}_{m0}_graph" run_simulation(filename, nodes) ################################################### # Advanced simulation: Policymakers and Journalists if options.ntype and options.a: if options.ntype == 'ring': # Ring Lattice nodes, G, config = generate_ring_lattice(N=N) nodes, G = add_policymaker_journalist(nodes, G, s) _network, _ = visualize(G, config=default_config, plot_in_cell_below=False) fig, ax = draw_netwulf(_network) plt.savefig( f"results/{EXPERIMENT}_{options.ntype}_{N}_{p}_{m0}_{s}.png") filename = f"{EXPERIMENT}_{options.ntype}_{N}_{p}_{m0}_{s}_graph" run_simulation(filename, nodes, advanced=True) if options.ntype == 'random': # Random Network nodes, G, config = generate_random_network(N=N, p=p) nodes, G = add_policymaker_journalist(nodes, G, s) _network, _ = visualize(G, config=default_config, plot_in_cell_below=False) fig, ax = draw_netwulf(_network) plt.savefig( f"results/{EXPERIMENT}_{options.ntype}_{N}_{p}_{m0}_{s}.png") filename = f"{EXPERIMENT}_{options.ntype}_{N}_{p}_{m0}_{s}_graph" run_simulation(filename, nodes, advanced=True) if options.ntype == 'ws': # Watts-Strogatz Network nodes, G, config = generate_watts_strogatz_network(N=N, p=p) nodes, G = add_policymaker_journalist(nodes, G, s) _network, _ = visualize(G, config=default_config, plot_in_cell_below=False) fig, ax = draw_netwulf(_network) plt.savefig( f"results/{EXPERIMENT}_{options.ntype}_{N}_{p}_{m0}_{s}.png") filename = f"{EXPERIMENT}_{options.ntype}_{N}_{p}_{m0}_{s}_graph" run_simulation(filename, nodes, advanced=True) if options.ntype == 'ba': # Barabasi-Albert Network nodes, G, config = generate_barabasi_albert_network(N=N, m0=m0, m=m0) nodes, G = add_policymaker_journalist(nodes, G, s) _network, _ = visualize(G, config=default_config, plot_in_cell_below=False) fig, ax = draw_netwulf(_network) plt.savefig( f"results/{EXPERIMENT}_{options.ntype}_{N}_{p}_{m0}_{s}.png") filename = f"{EXPERIMENT}_{options.ntype}_{N}_{p}_{m0}_{s}_graph" run_simulation(filename, nodes, advanced=True)