epfl-lts2 / pygsp

Graph Signal Processing in Python
https://pygsp.rtfd.io
BSD 3-Clause "New" or "Revised" License
483 stars 93 forks source link

Import export #32

Closed cgallay closed 5 years ago

cgallay commented 6 years ago

Hi @mdeff , Here is the PR for the "issue31" So that we can talk directly about it. Let me know what's need to be improved or any other comment.

coveralls commented 6 years ago

Coverage Status

Coverage decreased (-4.9%) to 77.547% when pulling 7847448a712113bb63047e3b112dfdaa3a697cc7 on cgallay:importExport into 638663798462c851e8f853ec6f65e6f2e4956d44 on epfl-lts2:master.

coveralls commented 6 years ago

Coverage Status

Coverage increased (+0.4%) to 87.054% when pulling bea1a1f20cdd8101332d558e1d75d053937abd19 on cgallay:importExport into 78034de01bac9959764c5aa85b87e126e69247c2 on epfl-lts2:master.

coveralls commented 6 years ago

Coverage Status

Coverage decreased (-4.7%) to 77.68% when pulling 7847448a712113bb63047e3b112dfdaa3a697cc7 on cgallay:importExport into 638663798462c851e8f853ec6f65e6f2e4956d44 on epfl-lts2:master.

mdeff commented 5 years ago

If you execute the below code, you can open graph_nx.graphml in gephi and it will show the below figure. That's awesome! :)

import numpy as np
import networkx as nx
import pygsp as pg

graph = pg.graphs.Logo()
graph.estimate_lmax()

DELTAS = [20, 30, 1090]
signal = np.zeros(graph.n_nodes)
signal[DELTAS] = 1
signal = pg.filters.Heat(graph, tau=50).filter(signal)

graph.set_signal(graph.coords[:, 0], 'x')
graph.set_signal(graph.coords[:, 1], 'y')
graph.set_signal(signal, 'diffusion')

graph_nx = graph.to_networkx()

nx.write_graphml(graph_nx, 'graph_nx.graphml')
#nx.write_gml(graph_nx, 'graph_nx.gml')
#nx.write_gexf(graph_nx, 'graph_nx.gexf')

2018-10-04-16 56 35

The export to gml and gexf does however not work. Can you investigate why?

The three works with graph-tool, but the graphml seems broken.

graph_gt = graph.to_graphtool(directed=False)
graph_gt.save('graph_gt.gml')
graph_gt.save('graph_gt.graphml')
graph_gt.save('graph_gt.dot')

I would suggest to export with all combinations of library and format, then look with a text editor if the files are fine. Then open them in gephi and cytoscape and look if everything (number of nodes, edges, edge weight, node properties, directed/undirected) is fine.

Another observation: graph_gt.graphml contains edges in both direction (a waste for undirected graphs), whereas 'graph_nx.graphml` only specify one of the edges. Networkx seems to do the right thing here. Is there a way to fix the graph-tool export?

mdeff commented 5 years ago

Importing seems to work with networkx and graphml:

g = nx.read_graphml('graph_nx.graphml')
g = pg.graphs.Graph.from_networkx(g, singals_names=['x', 'y', 'diffusion'])
g.coords = np.stack([g.signals['x'], g.signals['y']]).T
g.plot_signal(g.signals['diffusion'])

For graph-tool, it works with graphml and gml, but not dot:

g = gt.load_graph('graph_gt.graphml')
g = gt.load_graph('graph_gt.gml')
# g = gt.load_graph('graph_gt.dot')
g = pg.graphs.Graph.from_graphtool(g, singals_names=['x', 'y', 'diffusion'])
g.coords = np.stack([g.signals['x'], g.signals['y']]).T
g.plot_signal(g.signals['diffusion'])

Loading graph_gt.dot raises RuntimeError: Wanted right bracket to end attribute list (token is "<identifier> '7.96389'").

Exporting with networkx and importing with graph-tool works (i.e., g = gt.load_graph('graph_nx.graphml'). But exporting with graph-tool and importing with networkx does not, g = nx.read_graphml('graph_gt.graphml') raises ValueError: could not convert string to float: '0x1.83d2501c48897p-7'. There is something fishy with graph-tool graphml export.

mdeff commented 5 years ago

Add an autosummary to graphs/__init__.py under an "Import and export" section, so that the methods are linked from the top of the reference/graphs.html documentation. You can put the get_edge_list function there as well (currently in "Others").

mdeff commented 5 years ago

I see two problems with docker on travis:

  1. Currently, it seems to be tested with one version of python only. That can probably be fixed easily.
  2. We will need to build and upload the docker image to dockerhub. That shouldn't be done by hand.

As that is only for graph-tool, my impression is that it's easier and more maintainable to install graph-tool on the ubuntu image used by travis. Combining the graph-tool installation instructions and the travis documentation, it should be a matter of adding the following lines to .travis.yml:

addons:
  apt:
    sources:
    - sourceline: 'deb https://downloads.skewed.de/apt/xenial xenial universe'
      key_url: 'https://pgp.skewed.de/pks/lookup?op=get&search=0x612DEFB798507F25'
    packages:
    - python-graph-tool
    - python3-graph-tool
mdeff commented 5 years ago

The implementation has been cleaned up in #46. Thanks @cgallay!