python-igraph icon indicating copy to clipboard operation
python-igraph copied to clipboard

Graph.write_graphml does not store tuple attributes in python-igraph 0.6

Open gaborcsardi opened this issue 11 years ago • 5 comments

From @gaborcsardi on May 4, 2013 18:56

Tuple graph, vertex and edge attributes are not stored when exported to GraphML (I don't know about other formats) in python-igraph 0.6 (0.5 works fine).

See the attachment for a minimal example.


Imported from Launchpad using lp2gh.

  • date created: 2012-01-18T11:38:58Z
  • owner: d-landtwing
  • assignee: ntamas
  • the launchpad url was https://bugs.launchpad.net/bugs/918138

Copied from original issue: igraph/igraph#221

gaborcsardi avatar Jan 14 '15 21:01 gaborcsardi

(by d-landtwing)

gaborcsardi avatar Jan 14 '15 21:01 gaborcsardi

(by ntamas) Okay, so this is actually a result of trying to bring the GraphML exporter closer to the GraphML specification. According to the GraphML Primer ( http://graphml.graphdrawing.org/primer/graphml-primer.html#Attributes ), "[t]he type of the GraphML-Attribute can be either boolean, int, long, float, double, or string". Since tuples are neither of these, igraph simply ignores tuple vertex/edge attributes.

More precisely:

  • If all the attribute values for a given attribute are strings or None, igraph assumes that the GraphML type of the attribute will be "string".
  • If all the attribute values for a given attribute are numeric or None, igraph assumes that the GraphML type of the attribute will be "double".
  • In all other cases, igraph ignores the attribute.

Before igraph 0.6, the rules were as follows:

  • If all the attribute values for a given attribute were numeric or None, igraph assumed that the GraphML type of the attribute will be "double".
  • In all other cases, igraph assumed the attribute values to be strings but wrapped the values in a str(...) call to ensure that they are actually strings. Tuples were then stored as strings and loaded back as strings, which was confusing for some of the users.

The solution is probably to pickle the attribute values for non-numeric and non-string attributes before saving the GraphML file and unpickle them after loading (since pickled attribute values can simply be stored as strings). Alternatively, one could use the "repr" function to store the attributes and the "eval" function to load them back, which would not work for all Python data types but would provide a human-readable representation of tuples (unlike pickling). Would this solution suit you?

gaborcsardi avatar Jan 14 '15 21:01 gaborcsardi

(by d-landtwing) Thanks for your explanations and suggestions.

I think both solutions are fine and both have their advantages and drawbacks. I'm okay with any solution that works. I'd even be okay with the current implementation except that I would expect a warning log message when attributes are ignored.

The only reason for submitting this bug report was that the behaviour changed from 0.5 to 0.6 and it was not immediately obvious (to me as a developer) what went wrong and where it did. I think in those cases it would be helpful to give feedback to developers via exceptions or warnings or similar.

gaborcsardi avatar Jan 14 '15 21:01 gaborcsardi

(by ntamas) Postponed till 0.7 because it requires API changes in the attribute handler interface.

gaborcsardi avatar Jan 14 '15 21:01 gaborcsardi

The proper solution to this issue would be to add an argument to write_graphml() in the Python layer that tells igraph how to serialize attribute types not supported by GraphML to a GraphML-friendly format. Something like:

import pickle

g.write_graphml("test.graphml", serializer=repr)

This way all non-GraphML attributes would be filtered through repr() by igraph before saving them, and then they would simply be stored as strings. Definitely not for 0.8, but most likely for 0.9.

ntamas avatar Jan 30 '20 10:01 ntamas