pythongraphipycytoscape

layout of ipycytoscape for directed graphs arrow disapearing


I have the following code to generate and plot a graph with ipycytoscape:

from ipycytoscape import CytoscapeWidget
import networkx as nx
cyto = CytoscapeWidget()
nodes = [1,2,3,4,5,6,7,8]
children = [[2],[3,4],[5,6],[6,7],[8],[],[8],[]]
G2 = nx.Graph()
G2.add_nodes_from(nodes)
for i,child in enumerate(children):
    for c in child:
        G2.add_edge(i+1, c)

cyto.graph.add_graph_from_networkx(G2, directed=True)
cyto.set_layout(name='dagre', nodeSpacing=10, edgeLengthVal=10)
display(cyto)

So far so good: enter image description here

Now if I add a layout, whatever it is

cyto_style = [{ 'selector' : 'node',
                'style': {'font-family': 'arial',
                         'font-size': '10px',
                         'label': 'data(id)'}}]
cyto.set_style(cyto_style)
display(cyto)

enter image description here

THE ARROWS DISAPPEAR !!! NO DIRECTIONALITY PLOTTING. What should i do to make the arrows stay there as they were before adding style?


Solution

  • This happens because cytoscape.js, the library which ipycytoscape draws from need to have the following style configuration to show up arrows:

                {
                    "selector": "edge.directed",
                    "style": {
                        "curve-style": "bezier",
                        "target-arrow-shape": "triangle",
                        "target-arrow-color": "#9dbaea",
                    },
                },
    

    (Of course you can change the shape and color of the arrow, but it's necessary to specify these three attrs in order to see them).

    The problem here is that because of traitlets implementation (the library in which Jupyter lab depends on to sync the backend with the frontend attrs) doesn't offer support to deep objects like lists or dictionaries. In other words, it's only syncing simple objects like ints and strings automatically. Fortunately, I was able to overcome this issue in ipycytoscape using a library called spectate. However, spectate doesn't seem to be able to sync nested deep objects, aka, a dict inside a dict as we have when creating styles.

    I spent a while looking at it today but couldn't really figure out how to fix it. I'll try a bit more tomorrow. Please consider following the issue as I'm not active in stack overflow. Also, if you're up for trying to fix it, please let me know. I'm around for answering questions and to discuss ideas. Cheers.