paulbrodersen / netgraph

Publication-quality network visualisations in python
GNU General Public License v3.0
660 stars 39 forks source link

Support for `EditableGraph` with no edges #62

Closed fsoupimenta closed 1 year ago

fsoupimenta commented 1 year ago

Hello, I'm working on a project that uses Netgraph, and when i tried to plot a graph without an edge, i got the following traceback:

assert len(edges) > 0, "The list of edges has to be non-empty."
AssertionError: The list of edges has to be non-empty

There is a way to plot a graph with no edges? Or implement it?

hdahmou commented 1 year ago

Hi,

Would you mind sharing a simple code example that replicates the issue you are experiencing? I have not been able to reproduce the issue on my end:

  import networkx as nx
  import netgraph

  g = nx.Graph()
  g.add_nodes_from([0, 1, 2, 3])

  I = netgraph.Graph(g)

output

Thanks

paulbrodersen commented 1 year ago

@fsoupimenta Graphs without edges used to be out-of-scope until somewhat recently. Make sure that you are using the latest version. If you do, then it is entirely possible that I forgot to handle graphs without edges in some place. In that case, could you please provide a minimal, working example that reproduces the issue, and a full error trace?

paulbrodersen commented 1 year ago

Note that empty graphs, i.e. graphs without nodes (and edges), are still out of scope at this time. You would have to catch these occurrences in your own code base, presumably right before you hand the graph data object to netgraph.

In the vast majority of use-cases that I can imagine, it makes sense to raise an error instead of handing back an empty canvas. This clearly communicates the problem (although admittedly the current error message could be made more precise) and minimizes superfluous compute time. The only place where handing back an empty canvas might make sense is in the EditableGraph class. However, this then raises several new problems as EditableGraph uses the existing node and edge artists to style any new ones that are created on-the-fly via hotkeys. If there are none, then the current approach doesn't work.

All of this is to say that if this issue does not boil down to a version problem, then I would be interested in learning more about your specific use-case. Also, a minimal working example seems quite essential if a bit of defensive programming around the netgraph call does not address the issue.

fsoupimenta commented 1 year ago

I realized that i was indeed using an outdated version, but when updating i got a new error.

My code has a class that inherits from EditableGraph, so i made a small code just to represent the same error:

    import matplotlib.pyplot as plt
    import networkx as nx
    from netgraph import EditableGraph

    graph = nx.Graph()
    graph.add_nodes_from([0, 1])
    plot_instance = EditableGraph(graph, scale=(2, 1), node_labels=True)

    plt.show()

And here is the traceback:

Traceback (most recent call last):
  File "C:\Users\Fernando Pimenta\Documents\Github\GraphFilter\source\view\project\docks\visualize_graph_dock.py", line 145, in <module>
    plot_instance = EditableGraph(graph, scale=(2, 1), node_labels=True)
  File "C:\Users\Fernando Pimenta\Documents\Github\GraphFilter\venv\lib\site-packages\netgraph\_interactive_variants.py", line 433, in __init__
    super().__init__(*args, **kwargs)
  File "C:\Users\Fernando Pimenta\Documents\Github\GraphFilter\venv\lib\site-packages\netgraph\_interactive_variants.py", line 63, in __init__
    self._last_selected_edge_properties = self._extract_edge_properties(next(iter(self.edge_artists.values())))
StopIteration

Process finished with exit code 1

I also did the same test using InteractiveGraph, and it works fine.

paulbrodersen commented 1 year ago

EditableGraph uses the existing node and edge artists to style any new ones that are created on-the-fly via hotkeys. If there are no edges, then you run into the error above. I hadn't considered this issue when I implemented support for graphs with no edges. I will look into it next week.

paulbrodersen commented 1 year ago

Version 4.12.5 supports empty graphs in the EditableGraph class. It uses the parameters provided during instantiation to style the nodes and edges.

import matplotlib.pyplot as plt

from netgraph import EditableGraph

g = []

# import networkx as nx
# g = nx.Graph()

# import igraph
# g = igraph.Graph()

# import graph_tool
# g = graph_tool.Graph()

h = EditableGraph(g, node_color='red', node_edge_color='red', edge_color='orange')
plt.show()

Feel free to re-open if you encounter any bugs.

paulbrodersen commented 1 year ago

I forgot about the case, where the graph contains nodes but no edges. Hold on...

paulbrodersen commented 1 year ago

Feel free to re-open if you encounter any more bugs.

fsoupimenta commented 1 year ago

I already tested it and it worked fine, thank you!