def stack_exchange_interactive_graph(): import numpy as np import matplotlib.pyplot as plt plt.ion() plt.ion() import networkx import netgraph # pip install netgraph # Construct sparse, directed, weighted graph total_nodes = 20 weights = np.random.rand(total_nodes, total_nodes) connection_probability = 0.1 is_connected = np.random.rand(total_nodes, total_nodes) <= connection_probability graph = np.zeros((total_nodes, total_nodes)) graph[is_connected] = weights[is_connected] # construct a networkx graph g = networkx.from_numpy_array(graph, networkx.DiGraph) # decide on a layout pos = networkx.layout.spring_layout(g) # Create an interactive plot. # NOTE: you must retain a reference to the object instance! # Otherwise the whole thing will be garbage collected after the initial draw # and you won't be able to move the plot elements around. plot_instance = netgraph.InteractiveGraph(graph, node_positions=pos) ######## drag nodes around ######### # To access the new node positions: node_positions = plot_instance.node_positions
def draw(self): global pos, node_labels, plot_instance pos = nx.layout.spring_layout(self) node_labels = dict((node, gstr(node)) for node in self.nodes) # nx.draw(self, pos, with_labels=True, labels=node_labels) # nx.draw_networkx_edge_labels( # self, pos, edge_labels=nx.get_edge_attributes(self, 'weight') # ) plot_instance = netgraph.InteractiveGraph(self, node_positions=pos, node_labels=node_labels, node_label_font_size=6)
import matplotlib.pyplot as plt plt.ion() import netgraph plt.rcParams['axes.linewidth'] = 0.05 #set the value globally plt.figure(figsize=(20, 10)) # Construct sparse, directed, weighted graph # with positive and negative edges: total_nodes = 10 weights = np.random.randn(total_nodes, total_nodes) connection_probability = 0.2 is_connected = np.random.rand(total_nodes, total_nodes) <= connection_probability graph = np.zeros((total_nodes, total_nodes)) graph[is_connected] = weights[is_connected] # Make a standard plot: #netgraph.draw(graph) # Create an interactive plot. # NOTE: you must retain a reference to the object instance! # Otherwise the whole thing will be garbage collected after the initial draw # and you won't be able to move the plot elements around. plot_instance = netgraph.InteractiveGraph(graph, draw_arrows=False, edge_color='black') # The position of the nodes can be adjusted with the mouse. # To access the new node positions: node_positions = plot_instance.node_positions plt.show(block=True)
def set_pos(g, gtype='normal', scale=1, node_color='gray', label_size=8, initpos={}): """ Provides graphical interface to set graph node positions. If model is provided, it will also set the positions in the model object. To work, this method must be opened in an external window, so change the IPython before use usings %matplotlib qt' (or '%matplotlib osx') Parameters ---------- g : networkx graph or model normal or bipartite graph of the model of interest gtype : 'normal' or 'bipartite', optional Type of graph to plot. The default is 'normal'. scale : float, optional scale for the node sizes. The default is 1. node_color : str, optional color to use for the nodes. The default is 'gray'. label_size : float, optional size to use for the labels. The default is 8. initpos : dict, optional dict of initial positions for the labels (e.g. from nx.spring_layout). The default is {}. Returns ------- pos: dict dict of node positions for use in graph plotting functions """ set_mdl = False if not type(g) == nx.classes.graph.Graph: mdl = g set_mdl = True if gtype == 'normal': g = mdl.graph elif gtype == 'bipartite': g = mdl.bipartite plt.ion() fig = plt.figure() if gtype == 'normal': if not initpos: initpos = nx.shell_layout(g) edgeflows = {} for edge in g.edges: flows = list(g.get_edge_data(edge[0], edge[1]).keys()) edgeflows[edge[0], edge[1]] = ''.join(flow for flow in flows) plot_instance = netgraph.InteractiveGraph( g, node_size=20 * scale, node_shape='s', node_color=node_color, node_edge_width=0, node_positions=initpos, edge_labels=edgeflows, edge_label_font_size=label_size, node_labels={n: n for n in g.nodes}, node_label_font_size=label_size) elif gtype == 'bipartite': if not initpos: initpos = nx.spring_layout(g) plot_instance = netgraph.InteractiveGraph( g, node_size=7 * scale, node_color=node_color, node_edge_width=0, node_positions=initpos, node_labels={n: n for n in g.nodes}, node_label_font_size=label_size) plt.title("Click and drag to place nodes.") plt.xlabel("Close window to continue...") plt.show(block=False) t = 0 while plt.fignum_exists(fig.number): plt.pause(0.1) t += 0.1 if t < 0.2: print( "Cannot place nodes in inline version of plot. Use '%matplotlib qt' (or '%matplotlib osx') to open in external window" ) pos = { node: list(loc) for node, loc in plot_instance.node_positions.items() } if set_mdl: if gtype == 'normal': mdl.graph_pos = pos elif gtype == 'bipartite': mdl.bipartite_pos = pos return pos
G = nx.Graph() G.add_edges_from(neighborship_dict.keys()) pos = nx.spring_layout(G, k = 0.5, iterations = 70) nx.draw_networkx_labels(G, pos,labels=id_to_name(final_devices_list), font_size = 9, font_family = "sans-serif", font_weight = "bold") nx.draw_networkx_edges(G, pos, width = 4, alpha = 0.4, edge_color = 'black') nx.draw_networkx_edge_labels(G, pos, neighborship_dict, label_pos = 0.3, font_size = 6) nx.draw(G, pos, node_size = 700, with_labels = False, node_color = 'red') matp.show() continue elif user_choice == "4": import netgraph G = nx.Graph() G.add_edges_from(neighborship_dict.keys()) interactive_graph = netgraph.InteractiveGraph(G) node_positions = interactive_graph.node_positions edge_list = interactive_graph.edge_list node_labels = id_to_name(final_devices_list) # add blank labels for nodes that could not be querried by SNMP for node in node_positions.keys(): if node not in node_labels.keys(): node_labels[node]='' edge_labels = {key:neighborship_dict[key] for key in neighborship_dict.keys() if key in edge_list} interactive_graph.draw_node_labels(node_labels, node_positions,node_label_font_size=9) matp.show() elif user_choice == "5":
def print_graph(self) -> None: """ Interactive visual graph opens in new window. """ # Ensure proper packages available and imported if not has_nx: print("In order to use this function, you must pip install networkx") return if not has_mpl: print("In order to use this function, you must pip install matplotlib") return # Used to store the labels for nodes and edges node_labels = {} edge_labels = {} # Stores graph variable G = nx.DiGraph() # Draws each node in graph for node in self.nodes.values(): node_name = node.name # Name followed by ! if asserted in the current context if node in self.current_context: node_name += '!' node_labels[node_name] = node_name G.add_node(node_name) # Draws edges to other nodes to which node has arcs formed by slots (cables) if isinstance(node, Molecular): for i in range(len(node.frame.filler_set)): fillers = node.frame.filler_set[i] name = node.frame.caseframe.slots[i].name # Prints min and max with arc name if isinstance(node, MinMaxOpNode) and name in ["threshargs", "andorargs"]: name += " ({}, {})".format(node.min, node.max) # Nor wire (single down cable) displayed as not if name == "nor" and len(fillers) == 1: name = "not" for filler in fillers.nodes: filler_name = filler.name if filler in self.current_context: filler_name += '!' # If multiple down arcs go from one node to another, display them as one # edge with comma-separated arc names if (node_name, filler_name) in edge_labels: edge_labels[(node_name, filler_name)] += ", " + name else: G.add_edge(node_name, filler_name) edge_labels[(node_name, filler_name)] = name # Draws edges to other nodes to which node has arcs formed by restrictions if isinstance(node, Variable): for restriction_node in node.restriction_set: restriction_name = restriction_node.name if restriction_node in self.current_context: restriction_name += '!' if (node_name, restriction_name) in edge_labels: edge_labels[(node_name, restriction_name)] += ", restriction" else: G.add_edge(node_name, restriction_name) edge_labels[(node_name, restriction_name)] = "restriction" # Draws edges to other nodes to which node has arcs formed by dependencies if isinstance(node, Indefinite): for dependency_node in node.dependency_set: dependency_name = dependency_node.name if dependency_node in self.current_context: dependency_name += '!' if (node_name, dependency_name) in edge_labels: edge_labels[(node_name, dependency_name)] += ", dependency" else: G.add_edge(node_name, dependency_name) edge_labels[(node_name, dependency_name)] = "dependency" # Layout on which to draw nodes pos = nx.circular_layout(G) # Draggable nodes in graph if has_ng and self.nodes != {}: # This is a buggy module. # If you want adjustable graphs, you have to do an assignment for some reason _ = ng.InteractiveGraph(G, pos, node_size=10, node_label_font_size=12.0, node_color='grey', alpha=0.8, node_labels=node_labels, edge_labels=edge_labels, font_color='black') # Static graph else: nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_color='black') nx.draw_networkx(G, pos, node_size=800, node_color='grey', alpha=0.8) # Displays graph plt.subplots_adjust(left=0.0, right=1.0, top=1.0, bottom=0.0) plt.show()