def to_pydot(N, strict=True): """Return a pydot graph from a NetworkX graph N. Parameters ---------- N : NetworkX graph A graph created with NetworkX Examples -------- >>> K5 = nx.complete_graph(5) >>> P = nx.nx_pydot.to_pydot(K5) Notes ----- """ import pydotplus # set Graphviz graph type if N.is_directed(): graph_type='digraph' else: graph_type='graph' strict=N.number_of_selfloops()==0 and not N.is_multigraph() name = N.name graph_defaults=N.graph.get('graph',{}) if name is '': P = pydotplus.Dot('', graph_type=graph_type, strict=strict, **graph_defaults) else: P = pydotplus.Dot('"%s"'%name, graph_type=graph_type, strict=strict, **graph_defaults) try: P.set_node_defaults(**N.graph['node']) except KeyError: pass try: P.set_edge_defaults(**N.graph['edge']) except KeyError: pass for n,nodedata in N.nodes(data=True): str_nodedata=dict((k,make_str(v)) for k,v in nodedata.items()) p=pydotplus.Node(make_str(n),**str_nodedata) P.add_node(p) if N.is_multigraph(): for u,v,key,edgedata in N.edges(data=True,keys=True): str_edgedata=dict((k,make_str(v)) for k,v in edgedata.items()) edge=pydotplus.Edge(make_str(u), make_str(v), key=make_str(key), **str_edgedata) P.add_edge(edge) else: for u,v,edgedata in N.edges(data=True): str_edgedata=dict((k,make_str(v)) for k,v in edgedata.items()) edge=pydotplus.Edge(make_str(u),make_str(v),**str_edgedata) P.add_edge(edge) return P
def test_keep_graph_type(self): g = pydotplus.Dot(graph_name='Test', graph_type='graph') self.assertEqual(g.get_type(), 'graph') g = pydotplus.Dot(graph_name='Test', graph_type='digraph') self.assertEqual(g.get_type(), 'digraph')
def test_keep_graph_type(self): # 定义点类型,名称是Test,图像类型是graph,点类型的名称是g g = pydotplus.Dot(graph_name='Test', graph_type='graph') # 确定相等,确定g的类型是graph self.assertEqual(g.get_type(), 'graph') # 定义点的类型,图像类型是digraph g = pydotplus.Dot(graph_name='Test', graph_type='digraph') # 确认图像的类型是digraph self.assertEqual(g.get_type(), 'digraph')
def create_model_image(di_graph, name, likelihood_function): """ Using a networkx's DAG (created based on the composite model or the amalgamated model), this function creates an image of the result of the Simple Genetic Algorithm using 'pydotplus' library. Args: di_graph : nx.DiGraph() It's a networkx's digraph representing the composite model or the amalgamated model name : STRING The name given in the variable 'a_name' on 'data_logic.data_input.py' likelihood_function: INT Indicates the likelihood function that is going to be used 1 = cotemporal, 2 = next_step_one, 3 = next_step_one_two Returns: PNG IMAGE An image with the result of the problem, saved on the root file """ if likelihood_function == 1: display_graph = pydot.Dot(graph_type='graph') else: display_graph = pydot.Dot(graph_type='digraph') nodes = di_graph.nodes() for node in nodes: display_graph.add_node( pydot.Node(node, penwidth="1.5", fontname="times-bold")) edges = di_graph.edges() if likelihood_function == 1: for edge in edges: if edge[0] < edge[1]: display_graph.add_edge( pydot.Edge(edge[0], edge[1], label=" " + str(di_graph[edge[0]][edge[1]]['weight']), color="black", penwidth="1.5")) else: for edge in edges: display_graph.add_edge( pydot.Edge(edge[0], edge[1], label=" " + str(di_graph[edge[0]][edge[1]]['weight']), color="black", penwidth="1.5")) display_graph.write_png("../" + name + ".png")
def draw_net(self, caffe_net, rankdir, tplgy): pydot_graph = pydot.Dot( self.caffe_net.name if self.caffe_net.name else 'Net', graph_type='digraph', compound='true', rankdir=rankdir) tplgy.traverse(lambda node: self.add_pydot_node(node, tplgy, rankdir), lambda edge: self.add_pydot_edge(edge, tplgy)) self.draw_subgraphs(tplgy, pydot_graph) for edge in self.pydot_edges: if edge['dst'] not in self.pydot_nodes: print( 'Fatal error: node \'%s\' of edge %s is not in the pydot_node list!' % (edge['dst'], edge)) #exit() break style = 'dashed' if edge['memory'] == 'scratchpad' else '' pydot_graph.add_edge( pydot.Edge(self.pydot_nodes[edge['src']], self.pydot_nodes[edge['dst']], label=edge['label'], style=style)) print("Number of nodes:", len(self.pydot_nodes)) if self.__prefs['gen_dot_file']: print('Generating dot file') pydot_graph.write_raw('debug.dot') return pydot_graph.create_png()
def visiualization(lists): g = pydotplus.Dot(graph_type='digraph') i = 0 for item in lists: #不同node强制用不同的名字 node_name = item.name if 'leaf' in node_name and item.node['val'] != -1: node_name = "leaf" + str(i) + "\n" + str(item.node['val']) i += 1 node = pydotplus.Node(node_name) if item.node['property'] == 'internal': node.set('shape', 'diamond') else: node.set('shape', 'box') father_node_name = item.node['father'] if father_node_name != 'root': father_node_name = item.node['father'].name father_node = pydotplus.Node(father_node_name) edge = pydotplus.Edge(father_node_name, node_name) if 'ft_val' in list(item.node.keys()): edge.set('label', item.node['ft_val']) g.add_node(node) g.add_node(father_node) g.add_edge(edge) g.write("dt-tree.png", format='png') import os os.system("eog dt-tree.png")
def breadth_first_search(root): print("Starting Node(root) : %s" % root) graph = pydotplus.Dot(graph_type='digraph') queue = deque([root]) visited = [] expansion = 0 while True: node = queue.popleft() print("\n Parent Node : %s ,Currently popped node %s at depth %s" % (node.parent, node.state, node.depth)) if str(node) in visited: continue visited.append(str(node)) graph.add_node(node.dot) if node.parent: graph.add_edge(pydotplus.Edge(node.parent.dot, node.dot)) if node.state.is_goal(): graph.write_png('solution.png') print("\nReached Goal State at %s" % node.state) # print("Total no. of expansion is %d" % expansion) solution = node.get_solution() return solution expansion += 1 queue.extend(node.successor_node())
def bpmn_diagram_to_png(bpmn_diagram, file_name): """ Create a png picture for given diagram :param bpmn_diagram: an instance of BPMNDiagramGraph class, :param file_name: name of generated file. """ g = bpmn_diagram.diagram_graph graph = pydotplus.Dot() for node in g.nodes(data=True): if node[1].get(consts.Consts.type) == consts.Consts.task: n = pydotplus.Node(name=node[0], shape="box", style="rounded", label=node[1].get(consts.Consts.node_name)) elif node[1].get(consts.Consts.type) == consts.Consts.exclusive_gateway: n = pydotplus.Node(name=node[0], shape="diamond", label=node[1].get(consts.Consts.node_name)) else: n = pydotplus.Node(name=node[0], label=node[1].get(consts.Consts.node_name)) graph.add_node(n) for edge in g.edges(data=True): e = pydotplus.Edge(src=edge[2].get(consts.Consts.source_ref), dst=edge[2].get(consts.Consts.target_ref), label=edge[2].get(consts.Consts.name)) graph.add_edge(e) graph.write(file_name + ".png", format='png')
def _create_base_dot(self, subheading): dot = pydot.Dot("NOC", graph_type="digraph", strict=True) dot.set_prog("neato") dot.set_node_defaults(shape="none", fontsize=14, margin=0, fontname="Arial") dot.set_edge_defaults(fontsize=13, fontname="Arial") # dot.set_page('11.7,8.3!') # dot.set_margin(0.5) # dot.set_ratio('fill') dot.set_rankdir("LR") dot.set_fontname("Arial") dot.set_nodesep(0.3) dot.set_splines("spline") sg = pydot.Cluster() # 'physical', label='Physical') # sg.set_color('gray80') sg.set_style("invis") # sg.set_labeljust('l') dot.add_subgraph(sg) title = pydot.Node( "title", shape="none", label=self._title_label(self.opts.get("name"), subheading), ) title.set_pos("0,0!") title.set_fontsize(18) dot.add_node(title) return dot, sg
def render_graph(bb_graph, filename): """ Renders a basic block graph to file :param bb_graph: The Graph to render :type bb_graph: networkx.DiGraph """ graph = pydotplus.Dot(graph_type='digraph', rankdir='TB') entryblock = nx.get_node_attributes(bb_graph, 'isEntry').keys()[0] returnblocks = nx.get_node_attributes(bb_graph, 'isTerminal').keys() nodedict = {} for bb in bb_graph.nodes.iterkeys(): node = render_bb(bb, bb == entryblock, bb in returnblocks) if bb == entryblock: sub = pydotplus.Subgraph('sub', rank='source') sub.add_node(node) graph.add_subgraph(sub) else: graph.add_node(node) nodedict[bb] = node for edge in bb_graph.edges.iteritems(): edge = (edge[0][0], edge[0][1], edge[1]) src = nodedict[edge[0]] dest = nodedict[edge[1]] e_style = 'dashed' if edge[2]['edge_type'] == 'implicit' else 'solid' graph.add_edge(pydotplus.Edge(src, dest, style=e_style)) # graph.set('splines', 'ortho') # graph.set_prog('neato') # graph.set('dpi', '100') graph.write(filename, format='svg')
def __init__(self): super(DotCode, self).__init__() # Secuencia para nombres de nodos self.id = 0 # Stack para retornar nodos procesados self.stack = [] # Inicializacion del grafo para Dot self.dot = pgv.Dot('AST', graph_type='digraph') self.dot.set_node_defaults(shape='box', color='lightgray', style='filled') self.dot.set_edge_defaults(arrowhead='none') # variables de control self.pasecommandread = False self.pasecommandwrite = False self.paseAssing = False # listas de simbolos self.valoresEnteros = "IJKLMN" self.valoresInt = [["I", None], ["J", None], ["K", None], ["L", None], ["M", None], ["N", None]] self.valoresFlotantes = "ABCDEFGHIOPQRSTUVWXYZ" self.valoresFloat = []
def plot(cls, root: BiNode, path): ''' 打印单颗树 (pydotplus + graphviz) brew install graphviz graphviz文档 https://graphviz.readthedocs.io/en/stable/manual.html graphviz官网 https://graphviz.gitlab.io/documentation/ pydotplus https://github.com/carlos-jenkins/pydotplus ''' if not root: return dot = pdp.Dot(graph_type='digraph') # graph = pdp.Graph(graph_type='digraph') dot.set_node_defaults(shape='box') # 遍历获取决策树的父子节点关系 nodes = cls.level_traversal(root) edges = cls.level_traversal(root, get_rel_pair=True) # 添加节点 for tree_node in nodes: node = pdp.Node(name=tree_node.id, label=tree_node.kwargs_to_str()) dot.add_node(node) # 添加边 for pair in edges: label='Y' if pair[0].left == pair[1] else 'N' edge = pdp.Edge(src=pair[0].id, dst=pair[1].id, label=label) dot.add_edge(edge) if path: dot.write(path, format='png') return dot.to_string()
def visualize(aTree): def traverse(aNode, graph): node_lbl = aNode.id if aNode.id > 0 else '' # node_lbl = '[%i; %i]' % (aNode.leaflist_start, aNode.leaflist_end) if hasattr(aNode, 'marked') and aNode.marked: graph.add_node( pydot.Node(aNode.graphid, label=node_lbl, style='filled', fillcolor='#ddffdd')) else: graph.add_node(pydot.Node(aNode.graphid, label=node_lbl)) if aNode.parent is not None: edge = pydot.Edge(aNode.parent.graphid, aNode.graphid, label=aNode.parentEdge) graph.add_edge(edge) for c in aNode.children: traverse(c, graph) graph = pydot.Dot(graph_type='graph') tree_root = aTree.root if type(aTree) == suffix_tree.Tree else aTree traverse(tree_root, graph) return graph
async def gold_exchange(self): channel = self.get_channel(channel_id) for elem in self.players: if len(elem.thieves) > 0: elem.gold = elem.gold // 2 incomes = [] for i in range(len(self.players)): incomes.append(0) for i in range(len(self.players)): for thief in self.players[i].thieves: incomes[thief.id - 1] = self.players[i].gold // len(self.players[i].thieves) for i in range(len(self.players)): self.players[i].gold += incomes[i] graph = pydotplus.Dot(graph_type="digraph") for elem in self.players: node = pydotplus.Node(elem.user.name, style="filled", fillcolor="blue") graph.add_node(node) for elem in self.players: for thief in elem.thieves: edge = pydotplus.Edge(thief.user.name, elem.user.name) graph.add_edge(edge) graph.write_png('day' + str(self.day) + '.png') await channel.send(file=discord.File('day' + str(self.day) + '.png')) for elem in self.players: elem.thieves = []
def ExportGraphFunc(): global G, TransformationNumber if G == None: return Nodes = G.get_node_list() Edges = G.get_edge_list() GExport = pydotplus.Dot(graph_type="graph") for N in Nodes: name = N.get_name() lbl = N.get("label") newnode = pydotplus.Node(name, label=lbl) GExport.add_node(newnode) for E in Edges: sorc = E.get_source() dest = E.get_destination() newedge = pydotplus.Edge(sorc, dest) GExport.add_edge(newedge) GExport.write("{}.{}".format("Exported" + str(TransformationNumber), 'dot'), format='dot')
def __init__(self, smarthome, abitem): super().__init__(abitem) if not REQUIRED_PACKAGE_IMPORTED: self._log_warning( "Unable to import Python package 'pydotplus'. Visualizing SE items will not work." ) self.__states = abitem.webif_infos self.__name = abitem.id self.__active_conditionset = abitem.lastconditionset_name self.__active_state = abitem.laststate self.__graph = pydotplus.Dot('StateEngine', graph_type='digraph', splines='false', overlap='scale', compound='false') self.__graph.set_node_defaults(color='lightgray', style='filled', shape='box', fontname='Helvetica', fontsize='10') self.__graph.set_edge_defaults(color='darkgray', style='filled', shape='box', fontname='Helvetica', fontsize='10') self.__nodes = {} self.__scalefactor = 0.1 self.__textlimit = 145 self.__conditionset_count = 0
def plot_categorical_decision_tree(query=None): graph = pdp.Dot(graph_type='digraph') DECISION_TREE.plot(graph, query=query) graph.write_png('tree.png') img = cv2.imread('tree.png') cv2.imshow("Decision Tree", img) cv2.waitKey(0)
def Visualize_Optimal_Partitions(Partitions,edge_list,node_list): global colors graph = pydot.Dot(graph_type = 'digraph', nodesep = .5) graph.set_node_defaults(style = "filled",shape = "rect",fontsize = "20.0") graph.set_edge_defaults(color = 'blue', arrowhead = "vee") temp_dict = {} count = 0 #Highlight Groups of Two Input Gates mapped to same LUT for i in Partitions: for j in i: temp_dict[j] = pydot.Node(j, color = colors[count]) graph.add_node(temp_dict[j]) count+= 1 #base/input nodes highlighted in grey color for i in node_list: if i[:3] not in Operators and i[:2] not in Operators: temp_dict[i] = pydot.Node(i, color= u'#DCDCDC') graph.add_node(temp_dict[i]) #Add edges for i in edge_list: graph.add_edge(pydot.Edge(temp_dict[i[0]],temp_dict[i[1]])) #Store result in a file graph.write_png('partion_graph.png')
def drawCFG(code_obj, filename): ''' Draw the CFG of the code object. :param code_obj: the code object :type code_obj: code :param filename: filename of svg :type filename: str ''' global entrypoint # For normal codeobjects entrypoint = oep = 0 #entrypoint = oep = findOEP(code_obj) entrypoint = oep = 0 if oep == -1: print 'Not generating cfg for ', code_obj.co_name return leader_set = getLeaders(code_obj, oep) bblist = buildBasicBlocks(leader_set, code_obj) nodelist = [] graph = pydotplus.Dot(graph_type = 'digraph') # graph.set('splines', 'curved') for bb in bblist: node = bb.toDotNode() nodelist.append(node) graph.add_node(node) buildEdges(graph, bblist, nodelist) graph.write_svg(filename)
def __init__(self, max_level, db_features_list, k): self.max_level = max_level self.db_features_dict = {} self.db_features_ids = [] self.graph = pydot.Dot(graph_type='graph') self.query_ts = None self.query_score_chart = None self.node_shortcuts = None self.weights = None self.d_matrix = None self._original_time_series_ids = None self._query_vector = None self.n_nodes = 0 self.k = k id_ = 0 for ts in db_features_list: ts._id = id_ self.db_features_ids.append(ts._id) self.db_features_dict[ts._id] = ts id_ += 1 self.root = Node(0, self.max_level, self.db_features_ids, affinities, None, None, self.get_db_features_dict(), self.get_next_node_id(), self.get_original_time_series_ids(), self.k) self._build_node_shorcuts() self._build_weights_vector() self._build_d_matrix()
def make_pydot_graph(layers, output_shape=True, verbose=False): """ :parameters: - layers : list List of the layers, as obtained from lasagne.layers.get_all_layers - output_shape: (default `True`) If `True`, the output shape of each layer will be displayed. - verbose: (default `False`) If `True`, layer attributes like filter shape, stride, etc. will be displayed. :returns: - pydot_graph : PyDot object containing the graph """ import pydotplus as pydot pydot_graph = pydot.Dot('Network', graph_type='digraph') pydot_nodes = {} pydot_edges = [] for i, layer in enumerate(layers): layer_type = '{0}'.format(layer.__class__.__name__) key = repr(layer) label = layer_type color = get_hex_color(layer_type) if verbose: for attr in [ 'num_filters', 'num_units', 'ds', 'filter_shape', 'stride', 'strides', 'p' ]: if hasattr(layer, attr): label += '\n{0}: {1}'.format(attr, getattr(layer, attr)) if hasattr(layer, 'nonlinearity'): try: nonlinearity = layer.nonlinearity.__name__ except AttributeError: nonlinearity = layer.nonlinearity.__class__.__name__ label += '\nnonlinearity: {0}'.format(nonlinearity) if output_shape: label += '\nOutput shape: {0}'.format(layer.output_shape) pydot_nodes[key] = pydot.Node(key, label=label, shape='record', fillcolor=color, style='filled') if hasattr(layer, 'input_layers'): for input_layer in layer.input_layers: pydot_edges.append([repr(input_layer), key]) if hasattr(layer, 'input_layer'): pydot_edges.append([repr(layer.input_layer), key]) for node in pydot_nodes.values(): pydot_graph.add_node(node) for edges in pydot_edges: pydot_graph.add_edge( pydot.Edge(pydot_nodes[edges[0]], pydot_nodes[edges[1]])) return pydot_graph
def test_executable_not_found_exception(self): paths = {'dot': 'invalid_executable_path'} graph = pydotplus.Dot('graphname', graph_type='digraph') graph.set_graphviz_executables(paths) self.assertRaises(pydotplus.InvocationException, graph.create)
def get_pydot_graph(caffe_net, rankdir, label_edges=True): """Create a data structure which represents the `caffe_net`. Parameters ---------- caffe_net : object rankdir : {'LR', 'TB', 'BT'} Direction of graph layout. label_edges : boolean, optional Label the edges (default is True). Returns ------- pydot graph object """ pydot_graph = pydot.Dot(caffe_net.name, graph_type='digraph', rankdir=rankdir) pydot_nodes = {} pydot_edges = [] for layer in caffe_net.layer: node_label = get_layer_label(layer, rankdir) node_name = "%s_%s" % (layer.name, layer.type) if (len(layer.bottom) == 1 and len(layer.top) == 1 and layer.bottom[0] == layer.top[0]): # We have an in-place neuron layer. pydot_nodes[node_name] = pydot.Node(node_label, **NEURON_LAYER_STYLE) else: layer_style = LAYER_STYLE_DEFAULT layer_style['fillcolor'] = choose_color_by_layertype(layer.type) pydot_nodes[node_name] = pydot.Node(node_label, **layer_style) for bottom_blob in layer.bottom: pydot_nodes[bottom_blob + '_blob'] = pydot.Node('%s' % bottom_blob, **BLOB_STYLE) edge_label = '""' pydot_edges.append({'src': bottom_blob + '_blob', 'dst': node_name, 'label': edge_label}) for top_blob in layer.top: pydot_nodes[top_blob + '_blob'] = pydot.Node('%s' % (top_blob)) if label_edges: edge_label = get_edge_label(layer) else: edge_label = '""' pydot_edges.append({'src': node_name, 'dst': top_blob + '_blob', 'label': edge_label}) # Now, add the nodes and edges to the graph. for node in pydot_nodes.values(): pydot_graph.add_node(node) for edge in pydot_edges: pydot_graph.add_edge( pydot.Edge(pydot_nodes[edge['src']], pydot_nodes[edge['dst']], label=edge['label'])) return pydot_graph
def __init__(self, root, node_obj_representation, output_path): graph_representation = convert_to_graph_representation(root, node_obj_representation) visualizer_input = [graph_representation[0], graph_representation[1:]] # input format for visualizer: [root, children] ~ [root, [[root (child 1), child 1 child 1], child 2,...]] self.graph = pydot.Dot(graph_type='digraph') self.graph.add_node(pydot.Node(visualizer_input[0], )) self.add_edges(visualizer_input[0], visualizer_input[1]) self.graph.write_png(output_path)
def __init__(self): """ Constructor """ # create graph object self.graph = pydotplus.Dot(graph_type='graph', dpi=800) #index of node self.index = 0
def test_create_simple_graph_with_node(self): g = pydotplus.Dot() g.set_type('digraph') node = pydotplus.Node('legend') node.set("shape", 'box') g.add_node(node) node.set('label', 'mine') self.assertEqual(g.to_string(), 'digraph G {\nlegend [label=mine, shape=box];\n}\n')
def test_quoting(self): # 导入string 包 import string # 创建dot数据 g = pydotplus.Dot() # 添加一个点,节点的名称是test,标签是string.printable,暂时不知道什么意思 g.add_node(pydotplus.Node("test", label=string.printable)) # 创建图,格式是jpe data = g.create(format='jpe') # 检测data,即图的大小是0 self.assertEqual(len(data) > 0, True)
def to_pydot(viz_dag, graph_attr=None, node_attr=None, edge_attr=None): node_groups = {} for name, data in viz_dag.nodes(data=True): group = data.get('_group') node_groups.setdefault(group, []).append(name) edge_groups = {} for name1, name2, data in viz_dag.edges(data=True): group = data.get('_group') edge_groups.setdefault(group, []).append((name1, name2)) viz_dot = pydotplus.Dot() if graph_attr is not None: for k, v in six.iteritems(graph_attr): viz_dot.set(k, v) if node_attr is not None: viz_dot.set_node_defaults(**node_attr) if edge_attr is not None: viz_dot.set_edge_defaults(**edge_attr) for group, names in six.iteritems(node_groups): if group is None: continue c = pydotplus.Subgraph('cluster_' + str(group)) for name in names: node = pydotplus.Node(name) for k, v in six.iteritems(viz_dag.node[name]): if not k.startswith("_"): node.set(k, v) c.add_node(node) for name1, name2 in edge_groups.get(group, []): edge = pydotplus.Edge(name1, name2) c.add_edge(edge) c.obj_dict['label'] = str(group) viz_dot.add_subgraph(c) for name in node_groups.get(None, []): node = pydotplus.Node(name) for k, v in six.iteritems(viz_dag.nodes[name]): if not k.startswith("_"): node.set(k, v) viz_dot.add_node(node) for name1, name2 in edge_groups.get(None, []): edge = pydotplus.Edge(name1, name2) viz_dot.add_edge(edge) return viz_dot
def buildGraph(bb_list): graph = pydotplus.Dot(graph_type='digraph') # graph.set('splines', 'curved') nodelist = [] for bb in bb_list: node = bbToDot(bb) graph.add_node(node) nodelist.append(node) buildEdges(graph, nodelist, bb_list) graph.write_svg('1_d.svg')
def plot(self): fig = pydotplus.Dot(graph_name=self.conf['pipeline']['name'], rankdir="LR", labelloc='b', labeljust='r', ranksep=1) fig.set_node_defaults(shape='square') modules = [] for module in self.conf['modules']: if 'input_file' in module: modules.append( pydotplus.Node( name='input_file', texlbl='Input file\n' + module['input_file'], label='Input file\n' + module['input_file'])) label = '' if 'params' in module: for param in module['params']: if param['type'] == 'collection': label += 'param ' + param[ 'name'] + ' values: [' + ','.join( param['values']) + ']\n' else: label += 'param ' + param['name'] + ' range: [' + str( param['start']) + ', ' + str( param['step_size']) + ', ' + str( param['end']) + ']\n' modules.append( pydotplus.Node(name=module['name'], texlbl=module['name'], label=module['name'] + '\ntype: ' + module['type'] + '\n' + label + 'instances: ' + str(module['instances']))) if 'output_file' in module: modules.append( pydotplus.Node( name='output_file', texlbl='Output file' + module['output_file'], label='Output file\n' + module['output_file'])) for node in modules: fig.add_node(node) for i in range(len(modules) - 1): fig.add_edge(pydotplus.Edge(modules[i], modules[i + 1])) fig.write_png(self.conf['pipeline']['name'] + '.png')