用pygexf生成一个简单的gexf文件格式的文件

首先需要下载gexf包,但是这个包比较古老,如果不换源的话直接conda或者pip安装是行不通的的,因此执行下面这个命令安装pygexf

pip install pygexf -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

执行了这步,在python模式下输入

import gexf

在这里插入图片描述
像我这样没有报错就是对的,然而只要你用的是python3肯定会报错,所以需要做一些改动

  • 打开python下site-packages 文件夹,找到gexf文件夹,对文件夹内的程序进行修改。
  • 我去原作者github逛了一圈,发现有对应python3的更新程序,因此把__init__.py和_gexf.py改一下就ok了。下图是在我电脑里两个程序的位置。你要是用的ananconda搭建的深度学习环境照猫画虎应该能找到,其他情况我就不赘述了,可以参考这个.在这里插入图片描述
  • 把__init__.py改为:
from ._gexf import Gexf
from ._gexf import Node
from ._gexf import Edge
from ._gexf import Graph
from ._gexf import GexfImport
  • _gexf.py改为:
# -*- coding: utf-8 -*-

#
#     Gexf library in python
#     see gephi.org and gexf.net
#
#     repository : http://github.com/paulgirard/pygexf
#     documentation : http://packages.python.org/pygexf
#
#     main developper : Paul Girard, médialab Sciences Po
#     licence : GPL v3
#

from lxml import etree
from datetime import date
import itertools
import traceback

 # missing features :
 # data validation regarding attribute types
 # phylogeny


 # evolution ideas :
 # add display stats on graph composition when exportingto xml
 # add anti-paralell edges test

def msg_unexpected_tag(expected, got):
    print("Error : incorrect xml. Expected tag {expected}, not {got}.".format(expected=expected, got=got))


def ns_clean(token):
    i = token.find('}')
    return token[i + 1:]


class Gexf:

    def __init__(self, creator, description):
        self.creator = creator
        self.description = description
        self.graphs = []
        self.xmlns = "http://www.gephi.org/gexf/1.2draft"
        self.xsi = "http://www.w3.org/2001/XMLSchema-instance"
        self.schemaLocation = "http://www.gephi.org/gexf/1.1draft http://gephi.org/gexf/1.2draft.xsd"
        self.viz = "http://www.gexf.net/1.2draft/viz"
        self.version = "1.2"

    def addGraph(self, type, mode, label, timeformat=""):
        g = Graph(type, mode, label, timeformat)
        self.graphs.append(g)
        return g

    def getXML(self):
        gexfXML = etree.Element("{" + self.xmlns + "}gexf", version=self.version, nsmap={None: self.xmlns, 'viz': self.viz, 'xsi': self.xsi})
        #         gexfXML.set("xmlnsxsi",)
        gexfXML.set("{xsi}schemaLocation", self.schemaLocation)
        meta = etree.SubElement(gexfXML, "meta")
        meta.set("lastmodified", date.today().isoformat())
        etree.SubElement(meta, "creator").text = self.creator
        etree.SubElement(meta, "description").text = self.description
        for graph in self.graphs:
            gexfXML.append(graph.getXML())

        return gexfXML

    def write(self, file, print_stat=True):
        file.write(etree.tostring(self.getXML(), pretty_print=True, encoding='utf-8', xml_declaration=True))
        if print_stat is True:
            self.print_stat()

    def print_stat(self):
        for graph in self.graphs:
            graph.print_stat()

    @staticmethod
    def importXML(gexf_file):
        """ import gexf xml meta tags to create a Gexf Object and delegate Graph extraction to Graph class"""
        # parse the gexf file
        parser = etree.XMLParser(ns_clean=True)
        tree = etree.parse((gexf_file), parser)
        # start create Gexf Object
        gexf_xml = tree.getroot()
        tag = ns_clean(gexf_xml.tag).lower()
        if tag != "gexf":
            msg_unexpected_tag("gexf", tag)
            return
        gexf_obj = None
        for child in gexf_xml:
            tag = ns_clean(child.tag).lower()
            # create a gexf object by importing meta tag
            if tag == "meta":
                meta_xml = child
                for child in meta_xml:
                    tag = ns_clean(child.tag).lower()
                    if tag == "creator":
                        creator = child.text
                    if tag == "description":
                        description = child.text
                gexf_obj = Gexf(creator=creator, description=description)
            # export graph xml through Graph Class
            if tag == "graph":
                graph_xml = child
                if gexf_obj is None:
                    msg_unexpected_tag("meta", tag)
                    return
                Graph.importXML(graph_xml, gexf_obj)
        return gexf_obj


