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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
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,
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?
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?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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:
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!
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?
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:
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
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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?
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:
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
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:
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
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
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.
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
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:
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
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:
Cheers
with
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.
Indeed, make sure you instantiate the property before accessing it. Assuming UrbanAgglomeration stores integer values:
You may also use a shortcut and store the instantiated property in a variable (to avoid retyping the whole expression):
there was an error in your proposal, we are dealing with
strings
here, not withIntegers
. This works: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
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:
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 andCityCode
. This is where the info I am looking for resides.My question is how to complete the
src
andtgt
fields in the spreadsheet view and then in export witht these infos?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:
(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:
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:
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
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:
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
Last edit: Alain L'Hostis 2019-09-19
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: