floating point values in graphml
When exporting a graph to GraphML, graph-tool saves properties in their hexadecimal representation.
For example, it saves 1.3
as 0x1.4cccccccccccdp+0
(which is equal to float.hex(1.3)
.
Is there a reason for that?
While graph-tool (and gephi) can import the saved graph back, this format perturbs other tools.
For example NetworkX: nx.read_graphml('graph_gt.graphml')
raises ValueError: could not convert string to float: '0x1.4cccccccccccdp+0'
.
If there's a good reason for graph-tool's behavior, is it a bug in NetworkX to not accept this graph back?
Note that this behavior exists for GraphML, not GML.
Steps to reproduce
When running the below code
import numpy as np
import graph_tool as gt
import networkx as nx
graph = gt.Graph(directed=False)
graph.add_edge(0, 1)
graph.add_edge(0, 2)
weight = graph.new_edge_property('float')
weight[(0, 1)] = 1.3
weight[(0, 2)] = 2.4
graph.edge_properties['weight'] = weight
graph.save('graph_gt.graphml')
graph.save('graph_gt.gml')
graph = nx.Graph()
graph.add_edge(0, 1, weight=1.3)
graph.add_edge(0, 2, weight=2.4)
nx.write_graphml(graph, 'graph_nx.graphml')
I get the following files:
graph_gt.graphml
:
<?xml version="1.0" encoding="UTF-8"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
<!-- property keys -->
<key id="key0" for="edge" attr.name="weight" attr.type="float" />
<graph id="G" edgedefault="undirected" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst">
<!-- graph properties -->
<!-- vertices -->
<node id="n0">
</node>
<node id="n1">
</node>
<node id="n2">
</node>
<!-- edges -->
<edge id="e0" source="n0" target="n1">
<data key="key0">0x1.4cccccccccccdp+0</data>
</edge>
<edge id="e1" source="n0" target="n2">
<data key="key0">0x1.3333333333333p+1</data>
</edge>
</graph>
</graphml>
graph_gt.gml
:
graph [
node [
id 0
]
node [
id 1
]
node [
id 2
]
edge [
id 0
source 0
target 1
weight 1.3
]
edge [
id 1
source 0
target 2
weight 2.4
]
]
graph_nx.graphml
:
<?xml version='1.0' encoding='utf-8'?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
<key attr.name="weight" attr.type="double" for="edge" id="d0" />
<graph edgedefault="undirected">
<node id="0" />
<node id="1" />
<node id="2" />
<edge source="0" target="1">
<data key="d0">1.3</data>
</edge>
<edge source="0" target="2">
<data key="d0">2.4</data>
</edge>
</graph>
</graphml>
If I replace weight = graph.new_edge_property('float')
by weight = graph.new_edge_property('int')
, I get the expected integer representation in graph_gt.graphml
:
<?xml version="1.0" encoding="UTF-8"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
<!-- property keys -->
<key id="key0" for="edge" attr.name="weight" attr.type="int" />
<graph id="G" edgedefault="undirected" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst">
<!-- graph properties -->
<!-- vertices -->
<node id="n0">
</node>
<node id="n1">
</node>
<node id="n2">
</node>
<!-- edges -->
<edge id="e0" source="n0" target="n1">
<data key="key0">1</data>
</edge>
<edge id="e1" source="n0" target="n2">
<data key="key0">2</data>
</edge>
</graph>
</graphml>