class Graph:

    def __init__(self, type, mode, label, time_format="double", start="", end=""):

        # control variable
        self.authorizedType = ("directed", "undirected")
        self.authorizedMode = ("dynamic", "static")
        # time format
        # Discrete: integer or double
        # Continuous : date (yyyy-mm-dd) or dateTime
        # default : double
        self.authorizedTimeFormat = ("integer", "double", "date", "dateTime")

        self.defaultTimeFormat = "double"
        self.defaultType = "directed"
        self.defaultMode = "static"

        self.label = label

        if type in self.authorizedType:
            self.type = type
        else:
            self.type = self.defaultType
        if mode in self.authorizedMode:
            self.mode = mode
        else:
            self.mode = self.defaultMode

        if time_format in self.authorizedTimeFormat:
            self.time_format = time_format
        else:
            self.time_format = self.defaultTimeFormat

        self.start = start
        self.end = end

        self._attributes = Attributes()
        self.attributes = self._attributes
        self._nodes = {}
        self.nodes = self._nodes
        self._edges = {}
        self.edges = self._edges

    def addNode(self, id, label, start="", end="", startopen=False, endopen=False, pid="", r="", g="", b="", spells=[]):
        self._nodes[str(id)] = Node(self, id, label, start, end, pid, r, g, b, spells, startopen, endopen)
        return self._nodes[str(id)]

    def nodeExists(self, id):
        if id in self._nodes.keys():
            return 1
        else:
            return 0

    def addEdge(self, id, source, target, weight="", start="", end="", label="", r="", g="", b="", spells=[], startopen=False, endopen=False):
        self._edges[str(id)] = Edge(self, id, source, target, weight, start, end, label, r, g, b, spells, startopen, endopen)
        return self._edges[str(id)]

    def addNodeAttribute(self, title, defaultValue=None, type="integer", mode="static", force_id=""):
        # add to NodeAttributes
        return self._attributes.declareAttribute("node", type, defaultValue, title, mode, force_id)

    def addDefaultAttributesToNode(self, node):
        """ deprecated """
        pass

    def checkNodeAttribute(self, id, value, start, end):
        """deprecated"""
        pass
        # check conformity with type is missing
        #  if id in self._nodesAttributes.keys() :
        #             if self._nodesAttributes[id]["mode"]=="static" and ( not start=="" or not end=="") :
        #                 raise Exception("attribute "+str(id)+" is static you can't specify start or end dates. Declare Attribute as dynamic")
        #             return 1
        #         else :
        #             raise Exception("attribute id unknown. Add Attribute to graph first")

    def addEdgeAttribute(self, title, defaultValue, type="integer", mode="static", force_id=""):
        return self._attributes.declareAttribute("edge", type, defaultValue, title, mode, force_id)

    def addDefaultAttributesToEdge(self, edge):
        """ deprecated """
        pass

    def checkEdgeAttribute(self, id, value, start, end):
        """deprecated """
        pass
#         # check conformity with type is missing
#         if id in self._edgesAttributes.keys() :
#             if self._edgesAttributes[id]["mode"]=="static" and ( not start=="" or not end=="") :
#                 raise Exception("attribute "+str(id)+" is static you can't specify start or end dates. Declare Attribute as dynamic")
#             return 1
#         else :
#             raise Exception("attribute id unknown. Add Attribute to graph first")

    def getXML(self):
        # return lxml etree element
        graphXML = etree.Element("graph", defaultedgetype=self.type, mode=self.mode, label=self.label, timeformat=self.time_format)

        for attributesElement in self.attributes.getAttributesDeclarationXML():
            graphXML.append(attributesElement)

        nodesXML = etree.SubElement(graphXML, "nodes")
        node_ids = list(self._nodes.keys())
        node_ids.sort()
        for id in node_ids:
            nodesXML.append(self._nodes[id].getXML())

        edgesXML = etree.SubElement(graphXML, "edges")
        edge_ids = list(self._edges.keys())
        edge_ids.sort()
        for id in edge_ids:
            edgesXML.append(self._edges[id].getXML())

        return graphXML

    @staticmethod
    def importXML(graph_xml, gexf_obj):
        """ import graph xml tag to create a Graph Object and delegate Node/Edges extraction to Edge/Node class"""
        # get Graph attributes
        type = ""
        mode = ""
        label = ""
        timeformat = "double"
        for attr in graph_xml.attrib:
            attr = attr.lower()
            if attr == "defaultedgetype":
                type = graph_xml.attrib[attr]
            if attr == "mode":
                mode = graph_xml.attrib[attr]
            if attr == "label":
                label = graph_xml.attrib[attr]
            if attr == "timeformat":
                timeformat = graph_xml.attrib[attr]
        # create and attache the graph object to the Gexf object
        graph_obj = gexf_obj.addGraph(type=type, mode=mode, label=label, timeformat=timeformat)

        for child in graph_xml:
            tag = ns_clean(child.tag).lower()

            if tag == "attributes":
                attributes_xml = child
                # Delegate Attributes declaration to the attribute object
                graph_obj.attributes.importAttributesXML(attributes_xml)

            if tag == "nodes":
                nodes_xml = child
                # Delegate nodes creation to the Node class
                Node.importXML(nodes_xml, graph_obj)
            if tag == "edges":
                edges_xml = child
                # Delegate edges creation to the Edge class
                Edge.importXML(edges_xml, graph_obj)

    def print_stat(self):
        print(self.label + " " + self.type + " " + self.mode + " " + self.start + " " + self.end)
        print("number of nodes : " + str(len(self._nodes)))
        print("number of edges : " + str(len(self._edges)))


