Menu

Export graph table with origin id and estination id of nodes

Help
2019-09-11
2019-09-18
  • Alain L'Hostis

    Alain L'Hostis - 2019-09-11

    I generated a graph in Tulip, I have custom node Id (long code + label + etc). What I want is to generate a csv table where these info would be clearly shown (and not only the internal Tulip id of nodes). Here are the coluns I want to see:
    id origin node, code orig node, label orig node, id dest node, code dest node, label dest node

     
  • Patrick Mary

    Patrick Mary - 2019-09-11

    As you are talking about "orig node" and "dest node", I suppose that you want to export information about the graph edges.
    The Tulip "CSV Export" feature only allows to export the values of existing Tulip properties (, except the id of the graph element being exported).
    Thus the columns you cited must be existing properties correctly valuated for all graph edges before being exported.
    So you can first create these properties using the Table View, then use a python script doing a loop on all graph edges in order to correctly set the values corresponding to the source and target nodes of each edge.
    Hope this helps.

     
  • Melançon Guy

    Melançon Guy - 2019-09-11

    Hi Alain, long time no see, I hope you're doing fine -- well, you're still using Tulip which is a good sign :-)

    Using the export button (on the left behind the Undo/Redo buttons) you get a csv file containing all elements of the graph and all their user defined properties. I believe the simplest thing to do is create a user defined property that stores whatever system defined propery that you need to export, in your case the internal node id:

    def main(graph):
    nodeid = graph.getIntegerProperty("InternalNodeId")
    for n in graph.getNodes():
    graph["InternalNodeId"][n] = n.id

    Hope this helps
    Cheers
    Guy

     
  • Alain L'Hostis

    Alain L'Hostis - 2019-09-13

    Hi Guy and Patick
    so true, long time no see but still regular Tulip user :)
    Something is evidently wrong in my script, I am sure you will immediately detect my error:

    for n in graph.getNodes():
        graph["OriNodeLabel"][n] = n.UrbanAgglomeration
    

    In my graph I have introduced a new property called "OriNodeLabel" and in it I want to store the existing propery called "UrbanAgglomeration"
    I get an error: AttributeError: 'node' object has no attribute 'UrbanAgglomeration'
    In addition I do not perceive the magic that will identify origin and destination nodes of each edge ????

     

    Last edit: Alain L'Hostis 2019-09-13
  • Melançon Guy

    Melançon Guy - 2019-09-13

    Hi Alain,
    Patrick will confirm, but the error is you want to access the property using the dot operator which is forbidden (but for the n.id interger id), you need to write:

    for n in graph.getNodes():
        graph["OriNodeLabel"][n] = graph['UrbanAgglomeration'][n]
    

    Cheers

     
  • Alain L'Hostis

    Alain L'Hostis - 2019-09-13

    with

    for n in graph.getNodes():
        graph["OriNodeLabel"][n] = graph["UrbanAgglomeration"][n]
    

    starting at line 55 in the predefined script, I get an error
    Exception: Error : Unable to get node data as no graph property has been created through that proxy.

     
  • Melançon Guy

    Melançon Guy - 2019-09-13

    Indeed, make sure you instantiate the property before accessing it. Assuming UrbanAgglomeration stores integer values:

    graph.getIntegerProperty("UrbanAgglomeration")
    for n in graph.getNodes():
        graph["OriNodeLabel"][n] = graph["UrbanAgglomeration"][n]
    

    You may also use a shortcut and store the instantiated property in a variable (to avoid retyping the whole expression):

    urb = graph.getIntegerProperty("UrbanAgglomeration")
    for n in graph.getNodes():
        graph["OriNodeLabel"][n] = urb[n]
    
     
  • Alain L'Hostis

    Alain L'Hostis - 2019-09-14

    there was an error in your proposal, we are dealing with strings here, not with Integers. This works:

    graph.getStringProperty("UrbanAgglomeration")
    for n in graph.getNodes():
        graph["OriNodeLabel"][n] = graph["UrbanAgglomeration"][n]
    
     
  • Alain L'Hostis

    Alain L'Hostis - 2019-09-14

    the problem is that now it seems to run (no errors) but has no effect. I also tried to loop on edges instead of nodes, and still the property OriNodeLabel remains empty.
    In addition, what could be the instruction to populate the other extremity DesNodeLabel?
    In addition, this instruction seems to only copy the content of the property in another column of edges, the issue is that the intial colm=umn is now empty in edges view, this is probably why nothin occurs?
    I attach my graph.

     

    Last edit: Alain L'Hostis 2019-09-14
    • brenoust

      brenoust - 2019-09-15

      Yes indeed, Guy's code creates a new property, and copies the content of a
      new property into
      graph["OriNodeLabel"] which then becomes an empty string.
      My question is when you proposed,

      graph["OriNodeLabel"][n] = n.UrbanAgglomeration

      It seems that you are already reading some data. Were/how is this data stored?
      You were probably confusing between two version of n, n being a Tulip
      node, and n being your own data structure.

      Tulip nodes are their own structure (basically a fancy integer as a
      node id), and you cannot assign a node some other properties,
      like you would with other graph libraries (like n.someproperty = ...)
      I hope it helps,

      --
      Benjamin

      On Sat, 14 Sep 2019 at 22:18, Alain L'Hostis lhostis@users.sourceforge.net
      wrote:

      the problem is that now it seems to run (no errors) but has no effect. I
      also tried to loop on edges instead of nodes, and still the property
      OriNodeLabel remains empty.
      In addition, what could be the instruction to populate the other extremity
      DesNodeLabel?


      Export graph table with origin id and estination id of nodes
      https://sourceforge.net/p/auber/discussion/206283/thread/d77e244853/?limit=25#82df


      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/auber/discussion/206283/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

       
  • Alain L'Hostis

    Alain L'Hostis - 2019-09-16

    Dear Benjamin,
    since nodes have labels, they also can have custom propoerties, right? My nodes have a ccustom property called UrbanAgglomeration where labels are stored and CityCode . This is where the info I am looking for resides.
    My question is how to complete the src and tgt fields in the spreadsheet view and then in export witht these infos?

     
    • brenoust

      brenoust - 2019-09-17

      Dear Alain,

      There are a few issues in this thread.

      1) about populating node/edge properties:

      Custom properties are not really the problem here, my question is more on
      the way you populate these information.
      There are many ways to do it, and I guess you are first reading through a
      file.
      Because in your first example, UrbanAgglomeration does not exist before you
      create it (but then it is empty and remains unpopulated).
      Imagine that you are reading through a rough object of the form:

      mygraph=
      {nodes:
      {id: 1,
      UrbanAgglomeration: Paris,
      CityCode: 75000},
      {id: 2,
      UrbanAgglomeration: Marseille,
      CityCode: 13000},
      ...
      ,
      edges:
      {src: 1,
      tgt: 2,
      distance: 775 000},
      ...

      }

      You probably iterate through your nodes the following way:

      graph = tlp.newGraph
      urban = graph.getStringProperty('UrbanAgglomeration')
      city = graph.getDoublePropery('CityCode')

      for node in mygraph['nodes']:
      n = graph.addNode()
      urban[n] = node.UrbanAgglomeration // here you populate
      UrbanAgglomeration
      city[n] = node.CityCode // here you populate CityCode

      from that point on only, because you have populated the property to the
      tulip nodes n, you can read:
      city_code_value = city[n]

      2) As for accessing source and target nodes,
      you can try:
      sourceP = graph.getIntegerProperty("edge_source")
      targetP = graph.getIntegerProperty("edge_target")
      for e in graph.getEdges():
      source, target = graph.ends(e) //returns tulip nodes
      sourceP[e] = source.id
      targetP[e] = target.id

      Then two properties "edge_source" and "edge_target" should appear on your
      spreadsheet view.

      3) Going further:
      note that you can always create an arbitrary node from its id:
      n = tlp.node(node_id) // works also for tlp.edge(edge_id), the id should be
      an int
      then test if it exists in your graph:
      graph.isElement(n) // works also for edges

      Instead of forcing to add nodes of a certain ID to a graph (such as using
      your original ids), you should rather maintain
      an id_to_node map (because tulip uses its own efficient ID access system,
      and won't allow adding a node with an arbitrary ID).
      Taking the example in 1):

      graph = tlp.newGraph
      original_id = graph.getDoublePropery('OriginalID') // to store the original
      ID
      urban = graph.getStringProperty('UrbanAgglomeration')
      city = graph.getDoublePropery('CityCode')

      id_to_node = {}

      for node in mygraph['nodes']:
      n = graph.addNode()
      original_id[n] = node.id // saving the ID information
      id_to_node[node.id] = n // storing for link creation
      urban[n] = node.UrbanAgglomeration
      city[n] = node.CityCode

      distance = graph.getDoubleProperty('Distance')
      for edge in mygraph['edges']:
      src_node = id_to_node[edge.src] // fetching the corresponding tulip node
      tgt_node = id_to_node[edge.tgt] // fetching the corresponding tulip node
      e = graph.addEdge(src_node, tgt_node) // creating the tulip edge
      distance[e] = edge.distance

      You probably know most of these, but given your explanations I could not
      precisely be sure of what you need.
      I hope these detailed examples will help you!

      Cheers,

      --
      Benjamin

      On Tue, 17 Sep 2019 at 04:39, Alain L'Hostis lhostis@users.sourceforge.net
      wrote:

      Dear Benjamin,
      since nodes have labels, they also can have custom propoerties, right? My
      nodes have a ccustom property called UrbanAgglomeration where labels are
      stored and CityCode . This is where the info I am looking for resides.
      My question is how to complete the src and tgt fields in the spreadsheet
      view and then in export witht these infos?


      Export graph table with origin id and estination id of nodes
      https://sourceforge.net/p/auber/discussion/206283/thread/d77e244853/?limit=25#4715


      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/auber/discussion/206283/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

       
      • brenoust

        brenoust - 2019-09-17

        (apologies, as I am replying by email, the formatting seems to have
        vanished in the process)
        --
        Benjamin

        On Tue, 17 Sep 2019 at 11:59, brenoust falcoyote@users.sourceforge.net
        wrote:

        Dear Alain,

        There are a few issues in this thread.

        1) about populating node/edge properties:

        Custom properties are not really the problem here, my question is more on
        the way you populate these information.
        There are many ways to do it, and I guess you are first reading through a
        file.
        Because in your first example, UrbanAgglomeration does not exist before you
        create it (but then it is empty and remains unpopulated).
        Imagine that you are reading through a rough object of the form:

        mygraph=
        {nodes:
        {id: 1,
        UrbanAgglomeration: Paris,
        CityCode: 75000},
        {id: 2,
        UrbanAgglomeration: Marseille,
        CityCode: 13000},
        ...

        https://sourceforge.net/../%7Bid:%201,%0D%20%20%20%20%20%20UrbanAgglomeration:%20Paris,%0D%20%20%20%20%20%20CityCode:%2075000%7D,%0D%20%20%20%20%20%7Bid:%202,%0D%20%20%20%20%20%20UrbanAgglomeration:%20Marseille,%0D%20%20%20%20%20%20CityCode:%2013000%7D,%0D%20%20%20%20%20...
        ,
        edges:
        {src: 1,
        tgt: 2,
        distance: 775 000},
        ...

        https://sourceforge.net/../%7Bsrc:%201,%0D%20%20%20%20%20%20tgt:%202,%0D%20%20%20%20%20%20distance:%20775%20000%7D,%0D%20%20%20%20%20...
        }

        You probably iterate through your nodes the following way:

        graph = tlp.newGraph
        urban = graph.getStringProperty('UrbanAgglomeration')
        city = graph.getDoublePropery('CityCode')

        for node in mygraph['nodes']:
        n = graph.addNode()
        urban[n] = node.UrbanAgglomeration // here you populate
        UrbanAgglomeration
        city[n] = node.CityCode // here you populate CityCode

        from that point on only, because you have populated the property to the
        tulip nodes n, you can read:
        city_code_value = city[n]

        2) As for accessing source and target nodes,
        you can try:
        sourceP = graph.getIntegerProperty("edge_source")
        targetP = graph.getIntegerProperty("edge_target")
        for e in graph.getEdges():
        source, target = graph.ends(e) //returns tulip nodes
        sourceP[e] = source.id
        targetP[e] = target.id

        Then two properties "edge_source" and "edge_target" should appear on your
        spreadsheet view.

        3) Going further:
        note that you can always create an arbitrary node from its id:
        n = tlp.node(node_id) // works also for tlp.edge(edge_id), the id should be
        an int
        then test if it exists in your graph:
        graph.isElement(n) // works also for edges

        Instead of forcing to add nodes of a certain ID to a graph (such as using
        your original ids), you should rather maintain
        an id_to_node map (because tulip uses its own efficient ID access system,
        and won't allow adding a node with an arbitrary ID).
        Taking the example in 1):

        graph = tlp.newGraph
        original_id = graph.getDoublePropery('OriginalID') // to store the original
        ID
        urban = graph.getStringProperty('UrbanAgglomeration')
        city = graph.getDoublePropery('CityCode')

        id_to_node = {}

        for node in mygraph['nodes']:
        n = graph.addNode()
        original_id[n] = node.id // saving the ID information
        id_to_node[node.id] = n // storing for link creation
        urban[n] = node.UrbanAgglomeration
        city[n] = node.CityCode

        distance = graph.getDoubleProperty('Distance')
        for edge in mygraph['edges']:
        src_node = id_to_node[edge.src] // fetching the corresponding tulip node
        tgt_node = id_to_node[edge.tgt] // fetching the corresponding tulip node
        e = graph.addEdge(src_node, tgt_node) // creating the tulip edge
        distance[e] = edge.distance

        You probably know most of these, but given your explanations I could not
        precisely be sure of what you need.
        I hope these detailed examples will help you!

        Cheers,

        --
        Benjamin

        On Tue, 17 Sep 2019 at 04:39, Alain L'Hostis lhostis@users.sourceforge.net
        wrote:

        Dear Benjamin,
        since nodes have labels, they also can have custom propoerties, right? My
        nodes have a ccustom property called UrbanAgglomeration where labels are
        stored and CityCode . This is where the info I am looking for resides.
        My question is how to complete the src and tgt fields in the spreadsheet
        view and then in export witht these infos?


        Export graph table with origin id and estination id of nodes

        https://sourceforge.net/p/auber/discussion/206283/thread/d77e244853/?limit=25#4715

        Sent from sourceforge.net because you indicated interest in
        https://sourceforge.net/p/auber/discussion/206283/

        To unsubscribe from further messages, please visit
        https://sourceforge.net/auth/subscriptions/


        Export graph table with origin id and estination id of nodes
        https://sourceforge.net/p/auber/discussion/206283/thread/d77e244853/?limit=25#4715/5f90


        Sent from sourceforge.net because tulipdev@labri.fr is subscribed to
        https://sourceforge.net/p/auber/discussion/206283/

        To unsubscribe from further messages, a project admin can change settings
        at https://sourceforge.net/p/auber/admin/discussion/forums. Or, if this
        is a mailing list, you can unsubscribe from the mailing list.

         
  • Alain L'Hostis

    Alain L'Hostis - 2019-09-17

    Immensely useful dear Benjamin! I made huge steps in understanding tulip graphs.
    I am geting so close to the desired output, but not yet there:

      node_label = graph.getStringProperty("UrbanAgglomeration")
      sourceP = graph.getIntegerProperty("edge_source")
      targetP = graph.getIntegerProperty("edge_target")
      sourceL = graph.getStringProperty("source_label")
      targetL = graph.getStringProperty("target_label")
      for e in graph.getEdges():
        source, target = graph.ends(e) 
        sourceP[e] = source.id
        targetP[e] = target.id
        sourceL[e] = node_label[source]
        targetL[e] = node_label[target]
    

    this populated the id of source and target, great, but the source and target label columns remain emty :(
    I have created a recipient property, but I remain unable to access the existing node properties already existing in my graph (the labels)

     

    Last edit: Alain L'Hostis 2019-09-17
    • brenoust

      brenoust - 2019-09-17

      Thanks a lot Alain.
      Ok, so this is a progress.

      My hunch is that your label property: node_label =
      graph.getStringProperty("UrbanAgglomeration") has never been populated

      If it is populated, when you print:
      for n in graph.getNodes():
      print node_label[n]
      You should not have empty strings only.
      If so, this means that the property has never been stored.

      And probably it has not been created yet, because of the very first error
      you mention in this thread.
      To test if a property exist in a graph, you can do:
      graph.existProperty("UrbanAgglomeration")
      It will return True if it exists, False otherwise

      I suspect that it returns False in your case because "UrbanAgglomeration" does
      not exist yet in your graph.
      I will need finer details, such as how you read and store the
      "UrbanAgglomeration" property in your nodes to help you further.
      Are you reading a custom file? Maybe your graph object (tlp.Graph object)
      that you store things in the first time is not the same that you are
      reading now.
      Could you share more of your code?

      Cheers,
      --
      Benjamin

      On Wed, 18 Sep 2019 at 00:49, Alain L'Hostis lhostis@users.sourceforge.net
      wrote:

      Immensely useful dear Benjamin! I mage huge steps in understanding tulip
      graphs.
      I am geting so close to the desired output, but not yet there:

      node_label = graph.getStringProperty("UrbanAgglomeration")
      sourceP = graph.getIntegerProperty("edge_source")
      targetP = graph.getIntegerProperty("edge_target")
      sourceL = graph.getStringProperty("source_label")
      targetL = graph.getStringProperty("target_label")
      for e in graph.getEdges():
      source, target = graph.ends(e)
      sourceP[e] = source.id
      targetP[e] = target.id
      sourceL[e] = node_label[source]
      targetL[e] = node_label[target]

      this populated the id of source and target, great, but the source and
      target lable columns remain emty :(


      Export graph table with origin id and estination id of nodes
      https://sourceforge.net/p/auber/discussion/206283/thread/d77e244853/?limit=25#9d07


      Sent from sourceforge.net because tulipdev@labri.fr is subscribed to
      https://sourceforge.net/p/auber/discussion/206283/

      To unsubscribe from further messages, a project admin can change settings
      at https://sourceforge.net/p/auber/admin/discussion/forums. Or, if this
      is a mailing list, you can unsubscribe from the mailing list.

       
  • Alain L'Hostis

    Alain L'Hostis - 2019-09-18

    This is it, here comes my working solution. In my previous code there was a mistake in the naming of the property, I made a mistake in typing an 'U' instead of an 'u'.
    In the end, the code that works is here:

    ~~~
    node_label = graph.getStringProperty("urbanAgglomeration")
    node_city_code = graph.getIntegerProperty("cityCode")

    sourceP = graph.getIntegerProperty("edge_source")
    targetP = graph.getIntegerProperty("edge_target")
    sourceL = graph.getStringProperty("source_label")
    targetL = graph.getStringProperty("target_label")
    sourceC = graph.getIntegerProperty("source_city_code")
    targetC = graph.getIntegerProperty("target_city_code")
    for e in graph.getEdges():
    source, target = graph.ends(e)
    sourceP[e] = source.id
    targetP[e] = target.id
    sourceL[e] = node_label[source]
    targetL[e] = node_label[target]
    sourceC[e] = node_city_code[source]
    targetC[e] = node_city_code[target]
    ~~~
    This simply populates new columns attached to edges, with nodes existing information.
    Simply an annoyance, the newly created columns did not show immediately, I had to click on the little eye in the Properties box, this was all, and in the end I have a nice table with all the needed information, great!!!!
    TOPIC = CLOSED
    Thanks to Patrick, Guy and Benjamin

     
    🎉
    1

    Last edit: Alain L'Hostis 2019-09-19
    • brenoust

      brenoust - 2019-09-18

      Hurray! Congrats! Please come back to us if anything pops us.
      Good luck with your project!
      --
      Benjamin

      On Thu, 19 Sep 2019 at 02:57, Alain L'Hostis lhostis@users.sourceforge.net
      wrote:

      This is it, here comes my working solution. In my previous code there was
      a mistake in the naming of the property, I made a mistake in typing an 'U'
      instead of an 'u'.
      In the end, the code that works is here:

      ~~~
      node_label = graph.getStringProperty("urbanAgglomeration")
      node_city_code = graph.getIntegerProperty("cityCode")

      sourceP = graph.getIntegerProperty("edge_source")
      targetP = graph.getIntegerProperty("edge_target")
      sourceL = graph.getStringProperty("source_label")
      targetL = graph.getStringProperty("target_label")
      sourceC = graph.getIntegerProperty("source_city_code")
      targetC = graph.getIntegerProperty("target_city_code")
      for e in graph.getEdges():
      source, target = graph.ends(e)
      sourceP[e] = source.id
      targetP[e] = target.id
      sourceL[e] = node_label[source]
      targetL[e] = node_label[target]
      sourceC[e] = node_city_code[source]
      targetC[e] = node_city_code[target]
      ~~~
      This simply populates new columns attached to edges, with nodes existing
      information.
      Simply an annoyance, the newly created columns did not show immediately, I
      had to click on the little eye in the Properties box, this was all, and in
      the end I have a nice table with all the needed information, great!!!!
      TOPIC = CLOSED
      Thanks to Patrick, Guy and Benjamin


      Export graph table with origin id and estination id of nodes
      https://sourceforge.net/p/auber/discussion/206283/thread/d77e244853/?limit=25#da5a


      Sent from sourceforge.net because tulipdev@labri.fr is subscribed to
      https://sourceforge.net/p/auber/discussion/206283/

      To unsubscribe from further messages, a project admin can change settings
      at https://sourceforge.net/p/auber/admin/discussion/forums. Or, if this
      is a mailing list, you can unsubscribe from the mailing list.

       

Log in to post a comment.