## compute the degeneracy ordering of the nodes peel = tlp.DoubleProperty(self.graph) self.graph.applyDoubleAlgorithm("K-Cores", peel) peelMap = {} for u in self.graph.getNodes(): peelMap[u] = peel[u] sortedMap = OrderedDict(sorted(peelMap.items(), key=lambda x: x[1])) order = list(sortedMap.keys()) ## start clique detection for i in range(len(order)): Nu = self.getNeighborhoodSet(order[i]) if i == len(order) - 1: P = set() else: P = Nu & set(order[(i + 1):len(order)]) if i == 0: X = set() else: X = Nu & set(order[0:i]) self.maxCliquePivot(P, set([order[i]]), X) ## end return True ################################################################################################################### tulipplugins.registerPluginOfGroup( "CliquesEnum", "Cliques Enumeration", "François Queyroi", "07/03/2019", "Enumerate All Maximal Cliques using [Eppstein et al., 2010] method.", "1.0", "Clustering")
header_fields = headers.split(entry_separator) col_mode = self.dataSet['Column header mode'] for f in header_fields: if f == '': continue n = self.graph.addNode() label[n] = f mode[n] = col_mode color[n] = column_color shape[n] = column_shape column_nodes.append(n) row_mode = self.dataSet['Row header mode'] line = fp.readline() while line != '': row_entries = line.split(entry_separator) n = self.graph.addNode() label[n] = row_entries[0] mode[n] = row_mode color[n] = line_color shape[n] = line_shape row_entries.pop(0) for i, entry in enumerate(row_entries): if entry != '': self.graph.addEdge(n, column_nodes[i]) line = fp.readline() return True # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("ImportTwoMode", "Two Mode Network", "G. Melancon", "08/06/2016", "", "1.0", "File")
value = float(value - self.minElements[c]) / (self.maxElements[c] - self.minElements[c]) else: value = 0.0 color = self.getColorAtPos(value) trapezoid.color(color) #Returns the color for a given position in the color scale. This method computes the color associated to a specific position in the color scale and returns it. def getColorAtPos(self, pos): theColor = None minDist = 1.0 for value, color in self.colorScale.iteritems(): newDist = abs(pos - value) if newDist < minDist: theColor = color minDist = newDist return theColor # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("DataTubePlugin", "Data Tube", "Nicolas Chabalier", "18/06/2017", "infos", "1.0", "Python")
if f == '': continue n = self.graph.addNode() label[n] = f mode[n] = col_mode color[n] = column_color shape[n] = column_shape column_nodes.append(n) row_mode = self.dataSet['Row header mode'] line = fp.readline() while line != '': row_entries = line.split(entry_separator) n = self.graph.addNode() label[n] = row_entries[0] mode[n] = row_mode color[n] = line_color shape[n] = line_shape row_entries.pop(0) for i, entry in enumerate(row_entries): if entry != '': self.graph.addEdge(n, column_nodes[i]) line = fp.readline() return True # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("ImportTwoMode", "Two Mode Network", "G. Melancon", "08/06/2016", "", "1.0", "File")
# init properties for logos if self.logo_folder != '': color = self.graph.getColorProperty("viewColor") color.setAllNodeValue(tlp.Color(255, 255, 255, 255)) shape = self.graph.getIntegerProperty("viewShape") shape.setAllNodeValue(0) # crawl bands info bandNodes = {} # MA id to Band object, Tulip node self.crawlSimilarBands(bandNodes, self.base_url, 0) # add graph edges score = self.graph.getDoubleProperty("score") for band, n in bandNodes.values(): for id_sim, url_sim, score_sim in band.similar_bands: if id_sim in bandNodes.keys(): sim_b, sim_n = bandNodes[id_sim] e = self.graph.addEdge(n, sim_n) score[e] = score_sim return True # The line below does the magic to register the plugin into the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup( "MASimilarBandsCrawling", "Similar Metal Bands", "Francois Queyroi", "02/12/2019", "Crawling of metal-archives.org visiting bands similar to the given band.", "1.0", "Python")
) # remove temporary directory shutil.rmtree(tmpdir) return False # import the dot file in Tulip trough the graphviz import plugin dotImportParams = tlp.getDefaultPluginParameters( "graphviz", self.graph) dotImportParams['filename'] = cmakeProjectDotFilePath tlp.importGraph("graphviz", dotImportParams, self.graph) # set some visual attributes to the imported graph self.graph['viewSize'].setAllNodeValue(tlp.Size(1, 1, 1)) self.graph['viewShape'].setAllNodeValue(tlp.NodeShape.Circle) # apply a force directed algorithm to draw the graph self.graph.applyLayoutAlgorithm( 'Fast Multipole Multilevel Embedder (OGDF)') # remove temporary directory shutil.rmtree(tmpdir) # done return True # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("CMakeDependenciesGraphImport", "CMake dependencies graph", "Antoine Lambert", "24/11/2015", \ "Import the targets dependencies graph of a CMake project", "1.0", "Software")
if UID[n] == -1: if IsTrivial[n] == 1: #logging.debug('IsTrivial==1') self.result[n] = 1 else: #logging.debug('IsTrivial<>1') next_uid = max_prime_uid + 1 #Bertrand's postulate: there exists a prime between Pn and 2*Pn where Pn is the n-th prime for possiblePrime in range(next_uid, 2 * next_uid): isPrime = True # Assume next_uid is prime until shown it is not. for num in range(2, int(possiblePrime**0.5) + 1): if possiblePrime % num == 0: isPrime = False break if isPrime: next_uid = possiblePrime break #logging.debug(next_uid) self.result[n] = next_uid max_prime_uid = next_uid else: #logging.debug('UID<>-1') self.result[n] = UID[n] return True tulipplugins.registerPluginOfGroup("AugmentationGenerateNextPrime", "Generate Next Prime UID", "Janos Varga", "19/01/2019", "", "1.0", "PORGY")
def process_sequence(self, sortProperty): ''' uses the sequence and maps nodes to coordonates inthe 2D plane each letter in the sequence correspond to either - mapping coordinaletes to a node (L, R) - going forward (F) according to the directional vector - rotating the directional vector (+, -) ''' id = 0 nodeList = sorted(list(graph.getNodes()), key=lambda x: sortProperty[x]) for letter in self.sequence: if id < self.graph.numberOfNodes(): if (letter == 'L' or letter == 'R'): node = nodeList[id] self.graph.getLayoutProperty( "viewLayout")[node] = self.current_coord id = id + 1 if (letter == 'F'): self.current_coord = self.current_coord + 2 * self.direction_vector if (letter == '+'): self.rotate_dir_vector(math.pi / 2) if (letter == '-'): self.rotate_dir_vector(math.pi / -2) # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("HilbertPlugin", "Hilbert", "Elian Cocchi", "26/06/2017", "infos", "1.0", "Python")
e = sg.existEdge(n1, n2, False) if not e.isValid(): e = sg.addEdge(n1, n2) tSList = timeStamps[e] tSList.append(ts) timeStamps[e] = tSList durList = durations[e] durList.append(link.duration) durations[e] = durList dirList = directions[e] dirList.append(link.direction) directions[e] = dirList if multiProj: e = mg.addEdge(n1, n2) timeStamp[e] = ts direction[e] = link.direction duration[e] = link.duration vC[e] = tlp.Color(color) if self.dataSet["Force layout"]: if multiProj: vL = mg.getLayoutProperty("viewLayout") mg.applyLayoutAlgorithm("FM^3 (OGDF)", vL) if simpleProj: vL = sg.getLayoutProperty("viewLayout") sg.applyLayoutAlgorithm("FM^3 (OGDF)", vL) tulipplugins.registerPluginOfGroup("LoadLinkStream", "Load a linkstream", "Benjamin Renoust & Jordan Viard", "15/06/2015", "Loads a link stream", "1.0", "LinkStream")
def icon(self): return os.path.dirname(__file__) + '/npm.png' def importGraph(self): npmPackageDir = self.dataSet[npmPackageDirParamName] # Check if the directory contains a npm package first rootPackageJson = npmPackageDir + '/package.json' if not os.path.exists(rootPackageJson): if self.pluginProgress: self.pluginProgress.setError('Error : directory ' + npmPackageDir + ' does not seem to contain a npm package.') return False # parse package depedencies graph parsePackageJsonForDependenciesGraph(npmPackageDir, self.graph) # apply a force directed algorithm to draw the graph self.graph.applyLayoutAlgorithm('Fast Multipole Multilevel Embedder (OGDF)') return True # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("NpmPackageDependenciesGraphImport", "Npm package dependencies graph", "Antoine Lambert", "26/11/2015",\ """ Import the packages dependencies graph from a npm package. Be sure to have called 'npm install' in the package directory first in order to get the complete dependencies graph. """, "1.0", "Software")
else: ratios[param] /= ratios['ch6'] ratios['ch6'] /= n def evaluatePathwayInteractionsRatios(self, pathway, ratios): e = pathway.numberOfEdges() for interactionStatus in ('gain', 'loss'): if e == 0: ratios[interactionStatus] = 0 else: for interaction in pathway.getEdges(): if self.interactionStatus[interaction] == interactionStatus: ratios[interactionStatus] += 1 ratios[interactionStatus] /= e def filterAndSortRatiosByModality(self, pathwaysRatios, modalities): for modality in modalities: pathwaysRatios.sort(key=lambda elt: (elt[1][modality], elt[1]['ch6']), reverse=True) print('\n', modality.capitalize()) print('name,', ','.join(modalities)) for elt in pathwaysRatios: if elt[1][modality] != 0: print('{}, '.format(elt[0]), end='') for param in modalities: print('{:.2%}, '.format(elt[1][param]), end='') print() tulipplugins.registerPluginOfGroup("ImportantPathways", "Important Pathways", "AM2E", "29/01/2020", "", "1.0", "AM2E")
# The method must return a boolean indicating if the algorithm # has been successfully applied on the input graph. # edge_weight = self.graph.getDoubleProperty('edge_weight') edge_weight = self.dataSet['(Optional) Edge weight property'] to_delete = [] for n in self.graph.getNodes(): neighbors = [e for e in self.graph.getInEdges(n)] source_set = set([self.graph.source(ee) for ee in neighbors]) for nn in source_set: filtered_ee = filter( lambda x: self.graph.source(x).id == nn.id, neighbors) if self.dataSet['Aggregation mode'] == 'Uniform unit weight': nb_ee = len(filtered_ee) else: nb_ee = sum([edge_weight[e] for e in neighbors]) for ee in filtered_ee: to_delete.append(ee) eee = self.graph.addEdge(nn, n) edge_weight[eee] = nb_ee self.graph.delEdges(to_delete) return True # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("MakeSimpleCount", "Make Simple with edge multiplicity", "Guy Melancon", "12/12/2017", "", "1.0", "Topology Update")
merge_subgraph.addEdge(e) def check(self): # This method is called before applying the algorithm on the input graph. # You can perform some precondition checks here. # See comments in the run method to know how to access to the input graph. # Must return a tuple (boolean, string). First member indicates if the algorithm can be applied # and the second one can be used to provide an error message return (True, "") def run(self): # This method is the entry point of the algorithm when it is called # and must contain its implementation. # The graph on which the algorithm is applied can be accessed through # the "graph" class attribute (see documentation of class tlp.Graph). # The parameters provided by the user are stored in a Tulip DataSet # and can be accessed through the "dataSet" class attribute # (see documentation of class tlp.DataSet). # The method must return a boolean indicating if the algorithm # has been successfully applied on the input graph. self.merge() return True # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("MergeSubGraphs", "Merge SubGraphs", "Guy Melancon", "12/12/2017", "", "1.0", "SubGraphs")
scaling = 1000 if self.dataSet: scaling = self.dataSet['layout scaling'] self.result.scale((scaling, scaling, scaling)) # cleanup computed spanning tree tlp.TreeTest.cleanComputedTree(self.graph, spanningTree) return True pluginDoc = """ Implements the H3 layout technique for drawing large directed graphs as node-link diagrams in 3D hyperbolic space. That algorithm can lay out much larger structures than can be handled using traditional techniques for drawing general graphs because it assumes a hierarchical nature of the data. It was first published as:<br/><b> H3: Laying out Large Directed Graphs in 3D Hyperbolic Space</b>, Tamara Munzner, Proceedings of the 1997 IEEE Symposium on Information Visualization, Phoenix, AZ, pp 2-10, 1997.<br/> The implementation in Python (MIT License) has been written by BuzzFeed engineers (https://github.com/buzzfeed/pyh3). """ # The line below does the magic to register the plugin into the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup('H3Layout', 'H3', 'Antoine Lambert', '30/08/2017', pluginDoc, '1.0', 'Hierarchical')
for n in self.graph.getNodes(): self.result[n] = tlp.Coord(tree.nodes[n].coord.x, tree.nodes[n].coord.y, tree.nodes[n].coord.z) # apply some scaling factor to the layout to get a correct rendering # in Tulip scaling = 1000 if self.dataSet: scaling = self.dataSet["layout scaling"] self.result.scale(tlp.Vec3f(scaling)) # cleanup computed spanning tree tlp.TreeTest.cleanComputedTree(self.graph, spanningTree) return True # The line below does the magic to register the plugin into the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("H3Layout", "H3", "Antoine Lambert", "30/08/2017", """ Implements the H3 layout technique for drawing large directed graphs as node-link diagrams in 3D hyperbolic space. That algorithm can lay out much larger structures than can be handled using traditional techniques for drawing general graphs because it assumes a hierarchical nature of the data. It was first published as: <b> H3: Laying out Large Directed Graphs in 3D Hyperbolic Space </b>. Tamara Munzner. Proceedings of the 1997 IEEE Symposium on Information Visualization, Phoenix, AZ, pp 2-10, 1997. The implementation in Python (MIT License) has been written by BuzzFeed (https://github.com/buzzfeed/pyh3). """ , "1.0", "Hierarchical")
return (True, "") def run(self): # This method is the entry point of the algorithm when it is called # and must contain its implementation. # The graph on which the algorithm is applied can be accessed through # the "graph" class attribute (see documentation of class tlp.Graph). # The parameters provided by the user are stored in a Tulip DataSet # and can be accessed through the "dataSet" class attribute # (see documentation of class tlp.DataSet). # The method must return a boolean indicating if the algorithm # has been successfully applied on the input graph. self.two_mode_graph = self.graph.getSubGraph('Two_mode_graph') if self.two_mode_graph == None: self.two_mode_graph = self.graph.addCloneSubGraph('Two_mode_graph') self.substrates = [n for n in self.two_mode_graph.getNodes() if self.dataSet["Entity type"][n] == self.dataSet["Substrates (projected entities)"]] self.substrate_graph = self.graph.addSubGraph() for s in self.substrates: self.substrate_graph.addNode(s) self.substrate_graph.setName('Multilayer ' + self.dataSet['Substrates (projected entities)'] + ' Projection') self.edge_weight = self.substrate_graph.getDoubleProperty('edge_weight') self.project() return True # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("Multilayer", "Multilayer Projection", "Guy Melancon", "12/12/2017", "", "1.0", "Two_mode_Networks")
for n in self.graph.getNodes(): w = self.graph['viewSize'][n][0] h = self.graph['viewSize'][n][1] s = min(w, h) self.graph['viewSize'][n] = tlp.Size(s) if tulipGuiOk: for v in tlpgui.getViewsOfGraph(self.graph): if isinstance(v, tlpgui.NodeLinkDiagramComponent): rp = v.getRenderingParameters() rp.setEdge3D(True) rp.setViewArrow(True) rp.setLabelsAreBillboarded(True) v.setRenderingParameters(rp) return True # The line below does the magic to register the plugin into the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup( "H3LayoutHelper", "H3 Layout Helper", "Antoine Lambert", "01/09/2017", """ Enables to easily configure a H3 layout visualisation for a connected quasi-hierarchical graph. As this is a 3d layout, some rendering setup has to done after the algorithm execution in order to get an aesthetic rendering of it in Tulip. That plugin takes care of calling the H3 layout algorithm, setting node shapes as sphere, setting edge extremity shapes to cone and set appropriate rendering parameters for 3d layout visualization. """, "1.0", "Misc")
rootPackageJson = '%s/package.json' % npmPackageDir if not os.path.exists(rootPackageJson): if self.pluginProgress: self.pluginProgress.setError( ('Error : directory %s does not seem to contain a ' 'npm package.') % npmPackageDir) return False # parse package dependencies graph parsePackageJsonForDependenciesGraph(npmPackageDir, self.graph) # apply a force directed algorithm to draw the graph self.graph.applyLayoutAlgorithm( 'Fast Multipole Multilevel Embedder (OGDF)') return True pluginDoc = """ Import the packages dependencies graph from a npm package. Be sure to have called 'npm install' in the package directory first in order to get the complete dependencies graph. """ # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup('NpmPackageDependenciesGraphImport', 'Npm package dependencies graph', 'Antoine Lambert', '26/11/2015', pluginDoc, '1.0', 'Software')
if not self.isPathwayRelevant(pathway) ] for pathway in toDelete: self.graph.delSubGraph(pathway) def isPathwayRelevant(self, pathway): for locus in pathway.getNodes(): if self.graph.isElement(locus): if self.chromosome[locus] and self.expression[locus] in ( 'up', 'down'): return True return False def styleGraph(self): self.applyLayout() self.setLociSize() def applyLayout(self): fm3Properties = tlp.getDefaultPluginParameters('FM^3 (OGDF)', graph=None) self.graph.applyLayoutAlgorithm('FM^3 (OGDF)', self.viewLayout, fm3Properties) def setLociSize(self): self.viewSize.setAllNodeValue(tlp.Vec3f(1e4, 1e4, 0.5)) tulipplugins.registerPluginOfGroup("FilterInteractionsAndLocus", "Filter interactions and locus", "AM2E", "29/01/2020", "", "1.0", "AM2E")
def run(self): # get parameters weight = self.dataSet["weight"] # init result self.result.setAllEdgeValue(False) # sort edge in increasing order of weight edges = [] for e in self.graph.getEdges(): edges.append([e, weight.getEdgeMax() - weight[e]]) edges.sort(key=lambda ed: ed[1]) # init Union-Find data structure uf = unionfind.UnionFind() for ed in edges: e = ed[0] if uf[self.graph.source(e)] != uf[self.graph.target(e)]: uf.union(self.graph.source(e), self.graph.target(e)) self.result[e] = True return True ###################################################################### # The line below does the magic to register the plugin into the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("MinimumSpanningTree", "Minimum Spanning Tree", "Francois Queyroi", "04/12/2017", "Compute a Minimum Spanning Tree", "1.0", "selection")
def fileExtensions(self): return ['graphml'] def importGraph(self): # create an XML Sax parser parser = xml.sax.make_parser() # set our custom content handler parser.setContentHandler(TulipGraphMLHandler(self.graph)) # parse the GraphML file parser.parse(open(self.dataSet['filename'], 'rb')) return True pluginDoc = """ <p>Supported extension: graphml</p><p>Imports a graph from a file in the GraphML format (<a href=\"http://graphml.graphdrawing.org/">http://graphml.graphdrawing.org</a>). GraphML is a comprehensive and easy-to-use file format for graphs. It consists of a language core to describe the structural properties of a graph and a flexible extension mechanism to add application-specific data.</p> """ # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup('GraphMLImport', 'GraphML', 'Antoine Lambert', '14/05/2017', pluginDoc, '1.0', 'File')
cmakeProjectDotFilePath = tmpdir + '/' + cmakeProjectDotFileName + '.dot' if not os.path.exists(cmakeProjectDotFilePath): if self.pluginProgress: self.pluginProgress.setError("Error : the graphviz file has not been generated by CMake") # remove temporary directory shutil.rmtree(tmpdir) return False # import the dot file in Tulip trough the graphviz import plugin dotImportParams = tlp.getDefaultPluginParameters("graphviz", self.graph) dotImportParams['filename'] = cmakeProjectDotFilePath tlp.importGraph("graphviz", dotImportParams, self.graph) # set some visual attributes to the imported graph self.graph['viewSize'].setAllNodeValue(tlp.Size(1,1,1)) self.graph['viewShape'].setAllNodeValue(tlp.NodeShape.Circle) # apply a force directed algorithm to draw the graph self.graph.applyLayoutAlgorithm('Fast Multipole Multilevel Embedder (OGDF)') # remove temporary directory shutil.rmtree(tmpdir) # done return True # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("CMakeDependenciesGraphImport", "CMake dependencies graph", "Antoine Lambert", "24/11/2015", \ "Import the targets dependencies graph of a CMake project", "1.0", "Software")
return (True, "Ok") def run(self): result = self.dataSet['result'] lambdaProperty = float(self.dataSet['lambda']) centralities = self.calculateCentrality(self.graph, lambdaProperty) for node in self.graph.getNodes(): result[node] = centralities[node] return True def calculateCentrality(self, V, l): """Calculates the eigenvector centrality on the Tulip graph `V` based on the required lambda constant, given by `l`.""" # TODO Calculate the real eigenvector centrality for each node ds = { v: V.deg(v) for v in V.getNodes() } ec = { v: sum(map(lambda w: ds[w], V.getInOutNodes(v))) for v in V.getNodes() } return ec # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup( "EigencentralityAlgorithm", "Eigenvector Centrality", "Cristiano Silva Jr. <*****@*****.**>", "30/01/2018", "No info yet.", "0.2", "Python")
for n in self.graph.getNodes(): self.result[n] = tlp.Coord(tree.nodes[n].coord.x, tree.nodes[n].coord.y, tree.nodes[n].coord.z) # apply some scaling factor to the layout to get a correct rendering # in Tulip scaling = 1000 if self.dataSet: scaling = self.dataSet["layout scaling"] self.result.scale(tlp.Vec3f(scaling)) # cleanup computed spanning tree tlp.TreeTest.cleanComputedTree(self.graph, spanningTree) return True # The line below does the magic to register the plugin into the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup( "H3Layout", "H3", "Antoine Lambert", "30/08/2017", """ Implements the H3 layout technique for drawing large directed graphs as node-link diagrams in 3D hyperbolic space. That algorithm can lay out much larger structures than can be handled using traditional techniques for drawing general graphs because it assumes a hierarchical nature of the data. It was first published as: <b> H3: Laying out Large Directed Graphs in 3D Hyperbolic Space </b>. Tamara Munzner. Proceedings of the 1997 IEEE Symposium on Information Visualization, Phoenix, AZ, pp 2-10, 1997. The implementation in Python (MIT License) has been written by BuzzFeed (https://github.com/buzzfeed/pyh3). """, "1.0", "Hierarchical")
# and can be accessed through the "dataSet" class attribute # (see documentation of class tlp.DataSet). # The method must return a boolean indicating if the # graph has been successfully imported. # Check that we are using at least Tulip 4.8 if not tulipPluginUtils.tulipVersionCheck(4, 8, 0, self.pluginProgress): return False npmPackageDir = self.dataSet[npmPackageDirParamName] # Check if the directory contains a npm package first rootPackageJson = npmPackageDir + '/package.json' if not os.path.exists(rootPackageJson): if self.pluginProgress: self.pluginProgress.setError('Error : directory ' + npmPackageDir + ' does not seem to contain a npm package.') return False # parse package depedencies graph parsePackageJsonForDependenciesGraph(npmPackageDir, self.graph) # apply a force directed algorithm to draw the graph self.graph.applyLayoutAlgorithm('Fast Multipole Multilevel Embedder (OGDF)') return True # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("NpmPackageDependenciesGraphImport", "Npm package dependencies graph", "Antoine Lambert", "26/11/2015",\ "Import the packages dependencies graph from a npm package", "1.0", "Misc")
# the "graph" class attribute (see documentation of class tlp.Graph). # The parameters provided by the user are stored in a Tulip DataSet # and can be accessed through the "dataSet" class attribute # (see documentation of class tlp.DataSet). # The method must return a boolean indicating if the algorithm # has been successfully applied on the input graph. # edge_weight = self.graph.getDoubleProperty('edge_weight') edge_weight = self.dataSet['(Optional) Edge weight property'] to_delete = [] for n in self.graph.getNodes(): neighbors = [e for e in self.graph.getInEdges(n)] source_set = set([self.graph.source(ee) for ee in neighbors]) for nn in source_set: filtered_ee = filter(lambda x: self.graph.source(x).id == nn.id, neighbors) if self.dataSet['Aggregation mode'] == 'Uniform unit weight': nb_ee = len(filtered_ee) else: nb_ee = sum([edge_weight[e] for e in neighbors]) for ee in filtered_ee: to_delete.append(ee) eee = self.graph.addEdge(nn, n) edge_weight[eee] = nb_ee self.graph.delEdges(to_delete) return True # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("MakeSimpleCount", "Make Simple with edge multiplicity", "Guy Melancon", "12/12/2017", "", "1.0", "Topology Update")
self.graph.setAttribute(attrName, content) class GraphMLImport(tlp.ImportModule): def __init__(self, context): tlp.ImportModule.__init__(self, context) self.addFileParameter("filename", True, "the GraphML file to import") def fileExtensions(self): return ["graphml"] def importGraph(self): # create an XML Sax parser parser = xml.sax.make_parser() # set our custom content handler parser.setContentHandler(TulipGraphMLHandler(self.graph)) # parse the GraphML file parser.parse(open(self.dataSet["filename"], "rb")) return True # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("GraphMLImport", "GraphML", "Antoine Lambert", "14/05/2017", """ <p>Supported extension: graphml</p><p>Imports a graph from a file in the GraphML format (http://graphml.graphdrawing.org/). GraphML is a comprehensive and easy-to-use file format for graphs. It consists of a language core to describe the structural properties of a graph and a flexible extension mechanism to add application-specific data.</p> """, "1.0", "File")
if self.dataSet["Entity type"][n] == self.dataSet["Substrates (projected entities)"] ] self.substrate_graph = self.graph.addSubGraph() for s in self.substrates: self.substrate_graph.addNode(s) self.substrate_graph.setName( self.dataSet['Substrates (projected entities)'] + '_graph_' + self.dataSet['Weighting scheme']) self.edge_weight = self.substrate_graph.getDoubleProperty( 'edge_weight') if self.dataSet['Weighting scheme'] == 'Giatsidis': self.weight_function = self.Giatsidis_weight_function elif self.dataSet['Weighting scheme'] == 'Clique': self.weight_function = self.clique_weight_function else: # self.dataSet['Weighting scheme'] == 'Uniform 1.0' self.weight_function = self.uniform_weight self.project() if self.dataSet['Build k-cores']: self.compute_cores() return True # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("OneModeProjection", "One-Mode Projection", "Guy Melancon", "24/05/2016", "", "1.0", "Two_mode_Networks")
return False graph = self.graph graphMLFile = self.dataSet["file::filename"] nx_graph = None try: nx_graph = tulipnx.nx.read_graphml(graphMLFile) except: pass if nx_graph: tulipnx.nxGraphToTlpGraph(nx_graph, graph) return True else: if self.pluginProgress: self.pluginProgress.setError("An error occurred when trying to import the GraphML file") return False # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("NxGraphMLImport", "GraphML Import (NetworkX)", "", "15/12/2015", """ Imports a graph from a file in the GraphML format. GraphML is a comprehensive and easy-to-use file format for graphs. It consists of a language core to describe the structural properties of a graph and a flexible extension mechanism to add application-specific data. """, "1.0", "File")
return elist # @Deprecated def applyFilter(self, node, min, max, niv, visited, pStart): if node in visited or niv > max: return list() visited.append(node) neighs = self.graph.getInOutNodes(node) res_list = list() if niv < max: for n in neighs: l = self.applyFilter(n, min, max, (niv+1), visited, pStart) if not l == []: res_list += l e = self.graph.existEdge(node, n, False) res_list.append(e) if niv >= min and niv <= max: for n in neighs: for p in self.p_list: if not p == pStart and n == p: e = self.graph.existEdge(node, n, False) res_list.append(e) return res_list # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("HideUnrelated", "VisuDNA - Select Related", "SB", "13/12/2017", "info", "1.0", "Python")
# Populate data structures if link not in times: times[link] = [] times[link].append(t) if u not in nodes: nodes[u] = set() if v not in nodes: nodes[v] = set() nodes[u].add(v) nodes[v].add(u) nb_lines = nb_lines + 1 Cm._times = times Cm._nodes = nodes tmp_std_err = sys.stderr sys.stderr = NullDevice() results = Cm.getDeltaCliques(self.delta) sys.stderr = tmp_std_err self.mapCliquesBack(results) return True # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("DeltaCliques", "Delta Cliques", "Benjamin Renoust & Jordan Viard", "18/06/2015", "Computes the delta cliques in a link stream", "1.0", "Link Stream")
def importGraph(self): npmPackageDir = self.dataSet[npmPackageDirParamName] # Check if the directory contains a npm package first rootPackageJson = npmPackageDir + '/package.json' if not os.path.exists(rootPackageJson): if self.pluginProgress: self.pluginProgress.setError( 'Error : directory ' + npmPackageDir + ' does not seem to contain a npm package.') return False # parse package depedencies graph parsePackageJsonForDependenciesGraph(npmPackageDir, self.graph) # apply a force directed algorithm to draw the graph self.graph.applyLayoutAlgorithm( 'Fast Multipole Multilevel Embedder (OGDF)') return True # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("NpmPackageDependenciesGraphImport", "Npm package dependencies graph", "Antoine Lambert", "26/11/2015",\ """ Import the packages dependencies graph from a npm package. Be sure to have called 'npm install' in the package directory first in order to get the complete dependencies graph. """, "1.0", "Software")
# The parameters provided by the user are stored in a Tulip DataSet # and can be accessed through the "dataSet" class attribute # (see documentation of class tlp.DataSet). # The method must return a boolean indicating if the # graph has been successfully imported. if not tulipnx.checkNetworkX(self.pluginProgress): return False graph = self.graph n = self.dataSet["n"] m = self.dataSet["m"] p = self.dataSet["p"] bp_graph = tulipnx.bipartite_random_graph(n, m, p) tulipnx.nxGraphToTlpGraph(bp_graph, graph) return True # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("NxRandomBipartiteGraph", "Random Bipartite Graph (NetworkX)", "Antoine Lambert", "09/12/2015", """ Imports a bipartite random graph. This is a bipartite version of the binomial (Erdos-Renyi) graph. """, "1.0", "Graph")
while clone.numberOfNodes() > 0: self.pluginProgress.progress( self.graph.numberOfNodes() - clone.numberOfNodes(), self.graph.numberOfNodes()) clone.applyDoubleAlgorithm("K-Cores", cores, self.dataSet) d = cores.getNodeMax() for v in clone.getNodes(): if cores[v] == d: self.result[v] = d clone.delNode(v) self.graph.delAllSubGraphs(clone) ## compute core dependancy self.pluginProgress.setComment("Computing Core Dependency...") base_cores = tlp.DoubleProperty(self.graph) self.graph.applyDoubleAlgorithm("K-Cores", base_cores, self.dataSet) core_dep = 0. for n in self.graph.getNodes(): if base_cores[n] > 0: core_dep += (base_cores[n] - self.result[n]) / base_cores[n] core_dep /= self.graph.numberOfNodes() + 0. self.dataSet["Core Dependency"] = core_dep return True ######################################################################################################### tulipplugins.registerPluginOfGroup( "KPeaks", "K-Peaks", "François Queyroi", "21/03/2019", "Compute the k-peak decomposition of the networks. See</br> J. Abello and F. Queyroi.<br/><b>Network decomposition into fixed points of degree peeling.</b><br/>Social Network Analysis and Mining, 2014, vol. 4, no 1, p. 191. (2014)", "1.0", "Measure")
parameters_value[boolean_vec_prop_param_name] = self.dataSet[boolean_vec_prop_param_name] parameters_value[color_vec_prop_param_name] = self.dataSet[color_vec_prop_param_name] parameters_value[double_vec_prop_param_name] = self.dataSet[double_vec_prop_param_name] parameters_value[int_vec_prop_param_name] = self.dataSet[int_vec_prop_param_name] parameters_value[coord_vec_prop_param_name] = self.dataSet[coord_vec_prop_param_name] parameters_value[size_vec_prop_param_name] = self.dataSet[size_vec_prop_param_name] parameters_value[string_vec_prop_param_name] = self.dataSet[string_vec_prop_param_name] self.dataSet[out_boolean_param_name] = out_boolean_param_value self.dataSet[out_int_param_name] = out_int_param_value self.dataSet[out_float_param_name] = out_float_param_value self.dataSet[out_string_param_name] = out_string_param_value return True tulipplugins.registerPluginOfGroup('TestAlgorithm', plugin_name, plugin_author, plugin_date, plugin_info, plugin_version, plugin_group) class TestPluginParameters(unittest.TestCase): def setUp(self): self.graph = tlp.newGraph() self.boolean_prop = self.graph.getBooleanProperty(boolean_prop_param_value) self.color_prop = self.graph.getColorProperty(color_prop_param_value) self.double_prop = self.graph.getDoubleProperty(double_prop_param_value) self.int_prop = self.graph.getIntegerProperty(int_prop_param_value) self.layout_prop = self.graph.getLayoutProperty(layout_prop_param_value) self.size_prop = self.graph.getSizeProperty(size_prop_param_value) self.string_prop = self.graph.getStringProperty(string_prop_param_value) self.boolean_vec_prop = self.graph.getBooleanVectorProperty(boolean_vec_prop_param_default_value) self.color_vec_prop = self.graph.getColorVectorProperty(color_vec_prop_param_default_value) self.double_vec_prop = self.graph.getDoubleVectorProperty(double_vec_prop_param_default_value)
for n in self.graph.getNodes(): w = self.graph['viewSize'][n][0] h = self.graph['viewSize'][n][1] s = min(w, h) self.graph['viewSize'][n] = tlp.Size(s) if tulipGuiOk: for v in tlpgui.getViewsOfGraph(self.graph): if isinstance(v, tlpgui.NodeLinkDiagramComponent): rp = v.getRenderingParameters() rp.setEdge3D(True) rp.setViewArrow(True) rp.setLabelsAreBillboarded(True) v.setRenderingParameters(rp) return True # The line below does the magic to register the plugin into the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("H3LayoutHelper", "H3 Layout Helper", "Antoine Lambert", "01/09/2017", """ Enables to easily configure a H3 layout visualisation for a connected quasi-hierarchical graph. As this is a 3d layout, some rendering setup has to be done after the algorithm execution in order to get an aesthetic rendering of it in Tulip. That plugin takes care of calling the H3 layout algorithm, setting node shapes as sphere, setting edge extremity shapes to cone and set appropriate rendering parameters for 3d layout visualization. """ , "1.0", "Misc")
coord_vec_prop_param_name] parameters_value[size_vec_prop_param_name] = self.dataSet[ size_vec_prop_param_name] parameters_value[string_vec_prop_param_name] = self.dataSet[ string_vec_prop_param_name] self.dataSet[out_boolean_param_name] = out_boolean_param_value self.dataSet[out_int_param_name] = out_int_param_value self.dataSet[out_float_param_name] = out_float_param_value self.dataSet[out_string_param_name] = out_string_param_value return True tulipplugins.registerPluginOfGroup('TestAlgorithm', plugin_name, plugin_author, plugin_date, plugin_info, plugin_version, plugin_group) class TestPluginParameters(unittest.TestCase): def setUp(self): self.graph = tlp.newGraph() self.boolean_prop = self.graph.getBooleanProperty( boolean_prop_param_value) self.color_prop = self.graph.getColorProperty(color_prop_param_value) self.double_prop = self.graph.getDoubleProperty( double_prop_param_value) self.int_prop = self.graph.getIntegerProperty(int_prop_param_value) self.layout_prop = self.graph.getLayoutProperty( layout_prop_param_value) self.size_prop = self.graph.getSizeProperty(size_prop_param_value)
# and can be accessed through the "dataSet" class attribute # (see documentation of class tlp.DataSet). # The method must return a boolean indicating if the algorithm # has been successfully applied on the input graph. self.two_mode_graph = self.graph.getSubGraph('Two_mode_graph') if self.two_mode_graph == None: self.two_mode_graph = self.graph.addCloneSubGraph('Two_mode_graph') self.substrates = [n for n in self.two_mode_graph.getNodes() if self.dataSet["Entity type"][n] == self.dataSet["Substrates (projected entities)"]] self.substrate_graph = self.graph.addSubGraph() for s in self.substrates: self.substrate_graph.addNode(s) self.substrate_graph.setName(self.dataSet['Substrates (projected entities)'] + '_graph_' + self.dataSet['Weighting scheme']) self.edge_weight = self.substrate_graph.getDoubleProperty('edge_weight') if self.dataSet['Weighting scheme'] == 'Giatsidis': self.weight_function = self.Giatsidis_weight_function elif self.dataSet['Weighting scheme'] == 'Clique': self.weight_function = self.clique_weight_function else: # self.dataSet['Weighting scheme'] == 'Uniform 1.0' self.weight_function = self.uniform_weight self.project() if self.dataSet['Build k-cores']: self.compute_cores() return True # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("OneModeProjection", "One-Mode Projection", "Guy Melancon", "24/05/2016", "", "1.0", "Two_mode_Networks")
final_clust.resizeNodeValue(n, 0) set_clust = set() for lab in prop_memb[n]: set_clust.add(mapLabClust[lab]) for sc in set_clust: final_clust.pushBackNodeEltValue(n, sc) if self.create_sg: mapLabNodes = {} for n in self.graph.getNodes(): for lab in prop_memb[n]: if mapLabClust[lab] not in mapLabNodes.keys(): mapLabNodes[mapLabClust[lab]] = [] mapLabNodes[mapLabClust[lab]].append(n) for lab, cc in mapLabNodes.items(): sgg = self.graph.inducedSubGraph(cc) sgg.setName("Cluster_" + str(lab)) ## Delete temp variables self.graph.delLocalProperty("clique_memb") return True ################################################################################################################### # The line below does the magic to register the plugin into the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("CliquePercolation", "Clique Percolation", "François Queyroi", "07/03/2019", "Clique Percolation Algorithm", "1.0", "Clustering")
# get parameters from layout algorithm FM^3 params = tlp.getDefaultPluginParameters("FM^3 (OGDF)", self.graph) # get a reference to the default layout property viewLayout = self.graph.getLayoutProperty("viewLayout") # call the layout algorithm and store the result in viewLayout self.graph.applyLayoutAlgorithm("FM^3 (OGDF)", viewLayout, params) self.graph.applyAlgorithm("Edge bundling") viewShape = self.graph.getIntegerProperty("viewShape") viewShape.setAllEdgeValue(tlp.EdgeShape.BezierCurve) viewColor = self.graph.getColorProperty('viewColor') viewColor.setAllEdgeValue(tlp.Color(163, 163, 163, 70)) # create the name of your graph in tulip self.graph.setName(self.dataSet['Query']) return True # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup( "Import_graph", "QueryDrawer", "Antoine Lambert, modifié par Jean-Clément GALLARDO et Eliot RAGUENEAU", "11/05/2019", """ <p>Supported extension: graphml</p><p>Imports a graph from a file in the GraphML format (http://graphml.graphdrawing.org/). GraphML is a comprehensive and easy-to-use file format for graphs. It consists of a language core to describe the structural properties of a graph and a flexible extension mechanism to add application-specific data.</p> """, "1.0", "File")
bg=bg_color, cursor="hand2", highlightthickness=0, bd=0, activebackground=bg_color) add_button.pack(pady=5) # Send button to finish program execution send_btn = tk.Button(root, text="Draw", command=Method.draw, cursor="hand2") send_btn.pack(side=tk.BOTTOM) # Add the first method Method.new_method() # Begin the GUI root.mainloop() return True # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup( "AnalysisComparator", "Analysis comparator", "Eliot Ragueneau et Jean Clément Gallardo", "11/05/2019", "Compare analysis methods of transcriptomics by drawing parallels regulation graphs", "1.0", "Algorithm")
return False # import the dot file in Tulip trough the graphviz import plugin dotImportParams = tlp.getDefaultPluginParameters( 'graphviz', self.graph) dotImportParams['filename'] = cmakeProjectDotFilePath tlp.importGraph("graphviz", dotImportParams, self.graph) # set some visual attributes to the imported graph self.graph['viewSize'].setAllNodeValue((1, 1, 1)) self.graph['viewShape'].setAllNodeValue(tlp.NodeShape.Circle) # apply a force directed algorithm to draw the graph self.graph.applyLayoutAlgorithm( 'Fast Multipole Multilevel Embedder (OGDF)') # remove temporary directory shutil.rmtree(tmpdir) # done return True # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup( 'CMakeDependenciesGraphImport', 'CMake dependencies graph', 'Antoine Lambert', '24/11/2015', "Import the targets dependencies graph of a CMake project", '1.0', 'Software')
self.graph.delNode(n) ############################################################################################# def importGraph(self): moves_filename = self.dataSet['moves filepath'] ports_filename = self.dataSet['ports filepath'] self.keep_all_moves = self.dataSet['keep all moves?'] self.keep_all_ports = self.dataSet['keep all ports?'] self.min_date = self.dataSet['min date'] self.max_date = self.dataSet['max date'] self.net_type = self.dataSet['Type'] self.min_freq = self.dataSet['min freq'] self.pluginProgress.progress(0, 1) self.pluginProgress.setComment("Reading ports info...") [portsNodes, excluded_ports] = self.readPorts(ports_filename) self.pluginProgress.progress(1, 1) self.readMoves(moves_filename, portsNodes, excluded_ports) self.graph.setName("Llyods_"+self.net_type+"("+str(int(self.min_date))+":"+str(int(self.max_date))+")") if self.min_freq > 0: self.pluginProgress.setComment("Filtering ports"); self.filterFreq() self.computeStats() self.correctDurationEdge() return True ############################################################################################# tulipplugins.registerPluginOfGroup("TVGLlyodsImport", "TVG Llyods Import", "Francois Queyroi", "17/03/2019", "", "1.0", "Python")
value = float(value - self.minElements[c]) / (self.maxElements[c] - self.minElements[c]) else: value = 0.0 color = self.getColorAtPos(value) self.graph['viewColor'][node] = color #Returns the color for a given position in the color scale. This method computes the color associated to a specific position in the color scale and returns it. def getColorAtPos(self, pos): theColor = None minDist = 1.0 for value, color in self.colorScale.iteritems(): newDist = abs(pos - value) if newDist < minDist: theColor = color minDist = newDist return theColor # The line below does the magic to register the plugin to the plugin database # and updates the GUI to make it accessible through the menus. tulipplugins.registerPluginOfGroup("CircleSegmentsPlugin", "Circle Segments", "Nicolas Chabalier", "18/06/2017", "infos", "1.0", "Python")