class Attributes(dict):
    """
        attributes=
        {
         "node" :
            { "id1" : {"id":"id1","title":"age","type":"integer","defaultValue":50,"mode":"static"}, },
         "edge" :
            { "id2" : {"id":"id2","title":"relationship","type":"string","defaultValue":"friend",mode:"dynamic"}, },
        }
    """

    def __init__(self):
        self.type_choices = ["integer", "string", "float", "double", "boolean", "date", "URI"]
        self.attClass_choices = ["node", "edge"]
        self.mode_choices = ["static", "dynamic"]
        for attClass in self.attClass_choices:
            self[attClass] = {}

    def declareAttribute(self, attClass, type, defaultValue, title="", mode="static", id=None):
        """
            add a new attribute declaration to the graph
        """
        if attClass in self.attClass_choices:
            # should add quality control here on type and defaultValue
            # if no id given generating a numerical one based on dict length
            if not id:
                id = str(len(self[attClass]))
            self[attClass][id] = {"id": id, "type": type, "defaultValue": defaultValue, "mode": mode, "title": title}
            return id
        else:
            raise Exception("wrong attClass : " + str(attClass) + " Should be in " + str(type_choices))

    def makeAttributeInstance(self, attClass, id=None, value=None, start=None, end=None, startopen=False, endopen=False):
        """
           generate an attribute to be include to a node or edge.
           copied from the declared attributes, thus any attribute has to be declared first 
        """
        if attClass in self.attClass_choices:
            if id in self[attClass].keys():
                att = {"id": id}
                att["value"] = value if value else self[attClass][id]["defaultValue"]
                if self[attClass][id]["mode"] == "dynamic" and start or end:
                # start & end will be discarded if the mode is set to static
                    if start:
                        att["start"] = start
                    if startopen:
                        att["startopen"] = startopen
                    if end:
                        att["end"] = end
                    if endopen:
                        att["endopen"] = endopen
                return att
            else:
                raise Exception("wrong attribute id (%s), declare the attribute first with declareAttribute" % (id, ))
        else:
            raise Exception("wrong attClass : " + str(attClass) + " Should be in " + str(self.type_choices))

    def getAttributesDeclarationXML(self):
        """ generate attributes declaration XML """
        # return lxml etree element
        allAttributesXML = []
        if len(self) > 0:
            # iter on node and then edge atts
            for attClass, atts in self.items():
                # group by mode
                key_mode = lambda att: att["mode"]
                atts_sorted_by_mode = sorted(list(atts.values()), key=key_mode, reverse=True)
                for mode, atts in itertools.groupby(atts_sorted_by_mode, key_mode):
                    # generate on attributes by mode
                    attributesXML = etree.Element("attributes")
                    attributesXML.set("class", attClass)
                    attributesXML.set("mode", mode)
                    # generate attribute by id order
                    for att in sorted(atts, key=lambda att: att["id"]):
                        attributeXML = etree.SubElement(attributesXML, "attribute")
                        attributeXML.set("id", str(att["id"]))
                        attributeXML.set("title", att["title"])
                        attributeXML.set("type", att["type"])
                        if att["defaultValue"]:
                            etree.SubElement(attributeXML, "default").text = att["defaultValue"]
                    allAttributesXML.append(attributesXML)
        return allAttributesXML

    @staticmethod
    def getAttributesXML(atts):
        """ get XML attValues for an element (Node or Edge) by passing an attribute values list (stored in Nodes and Edges)"""
        if len(atts) > 0:
            attValuesXML = etree.Element("attvalues")
            for att in atts:
                attValueXML = etree.SubElement(attValuesXML, "attvalue")
                attValueXML.set("for", str(att["id"]))
                attValueXML.set("value", att["value"])
                if "start" in att.keys() and not att["start"] == "":
                    attValueXML.set("start" if not "startopen" in att.keys() or not att["startopen"] else "startopen", att["start"])
                if "end" in att.keys() and not att["end"] == "":
                    attValueXML.set("end" if not "endopen" in att.keys() or not att["endopen"] else "endopen", att["end"])
            return attValuesXML
        else:
            return None

    def importAttributesXML(self, attributes_xml):
        """ get XML attributes declaration of a graph gexf"""
        attr_class = None
        mode = ""
        for attr in attributes_xml.attrib:
            attr = attr.lower()
            if attr == "class":
                attr_class = attributes_xml.attrib[attr].lower()
            if attr == "mode":
                mode = attributes_xml.attrib[attr]

        for child in attributes_xml:
            tag = ns_clean(child.tag).lower()
            if tag == "attribute":
                attribute_xml = child
                id = ""
                title = ""
                type = ""

                for attr in attribute_xml.attrib:
                    attr = attr.lower()
                    if attr == "id":
                        id = attribute_xml.attrib[attr]
                    if attr == "title":
                        title = attribute_xml.attrib[attr]
                    if attr == "type":
                        type = attribute_xml.attrib[attr]

                default = ""

                for child in attribute_xml:
                    tag = ns_clean(child.tag).lower()
                    if tag == "default":
                        default = child.text

                self.declareAttribute(attr_class, type, default, title, mode, id)

    def importAttributesValuesXML(self, attClass, attvalues_xml):
        """ import attributes values from attvalues gexf xml tag attached to nodes or edges"""
        atts = []
        for attvalues in attvalues_xml:
            for child in attvalues:
                tag = ns_clean(child.tag).lower()
                if tag == "attvalue":
                    attvalue_xml = child
                    id = ""
                    value = ""
                    start = ""
                    startopen = False
                    end = ""
                    endopen = False
                    for attr in attvalue_xml.attrib:
                        if attr == "for":
                            id = attvalue_xml.attrib[attr]
                        if attr == "value":
                            value = attvalue_xml.attrib[attr]
                        if attr == "start":
                            start = attvalue_xml.attrib[attr]
                        if attr == "end":
                            end = attvalue_xml.attrib[attr]
                        if attr == "startopen":
                            start = attvalue_xml.attrib[attr]
                            startopen = True
                        if attr == "endopen":
                            end = attvalue_xml.attrib[attr]
                            endopen = True

                    atts.append(self.makeAttributeInstance(attClass, id, value, start, end, startopen, endopen))
        return atts


