I'm new to Qt and Netgraph, and I'd like to develop a Qt application with graph construction at its core. NetGraph's EditableGraph function meets my expectations and seems great. However, I also need to continuously update another structure based on the graph incrementally while it is constructed. For instance, I want to print the nodes and arcs of the graph as they are created.
Is it possible to retrieve the graph structure during its construction by EditableGraph and process it incrementally?
Otherwise I would have to design an interactive graph construction function with this functionality.
The EditableGraph
class (like all classes derived from Graph
) maintains several data structures to keep track of all plot elements.
node_positions
maps nodes to their (x, y) coordinates (their center),edge_paths
maps edges to their coordinate paths,node_artists
/ edge_artists
map nodes / edges to the corresponding matplotlib.patches.PathPatch
artists,node_label_artists
/ edge_label_artists
map node / edge labels to the corresponding matplotlib.text.Text
instances.The matplotlib patch artists can themselves be queried to determine their visual properties such as their color, e.g. my_editable_graph_instance.node_artists[42].get_facecolor()
. The same holds for the label artists.
from netgraph import EditableGraph
g = EditableGraph([(0, 1)], node_labels=True, edge_labels=True)
print(g.node_positions)
# {0: array([0.95, 0.5 ]), 1: array([0.05, 0.5 ])}
print(g.edge_paths)
# {(0, 1): array([[0.95, 0.5 ], [0.05, 0.5 ]])}
print(g.node_artists)
# {0: <netgraph._artists.NodeArtist at 0x7f7d5d2d68e0>,
# 1: <netgraph._artists.NodeArtist at 0x7f7d5d2d6b80>}
print(g.node_artists[0].get_facecolor())
# (1.0, 1.0, 1.0, 1.0)
print(g.node_label_artists)
# {0: Text(0.05, 0.5, '0'), 1: Text(0.9500000000000001, 0.5, '1')}
print(g.node_label_artists[0].get_weight())
# normal
print(g.edge_artists)
# {(0, 1): <netgraph._artists.EdgeArtist at 0x7f7d0f0c89a0>}
print(g.edge_label_artists)
# {(0, 1): Text(0.5, 0.5, '(0, 1)')}
The data structures are updated on key press events (insert/+ and delete/-), but to prevent race conditions, you may want to hook into draw events instead as the canvas is redrawn after all data structures are up-to-date.
import matplotlib.pyplot as plt
from netgraph import EditableGraph
fig, ax = plt.subplots()
g = EditableGraph([(0, 1)], ax=ax)
def trigger_update(event):
# Here should go your logic to update your own data structures.
# For this mock-up, we just print some information.
print(g.node_positions)
print(g.edge_paths)
fig.canvas.mpl_connect('draw_event', trigger_update)
plt.show()
This project may be of interest, as it uses Netgraph within a Qt application. I imagine they faced many of the same issues as you will / do.