def render_graph_with_graphviz(g, filename): """manual hack to render graph because graphtool's graphviz rendering is broken""" edgelist = [] for i in g.edges(): edgelist.append([g.vp.id[i.source()], g.vp.id[i.target()]]) dot = Digraph() dot.engine = 'sfdp' dot.node_attr = {'shape': "point"} dot.edge_attr = {'arrowsize': "0.1", 'penwidth':'0.1'} dot.graph_attr = {'outputorder':'edgesfirst', 'overlap':'false'} size = g.degree_property_map('out') label_size_scaler = graph_tool.draw.prop_to_size(size, mi=2, ma=6, log=False, power=0.5) node_size_scaler = graph_tool.draw.prop_to_size(size, mi=0.005, ma=0.1, log=False, power=1) # https://github.com/xflr6/graphviz/issues/85 for i in flatten_list(edgelist): gt_node = graph_tool.util.find_vertex(g, g.vp.id, i)[0] # gt_node = g_kld2.vertex(vd_kld2[i]) label_size =label_size_scaler[gt_node] node_size = node_size_scaler[gt_node] dot.node(i, xlabel=i, width=str(node_size), fontsize=str(label_size)) dot.edges(edgelist) dot.render(filename = filename)
def recalc_layout_dot(self): """recalculate node positions with dot layout""" logging.info('dot recalculating starting') t1 = time() # think i have to set it here as well, is defined in force calcs # maybe move to get_node_text_dimensions? # self.dim_ar = np.array([[self.g.nodes[i]['width'], self.g.nodes[i]['height']] for i in self.g.nodes]) # get node array self.base_pos_ar = np.array([ (self.g.nodes[i]['x'], self.g.nodes[i]['y']) for i in self.g.nodes ]) dg = Digraph() dg.graph_attr = {'rankdir': 'BT', 'dpi': '72'} dg.edges([i for i in self.g.edges]) for i in self.g.nodes: # dg.node(i) = {'width': self.g.nodes[i]['width']/96, 'height': self.g.nodes[i]['height']/96} dg.node(i, width=str(self.g.nodes[i]['width'] / 72), height=str(self.g.nodes[i]['height'] / 72)) dg_gv_piped = dg.pipe(format='json') dg_gv_parsed = json.loads(dg_gv_piped) for i in dg_gv_parsed['objects']: posx, posy = i['pos'].split(',') self.g.nodes[i['name']]['x'] = float(posx) + 20 self.g.nodes[i['name']]['y'] = float(posy) pos_nds = np.array([(self.g.nodes[i]['x'], self.g.nodes[i]['y']) for i in self.g.nodes]) self.chng_ar = (pos_nds - self.base_pos_ar) / self.step t2 = time() logging.info('dot recalc done in ' + str(round(t2 - t1)) + ' seconds')
# function: smaller angle -> greater force # no force if angle is pi force_mult = np.pi - angle # kinda would like to have some division for low angles because it really ups those forces # minus just doesn't cut it # more important than having 0 force (stuff will oscillate out anyways) force_mult = 1/angle # maybe have to multiply by constant? disp_vec *= force_mult from graphviz import Digraph dg = Digraph() dg.graph_attr = {'rankdir': 'BT', 'dpi': '72'} dg.edge('a', 'b', label = 'kkk') import json dg_gv_piped = dg.pipe(format = 'json') dg_gv_parsed = json.loads(dg_gv_piped) 27 86.997 27 36.026 27 47.808 27 63.439 27 76.842' is lp?
ontology = getData(o)["ontology_tree"] # # the tree of networks f = o_template % "tree" print(f) graph_attr = {} graph_attr["nodesep"] = "1" graph_attr["ranksep"] = "0.3" # graph_attr.edge_attr["color"] = "blue" graph_attr["splines"] = "false" # ""polyline" edge_attr = {} # edge_attr["tailport"] = "s" # edge_attr["headport"] = "n" simple_graph = Digraph("T", filename=f) simple_graph.graph_attr = graph_attr simple_graph.edge_attr = edge_attr ontology_hierarchy = walkTreeOnly(ontology, "root", simple_graph) print(ontology_hierarchy) simple_graph.view() # generates pdf os.remove(f) # # one node at the time starting with the root node in the network tree behaviour_nodes = [] structure_nodes = [] graph_attr["rankdir"] = "LR" edge_attr["tailport"] = "e" edge_attr["headport"] = "w" # msg_box" graph_attr["nodesep"] = "0.4"
def makeOntologyDotGraph(ontology_tree, ontology_name, show="write"): """ makes the ontology tree for each domain as a pdf and one pdf with all together """ import subprocess ontology = ontology_tree dot_path = os.path.join(DIRECTORIES["ontology_repository"], ontology_name, DIRECTORIES["ontology_graphs_location"], "%s") o_template = dot_path # + ".gv" o = FILES["ontology_file"] % ontology_name # # the tree of networks f = o_template % "tree" print(f) graph_attr = {} graph_attr["nodesep"] = "1" graph_attr["ranksep"] = "0.3" # graph_attr.edge_attr["color"] = "blue" graph_attr["splines"] = "false" # ""polyline" edge_attr = {} # edge_attr["tailport"] = "s" # edge_attr["headport"] = "n" simple_graph = Digraph("T", filename=f) simple_graph.graph_attr = graph_attr simple_graph.edge_attr = edge_attr ontology_hierarchy = walkTreeOnly(ontology, "root", simple_graph) print(ontology_hierarchy) if show == "view": simple_graph.view() # generates pdf else: simple_graph.render() os.remove(f) # # one node at the time starting with the root node in the network tree behaviour_nodes = [] structure_nodes = [] graph_attr["rankdir"] = "LR" edge_attr["tailport"] = "e" edge_attr["headport"] = "w" # msg_box" graph_attr["nodesep"] = "0.4" graph_attr["ranksep"] = "0.8" node = "root" n = str(node) f = o_template % n print(f) node_graph = Digraph(n, filename=f, graph_attr=graph_attr) node_graph.graph_attr = graph_attr node_graph.edge_attr = edge_attr ontology_hierarchy = singleNodeOnly(ontology, n, node_graph, behaviour_nodes, structure_nodes) if show != "summary": node_graph.view() tree = ["root"] makeTree(ontology, "root", tree) for node in tree: if node != "root": n = str(node) f = o_template % n print(f) node_graph = Digraph(n, filename=f, graph_attr=graph_attr) ontology_hierarchy = singleNodeOnly(ontology, n, node_graph, behaviour_nodes, structure_nodes) if show != "summary": node_graph.view() pdf_template = dot_path + ".pdf" merger = PdfFileMerger() pdf = pdf_template % "tree" merger.append(open(pdf, 'rb')) pdf = pdf_template % str("root") merger.append(open(pdf, 'rb')) for node in tree: if node != "root": pdf = pdf_template % str(node) merger.append(open(pdf, 'rb')) o_ = o_template % str(node) if os.path.exists(o_): os.remove(o_) o = dot_path % "all_nodes" + ".pdf" merger.write(o) if show == "summary": shell_file = FILES["latex_shell_ontology_view_exec"] % ontology_name args = ['sh', shell_file, dot_path.replace("%s", "")] # print('ARGS: ', args) make_it = subprocess.Popen( args, # start_new_session=True, # stdout=subprocess.PIPE, # stderr=subprocess.PIPE ) out, error = make_it.communicate() print("file written to :", o)
def recalc_layout_dot(self): """recalculate node positions with dot layout""" logging.info('dot recalculating starting') t1 = time() # think i have to set it here as well, is defined in force calcs # maybe move to get_node_text_dimensions? # self.dim_ar = np.array([[self.g.nodes[i]['width'], self.g.nodes[i]['height']] for i in self.g.nodes]) # get node array self.base_pos_ar = np.array([(self.g.nodes[i]['x'],self.g.nodes[i]['y']) for i in self.g.nodes]) dg = Digraph() dg.graph_attr = {'rankdir': 'BT', 'dpi': '72'} if self.use_edge_labels != True: dg.edges([i for i in self.g.edges]) for n in self.g.nodes: # dg.node(i) = {'width': self.g.nodes[i]['width']/96, 'height': self.g.nodes[i]['height']/96} if self.g.nodes[n]['nd_tp'] == 'nd': dg.node(n, width = str(self.g.nodes[n]['width']/72), height = str(self.g.nodes[n]['height']/72)) # assumes now that every edge has a label over which the out/in-going nodes can be retrieved if self.use_edge_labels == True: dg_edges = [] for n in self.g.nodes: if self.g.nodes[n]['nd_tp'] == 'lbl': node_out = list(self.g.predecessors(n))[0] node_in = list(self.g.successors(n))[0] dg.edge(node_out, node_in, label = self.g.nodes[n]['title']) logging.info(['graph:\n', str(dg)]) # logging.info(['graph:\n', dg]) dg_gv_piped = dg.pipe(format = 'json') dg_gv_parsed = json.loads(dg_gv_piped) # loop over edges? have to get get info somehow if self.use_edge_labels == True: for e in dg_gv_parsed['edges']: lbl_text = e['label'] lbl_x, lbl_y = e['lp'].split(',') head_id = e['tail'] tail_id = e['head'] head_name = dg_gv_parsed['objects'][head_id]['name'] tail_name = dg_gv_parsed['objects'][tail_id]['name'] elbl_nd_name = elbl_nd_name = "lbl_" + head_name + "_" + tail_name + "_" + lbl_text self.g.nodes[elbl_nd_name]['x'] = float(lbl_x) # self.g.nodes[elbl_nd_name]['x'] = float(lbl_x) + self.g.nodes[elbl_nd_name]['width']/2 self.g.nodes[elbl_nd_name]['y'] = float(lbl_y) for i in dg_gv_parsed['objects']: posx, posy = i['pos'].split(',') self.g.nodes[i['name']]['x'] = float(posx) + 20 # tf is this +20 doing here self.g.nodes[i['name']]['y'] = float(posy) pos_nds = np.array([(self.g.nodes[i]['x'],self.g.nodes[i]['y']) for i in self.g.nodes]) logging.info(['pos_nds:\n', pos_nds]) self.chng_ar = (pos_nds - self.base_pos_ar)/self.step t2 = time() logging.info('dot recalc done in ' + str(round(t2-t1)) + ' seconds')