class Spells(list):
    '''
    spells are time periods
    spells is a list of dictionaries
    a spell is a dict : {"start":"YYYY-MM-DD","end":"YYYY-MM-DD"}
    '''

    def getXML(self):

        spellsXML = etree.Element("spells")
        for spell in self:
            spellXML = etree.SubElement(spellsXML, "spell")
            if "start" in spell.keys():
                spellXML.set("start", spell["start"])
            if "end" in spell.keys():
                spellXML.set("end", spell["end"])
        return spellsXML

    @staticmethod
    def importXML(spellsxmltree):
        return Spells([spell.attrib for spell in spellsxmltree])


class Node:

    def __init__(self, graph, id, label, start="", end="", pid="", r="", g="", b="", spells=[], startopen=False, endopen=False):
        self.id = id
        self.label = label
        self.start = start
        self.startopen = startopen
        self.end = end
        self.endopen = endopen
        self.pid = pid
        self._graph = graph
        self.setColor(r, g, b)

        #spells expecting format = [{start:"",end:""},...]
        self.spells = spells

        if not self.pid == "":
            if not self._graph.nodeExists(self.pid):
                raise Exception("pid " + self.pid + " node unknown, add nodes to graph first")

        self._attributes = []
        self.attributes = self._attributes
        # add existing nodesattributes default values : bad idea and unecessary
        #self._graph.addDefaultAttributesToNode(self)

    def addAttribute(self, id, value, start="", end="", startopen=False, endopen=False):
        self._attributes.append(self._graph.attributes.makeAttributeInstance("node", id, value, start, end, startopen, endopen))

    def getXML(self):
        # return lxml etree element
        try:
            nodeXML = etree.Element("node", id=str(self.id), label=self.label)
            if not self.start == "":
                nodeXML.set("start" if not self.startopen else "startopen", self.start)
            if not self.end == "":
                nodeXML.set("end" if not self.endopen else "endopen", self.end)
            if not self.pid == "":
                nodeXML.set("pid", self.pid)

            # attributes
            if self._attributes:
                nodeXML.append(Attributes.getAttributesXML(self._attributes))

            # spells
            if self.spells:
                print("found spells in node " + self.id)
                nodeXML.append(self.spells.getXML())


            if not self.r == "" and not self.g == "" and not self.b == "":
                #color : <viz:color r="239" g="173" b="66"/>
                colorXML = etree.SubElement(nodeXML, "{http://www.gexf.net/1.1draft/viz}color")
                colorXML.set("r", self.r)
                colorXML.set("g", self.g)
                colorXML.set("b", self.b)

            return nodeXML
        except Exception as e:
            print(self.label)
            print(self._attributes)
            print(e)
            traceback.print_exc()
            exit()

    def getAttributes(self):
        attsFull = []
        for att in self._attributes:
            attFull = self._graph.attributes["node"][att["id"]].copy()
            attFull.update(att)
            attsFull.append(attFull)
        return attsFull

    @staticmethod
    def importXML(nodes_xml, graph_obj):

        for child in nodes_xml:
            tag = ns_clean(child.tag).lower()
            if tag == "node":
                node_xml = child
                id = ""
                label = ""
                start = ""
                startopen = False
                end = ""
                endopen = False
                pid = ""
                r = ""
                g = ""
                b = ""

                for attr in node_xml.attrib:
                    attr = attr.lower()
                    if attr == "id":
                        id = node_xml.attrib[attr]
                    if attr == "label":
                        label = node_xml.attrib[attr]
                    if attr == "start":
                        start = node_xml.attrib[attr]
                    if attr == "end":
                        start = node_xml.attrib[attr]
                    if attr == "startopen":
                        start = attvalue_xml.attrib[attr]
                        startopen = True
                    if attr == "endopen":
                        end = attvalue_xml.attrib[attr]
                        endopen = True
                    if attr == "pid":
                        pid = node_xml.attrib[attr]

                attvalues_xml = []
                spells = []

                for child in node_xml:
                    tag = ns_clean(child.tag).lower()
                    if tag == "attvalues":
                        attvalues_xml.append(child)
                    if tag == "viz:color":
                        r = child.attrib["r"]
                        g = child.attrib["g"]
                        b = child.attrib["b"]
                    if tag == "spells":
                        spells = Spells.importXML(child)

                node_obj = graph_obj.addNode(id=id, label=label, start=start, end=end, startopen=startopen, endopen=endopen, pid=pid, r=r, g=g, b=b, spells=spells)
                node_obj._attributes = graph_obj.attributes.importAttributesValuesXML("node", attvalues_xml)

    def setColor(self, r, g, b):
        self.r = r
        self.g = g
        self.b = b

    def __str__(self):
        return self.label


