cytoscape / ipycytoscape

A Cytoscape Jupyter widget
https://ipycytoscape.readthedocs.io/en/master/
BSD 3-Clause "New" or "Revised" License
268 stars 62 forks source link

Pandas Example does not show how edges work #328

Open avowkind opened 2 years ago

avowkind commented 2 years ago

Problem

I cannot work out how to get edges from a pandas table using add_graph_from_df.

The add_graph_from_df code takes an edges tuple. edges=tuple() with comment that the first item is the source edge and the second is the target edge.

However the pandas notebook example does not set any edges and it is unclear what the tuple is supposed to represent. As it is not a list of edges I guess that it might be the column names or indexes in the data frame that represent edges.

Testing with this code

# initialize simple 3 node list.
nodes = [
  ['node-1', 10, 'A', 'node-1', 'node-2'], 
  ['node-2', 15, 'A', 'node-2', 'node-3'],
  ['node-3', 20, 'A', ],
]

# Create the pandas DataFrame
node_df = pd.DataFrame(nodes, columns=['name', 'score', 'group', 'source', 'target'])

cyw = cy.CytoscapeWidget()
cyw.graph.add_graph_from_df(node_df, ['group'], ['name', 'score'], edges=('source', 'target'), directed=True)  

creates the following cyw.graph.nodes

[Node(data={'id': 'parent-0', 'name': ('A',)}, position={}),
 Node(data={'id': 0, 'parent': 'parent-0', 'name': 'name: node-1\nscore: 10\n'}, position={}),
 Node(data={'id': 1, 'parent': 'parent-0', 'name': 'name: node-2\nscore: 15\n'}, position={}),
 Node(data={'id': 2, 'parent': 'parent-0', 'name': 'name: node-3\nscore: 20\n'}, position={})]

but cyw.graph.edges is and empty array []

setting edges to (3,4) also returns an empty edges array. even trying something like edges=('node-1', 'node-2') creates no edges.

Reviewing the source code for add_graph_from_df we see an edge is created with source set to the first tuple item and target set to the second.

 if not all(edges):
...
 graph_edges.append(
                    Edge(
                        data={
                            "id": index,
                            "source": edges[0],
                            "target": edges[1],
                            "classes": classes,
                        }
                    )
                )

This means the edge is only added if one of the items in the tuple is false. if we set edges to (0,1,False) we get an edge added [Edge(data={'id': 0, 'source': 0, 'target': 1, 'classes': ''})]

we also get the 0 and 1 nodes reset with no name data although I'm not clear why.

[Node(data={'id': 0}, position={}),
 Node(data={'id': 1}, position={}),
 Node(data={'id': 'parent-0', 'name': ('A',)}, position={}),
 Node(data={'id': 2, 'parent': 'parent-0', 'name': 'name: node-3\nscore: 20\n'}, position={})]

and no matter how many times we run through the iterator we will only get the one link. Although n identical edges are added they appear to be de-duplicated. No visible line is drawn between the nodes. - this appears if id is removed from the edge.

Is the edges tuple supposed to be some kind of function that returns successive values?