class Edge:

    def __init__(self, graph, id, source, target, weight="", start="", end="", label="", r="", g="", b="", spells=[], startopen=False, endopen=False):

        self.id = id
        self._graph = graph

        if self._graph.nodeExists(source):
            self._source = source
            self.source = self._source
        else:
            raise Exception("source " + source + " node unknown, add nodes to graph first")

        if self._graph.nodeExists(target):
            self._target = target
            self.target = self._target
        else:
            raise Exception("target " + target + " node unknown, add nodes to graph first")

        self.start = start
        self.startopen = startopen
        self.end = end
        self.endopen = endopen

        self.weight = weight
        self.label = label
        self._attributes = []
        self.attributes = self._attributes
        # COLOR on edges now supported in GEXF 1.2
        self.setColor(r, g, b)

        #spells expecting format = [{start:"",end:""},...]
        self.spells = Spells(spells)
        # add existing nodesattributes default values : bad idea and unecessary
        #self._graph.addDefaultAttributesToEdge(self)

    def addAttribute(self, id, value, start="", end="", startopen=False, endopen=False):
        self._attributes.append(self._graph.attributes.makeAttributeInstance("edge", id, value, start, end, startopen, endopen))

    def getXML(self):
        # return lxml etree element
        try:
            edgeXML = etree.Element("edge", id=str(self.id), source=str(self._source), target=str(self._target))
            if not self.start == "":
                edgeXML.set("start" if not self.startopen else "startopen", self.start)
            if not self.end == "":
                edgeXML.set("end" if not self.endopen else "endopen", self.end)
            if not self.weight == "":
                edgeXML.set("weight", str(self.weight))
            if not self.label == "":
                edgeXML.set("label", self.label)

            # attributes
            if self._attributes:
                edgeXML.append(Attributes.getAttributesXML(self._attributes))

            # spells
            if self.spells:
                #spellsXML = etree.SubElement(edgeXML, "spells")
                #spellsXML.append(self.spells.getXML())
                edgeXML.append(self.spells.getXML())

            # COLOR on edges is supported in GEXF since 1.2
            if not self.r == "" and not self.g == "" and not self.b == "":
                #color : <viz:color r="239" g="173" b="66"/>
                colorXML = etree.SubElement(edgeXML, "{http://www.gexf.net/1.2draft/viz}color")
                colorXML.set("r", self.r)
                colorXML.set("g", self.g)
                colorXML.set("b", self.b)

            return edgeXML
        except Exception as e:
            print(self._source + " " + self._target)
            print(e)
            exit()

    def getAttributes(self):
        attsFull = []
        for att in self._attributes:
            attFull = self._graph.attributes["edge"][att["id"]].copy()
            attFull.update(att)
            attsFull.append(attFull)
        return attsFull

    @staticmethod
    def importXML(edges_xml, graph_obj):

        for child in edges_xml:

            tag = ns_clean(child.tag).lower()
            if tag == "edge":
                edge_xml = child
                id = ""
                source = ""
                target = ""
                weight = ""
                start = ""
                startopen = False
                end = ""
                endopen = False
                label = ""
                r = ""
                g = ""
                b = ""

                for attr in edge_xml.attrib:
                    attr = attr.lower()
                    if attr == "id":
                        id = edge_xml.attrib[attr]
                    if attr == "source":
                        source = edge_xml.attrib[attr]
                    if attr == "target":
                        target = edge_xml.attrib[attr]
                    if attr == "weight":
                        weight = edge_xml.attrib[attr]
                    if attr == "start":
                        start = edge_xml.attrib[attr]
                    if attr == "end":
                        end = edge_xml.attrib[attr]
                    if attr == "startopen":
                        start = edge_xml.attrib[attr]
                        startopen = True
                    if attr == "endopen":
                        end = edge_xml.attrib[attr]
                        endopen = True
                    if attr == "label":
                        label = edge_xml.attrib[attr]

                spells = []
                attvalues_xml = []
                for child in edge_xml:
                    tag = ns_clean(child.tag).lower()
                    if tag == "attvalues":
                        attvalues_xml.append(child)
                    if tag == "spells":
                        spells = Spells.importXML(child)
                    if tag == "viz:color":
                        r = child.attrib["r"]
                        g = child.attrib["g"]
                        b = child.attrib["b"]

                edge_obj = graph_obj.addEdge(id=id, source=source, target=target, weight=weight, start=start, end=end, startopen=startopen, endopen=endopen, label=label, r=r, g=g, b=b, spells=spells)
                edge_obj._attributes = graph_obj.attributes.importAttributesValuesXML("edge", attvalues_xml)

# COLOR on edges is supported in GEXF since 1.2
    def setColor(self, r, g, b):
        self.r = r
        self.g = g
        self.b = b


class GexfImport:
# class coded by elie Rotenberg, médialab 20/07/2010
# deprecated : import XML codes are now included to the Gexf, Graph, Attribute, Node, Edge classes

    def __init__(self, file_like):
        parser = etree.XMLParser(ns_clean=True)
        tree = etree.parse(file_like, parser)
        gexf_xml = tree.getroot()
        tag = self.ns_clean(gexf_xml.tag).lower()
        if tag != "gexf":
            self.msg_unexpected_tag("gexf", tag)
            return
        self.gexf_obj = None
        for child in gexf_xml:
            tag = self.ns_clean(child.tag).lower()
            if tag == "meta":
                meta_xml = child
                self.gexf_obj = self.extract_gexf_obj(meta_xml)
            if tag == "graph":
                graph_xml = child
                if self.gexf_obj == None:
                    self.msg_unexpected_tag("meta", tag)
                    return
                self.graph_obj = self.extract_graph_obj(graph_xml)

    def ns_clean(self, token):
        i = token.find('}')
        return token[i + 1:]

    def msg_unexpected_tag(self, expected, got):
        print("Error : incorrect xml. Expected tag {expected}, not {got}.".format(expected=expected, got=got))

    def extract_gexf_obj(self, meta_xml):
        for child in meta_xml:
            tag = self.ns_clean(child.tag).lower()
            if tag == "creator":
                creator = child.text
            if tag == "description":
                description = child.text
        return Gexf(creator=creator, description=description)

    def extract_graph_obj(self, graph_xml):
        type = ""
        mode = ""
        label = ""
        timeformat = "double"
        for attr in graph_xml.attrib:
            attr = attr.lower()
            if attr == "defaultedgetype":
                type = graph_xml.attrib[attr]
            if attr == "mode":
                mode = graph_xml.attrib[attr]
            if attr == "label":
                label = graph_xml.attrib[attr]
            if attr == "timeformat":
                timeformat = graph_xml.attrib[attr]

        self.graph_obj = self.gexf_obj.addGraph(type=type, mode=mode, label=label, timeformat=timeformat)

        for child in graph_xml:
            tag = self.ns_clean(child.tag).lower()
            if tag == "attributes":
                attributes_xml = child
                self.extract_attributes(attributes_xml)
            if tag == "nodes":
                nodes_xml = child
                self.extract_nodes(nodes_xml)
            if tag == "edges":
                edges_xml = child
                self.extract_edges(edges_xml)

    def extract_attributes(self, attributes_xml):
        attr_class = None
        mode = ""
        for attr in attributes_xml.attrib:
            attr = attr.lower()
            if attr == "class":
                attr_class = attributes_xml.attrib[attr].lower()
            if attr == "mode":
                mode = attributes_xml.attrib[attr]

        for child in attributes_xml:
            tag = self.ns_clean(child.tag).lower()
            if tag == "attribute":
                attribute_xml = child
                self.extract_attribute(attribute_xml, attr_class, mode)

    def extract_attribute(self, attribute_xml, attr_class, mode):
        id = ""
        title = ""
        type = ""

        for attr in attribute_xml.attrib:
            attr = attr.lower()
            if attr == "id":
                id = attribute_xml.attrib[attr]
            if attr == "title":
                title = attribute_xml.attrib[attr]
            if attr == "type":
                type = attribute_xml.attrib[attr]

        default = ""

        for child in attribute_xml:
            tag = self.ns_clean(child.tag).lower()
            if tag == "default":
                default = child.text

        if attr_class == "node":
            self.graph_obj.addNodeAttribute(title, default, type, mode, force_id=id)

        if attr_class == "edge":
            self.graph_obj.addEdgeAttribute(title, default, type, mode, force_id=id)

    def extract_nodes(self, nodes_xml):
        for child in nodes_xml:
            tag = self.ns_clean(child.tag).lower()
            if tag == "node":
                node_xml = child
                self.extract_node(node_xml)

    def extract_node(self, node_xml):
        id = ""
        label = ""
        start = ""
        startopen = False
        end = ""
        endopen = False
        pid = ""
        r = ""
        g = ""
        b = ""

        for attr in node_xml.attrib:
            attr = attr.lower()
            if attr == "id":
                id = node_xml.attrib[attr]
            if attr == "label":
                label = node_xml.attrib[attr]
            if attr == "start":
                start = node_xml.attrib[attr]
            if attr == "end":
                start = node_xml.attrib[attr]
            if attr == "startopen":
                start = attvalue_xml.attrib[attr]
                startopen = True
            if attr == "endopen":
                end = attvalue_xml.attrib[attr]
                endopen = True
            if attr == "pid":
                pid = node_xml.attrib[attr]

        attvalues_xmls = []
        spells = []

        for child in node_xml:
            tag = self.ns_clean(child.tag).lower()
            if tag == "attvalues":
                attvalues_xmls.append(child)
            if tag == "viz:color":
                r = child.attrib["r"]
                g = child.attrib["g"]
                b = child.attrib["b"]
            if tag == "spells":
                spells = [spell.attrib for spell in child]

        self.node_obj = self.graph_obj.addNode(id=id, label=label, start=start, end=end, startopen=startopen, endopen=endopen, pid=pid, r=r, g=g, b=b, spells=spells)

        for attvalues_xml in attvalues_xmls:
            self.extract_node_attvalues(attvalues_xml)

    def extract_node_attvalues(self, attvalues_xml):
        for child in attvalues_xml:
            tag = self.ns_clean(child.tag).lower()
            if tag == "attvalue":
                attvalue_xml = child
                self.extract_node_attvalue(attvalue_xml)

    def extract_node_attvalue(self, attvalue_xml):
        id = ""
        value = ""
        start = ""
        startopen = False
        end = ""
        endopen = False
        for attr in attvalue_xml.attrib:
            attr = attr.lower()
            if attr == "for":
                id = attvalue_xml.attrib[attr]
            if attr == "value":
                value = attvalue_xml.attrib[attr]
            if attr == "start":
                start = attvalue_xml.attrib[attr]
            if attr == "end":
                end = attvalue_xml.attrib[attr]
            if attr == "startopen":
                start = attvalue_xml.attrib[attr]
                startopen = True
            if attr == "endopen":
                end = attvalue_xml.attrib[attr]
                endopen = True
        self.node_obj.addAttribute(id=id, value=value, start=start, end=end, startopen=startopen, endopen=endopen)

    def extract_edges(self, edges_xml):
        for child in edges_xml:
            tag = self.ns_clean(child.tag).lower()
            if tag == "edge":
                edge_xml = child
                self.extract_edge(edge_xml)

    def extract_edge(self, edge_xml):
        id = ""
        source = ""
        target = ""
        weight = ""
        start = ""
        startopen = False
        end = ""
        endopen = False
        label = ""
        r = ""
        g = ""
        b = ""

        for attr in edge_xml.attrib:
            attr = attr.lower()
            if attr == "id":
                id = edge_xml.attrib[attr]
            if attr == "source":
                source = edge_xml.attrib[attr]
            if attr == "target":
                target = edge_xml.attrib[attr]
            if attr == "weight":
                weight = edge_xml.attrib[attr]
            if attr == "start":
                start = edge_xml.attrib[attr]
            if attr == "end":
                end = edge_xml.attrib[attr]
            if attr == "startopen":
                start = edge_xml.attrib[attr]
                startopen = True
            if attr == "endopen":
                end = edge_xml.attrib[attr]
                endopen = True
            if attr == "label":
                label = edge_xml.attrib[attr]

        spells = []
        attvalues_xml = []
        for child in edge_xml:
            tag = self.ns_clean(child.tag).lower()
            if tag == "attvalues":
                attvalues_xml = child
            if tag == "spells":
                spells = [spell.attrib for spell in child]
            if tag == "viz:color":
                r = child.attrib["r"]
                g = child.attrib["g"]
                b = child.attrib["b"]

        self.edge_obj = self.graph_obj.addEdge(id=id, source=source, target=target, weight=weight, start=start, end=end, startopen=startopen, endopen=endopen, label=label, r=r, g=g, b=b, spells=spells)
        self.extract_edge_attvalues(attvalues_xml)

    def extract_edge_attvalues(self, attvalues_xml):
        for child in attvalues_xml:
            tag = self.ns_clean(child.tag).lower()
            if tag == "attvalue":
                attvalue_xml = child
                self.extract_edge_attvalue(attvalue_xml)
#    def addAttribute(self,id,value,start="",end="") :

    def extract_edge_attvalue(self, attvalue_xml):
        id = ""
        value = ""
        start = ""
        startopen = True
        end = ""
        endopen = True
        for attr in attvalue_xml.attrib:
            if attr == "for":
                id = attvalue_xml.attrib[attr]
            if attr == "value":
                value = attvalue_xml.attrib[attr]
            if attr == "start":
                start = attvalue_xml.attrib[attr]
            if attr == "end":
                end = attvalue_xml.attrib[attr]
            if attr == "startopen":
                startopen = attvalue_xml.attrib[attr]
            if attr == "endopen":
                endopen = attvalue_xml.attrib[attr]

        self.edge_obj.addAttribute(id=id, value=value, start=start, end=end, startopen=startopen, endopen=endopen)

    def gexf(self):
        return self.gexf_obj

然后再次import gexf,此时应该是没有问题的。之后用程序测试一下:

  • 关于测试程序,这里要多说几句,下面的测试程序代码片倒数第三行
    output_file=open("./data.gexf","wb")的形式具体取决于
  • 你是windows还是linux
  • 你是python2还是python3
1.在python3且linux情况下,直接执行下面的大段代码
2.在python3且windows情况下,则需把倒数第三行改为

output_file=open(".\data.gexf","wb")

3.我没用过python2,所以这些同学如果失败的话,先看看是不是1和2说的操作系统的问题。之后不行的话,可以试试把“wb”改为“w“(未测试过)
import sys,pprint
from gexf import Gexf


# test helloworld.gexf
gexf = Gexf("Gephi.org","A Web network")
graph=gexf.addGraph("directed","static","A Web network")

atr1 = graph.addNodeAttribute('url',type='string')
atr2 = graph.addNodeAttribute('indegree',type='float')
atr3 = graph.addNodeAttribute('frog',type='boolean',defaultValue='true')

tmp = graph.addNode("0","Gephi")
tmp.addAttribute(atr1,"http://gephi.org")
tmp.addAttribute(atr2,'1')

tmp = graph.addNode("1","Webatlas")
tmp.addAttribute(atr1,"http://webatlas.fr")
tmp.addAttribute(atr2,'2')

tmp = graph.addNode("2","RTGI")
tmp.addAttribute(atr1,"http://rtgi.fr")
tmp.addAttribute(atr2,'1')

tmp = graph.addNode("3","BarabasiLab")
tmp.addAttribute(atr1,"http://barabasilab.com")
tmp.addAttribute(atr2,'1')
tmp.addAttribute(atr3,'false')

graph.addEdge("0","0","1",weight='1')
graph.addEdge("1","0","2",weight='1')
graph.addEdge("2","1","0",weight='1')
graph.addEdge("3","2","1",weight='1')
graph.addEdge("4","0","3",weight='1')



output_file=open("./data.gexf","wb")
gexf.write(output_file)
output_file.close()

执行完后,在你代码文件的父目录下,应该会产生一个data.gexf文件,大功告成!在这里插入图片描述

Reference:

1.python3环境下安装gexf库的一些错误修正方法

  • 这个博客比较优质,我在上面做了一点改进,不用手动在_gexf里面找空格,而且后面更新的python3版本的_gexf.py(1000多行)比原来python2(600多行)的要长很多。

2.Python生成gexf文件并导入gephi做网络图分析

  • 测试程序来源
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值