I want to visualize a sequence of graphs where one is edited into another one edit step at a time. One subtask in doing this is to create the intermediate graphs between a source graph and a target graph.
networkx.optimal_edit_paths
looks like a promising tool for getting the required information for each intermediate graph, but I find the output a little difficult to interpret as-is.
Let us take their example from the documentation:
import networkx as nx
G1 = nx.cycle_graph(4)
G2 = nx.wheel_graph(5)
paths, cost = nx.optimal_edit_paths(G1, G2)
Now taking a look inside paths
I see this output:
[([(0, 0), (1, 1), (2, 2), (3, 3), (None, 4)], [((0, 1), (0, 1)), ((1, 2), (1, 2)), (None, (0, 2)), ((0, 3), (0, 3)), ((2, 3), (2, 3)), (None, (0, 4)), (None, (1, 4)), (None, (3, 4))]), ([(0, 0), (1, 1), (None, 2), (3, 3), (2, 4)], [((0, 1), (0, 1)), (None, (0, 2)), (None, (1, 2)), ((0, 3), (0, 3)), (None, (2, 3)), ((1, 2), (1, 4)), ((2, 3), (3, 4)), (None, (0, 4))]), ([(0, 0), (2, 1), (1, 2), (None, 3), (3, 4)], [(None, (0, 1)), ((0, 1), (0, 2)), ((1, 2), (1, 2)), (None, (0, 3)), (None, (2, 3)), ((0, 3), (0, 4)), ((2, 3), (1, 4)), (None, (3, 4))]), ([(0, 0), (2, 1), (3, 2), (None, 3), (1, 4)], [(None, (0, 1)), ((0, 3), (0, 2)), ((2, 3), (1, 2)), (None, (0, 3)), (None, (2, 3)), ((0, 1), (0, 4)), ((1, 2), (1, 4)), (None, (3, 4))]), ([(0, 0), (3, 1), (2, 2), (1, 3), (None, 4)], [((0, 3), (0, 1)), ((2, 3), (1, 2)), (None, (0, 2)), ((0, 1), (0, 3)), ((1, 2), (2, 3)), (None, (0, 4)), (None, (1, 4)), (None, (3, 4))]), ([(0, 0), (3, 1), (None, 2), (1, 3), (2, 4)], [((0, 3), (0, 1)), (None, (0, 2)), (None, (1, 2)), ((0, 1), (0, 3)), (None, (2, 3)), ((1, 2), (3, 4)), ((2, 3), (1, 4)), (None, (0, 4))]), ([(0, 0), (None, 1), (1, 2), (2, 3), (3, 4)], [(None, (0, 1)), ((0, 1), (0, 2)), (None, (1, 2)), ((1, 2), (2, 3)), (None, (0, 3)), ((0, 3), (0, 4)), ((2, 3), (3, 4)), (None, (1, 4))]), ([(0, 0), (None, 1), (3, 2), (2, 3), (1, 4)], [(None, (0, 1)), ((0, 3), (0, 2)), (None, (1, 2)), ((2, 3), (2, 3)), (None, (0, 3)), ((0, 1), (0, 4)), ((1, 2), (3, 4)), (None, (1, 4))]), ([(1, 0), (0, 1), (3, 2), (2, 3), (None, 4)], [((0, 1), (0, 1)), ((0, 3), (1, 2)), (None, (0, 2)), ((1, 2), (0, 3)), ((2, 3), (2, 3)), (None, (0, 4)), (None, (1, 4)), (None, (3, 4))]), ([(1, 0), (0, 1), (None, 2), (2, 3), (3, 4)], [((0, 1), (0, 1)), (None, (0, 2)), (None, (1, 2)), ((1, 2), (0, 3)), (None, (2, 3)), ((0, 3), (1, 4)), ((2, 3), (3, 4)), (None, (0, 4))]), ([(1, 0), (2, 1), (3, 2), (0, 3), (None, 4)], [((1, 2), (0, 1)), ((2, 3), (1, 2)), (None, (0, 2)), ((0, 1), (0, 3)), ((0, 3), (2, 3)), (None, (0, 4)), (None, (1, 4)), (None, (3, 4))]), ([(1, 0), (2, 1), (None, 2), (0, 3), (3, 4)], [((1, 2), (0, 1)), (None, (0, 2)), (None, (1, 2)), ((0, 1), (0, 3)), (None, (2, 3)), ((0, 3), (3, 4)), ((2, 3), (1, 4)), (None, (0, 4))]), ([(1, 0), (3, 1), (0, 2), (None, 3), (2, 4)], [(None, (0, 1)), ((0, 1), (0, 2)), ((0, 3), (1, 2)), (None, (0, 3)), (None, (2, 3)), ((1, 2), (0, 4)), ((2, 3), (1, 4)), (None, (3, 4))]), ([(1, 0), (3, 1), (2, 2), (None, 3), (0, 4)], [(None, (0, 1)), ((1, 2), (0, 2)), ((2, 3), (1, 2)), (None, (0, 3)), (None, (2, 3)), ((0, 1), (0, 4)), ((0, 3), (1, 4)), (None, (3, 4))]), ([(1, 0), (None, 1), (0, 2), (3, 3), (2, 4)], [(None, (0, 1)), ((0, 1), (0, 2)), (None, (1, 2)), ((0, 3), (2, 3)), (None, (0, 3)), ((1, 2), (0, 4)), ((2, 3), (3, 4)), (None, (1, 4))]), ([(1, 0), (None, 1), (2, 2), (3, 3), (0, 4)], [(None, (0, 1)), ((1, 2), (0, 2)), (None, (1, 2)), ((2, 3), (2, 3)), (None, (0, 3)), ((0, 1), (0, 4)), ((0, 3), (3, 4)), (None, (1, 4))]), ([(2, 0), (0, 1), (1, 2), (None, 3), (3, 4)], [(None, (0, 1)), ((0, 1), (1, 2)), ((1, 2), (0, 2)), (None, (0, 3)), (None, (2, 3)), ((0, 3), (1, 4)), ((2, 3), (0, 4)), (None, (3, 4))]), ([(2, 0), (0, 1), (3, 2), (None, 3), (1, 4)], [(None, (0, 1)), ((0, 3), (1, 2)), ((2, 3), (0, 2)), (None, (0, 3)), (None, (2, 3)), ((0, 1), (1, 4)), ((1, 2), (0, 4)), (None, (3, 4))]), ([(2, 0), (1, 1), (0, 2), (3, 3), (None, 4)], [((1, 2), (0, 1)), ((0, 1), (1, 2)), (None, (0, 2)), ((0, 3), (2, 3)), ((2, 3), (0, 3)), (None, (0, 4)), (None, (1, 4)), (None, (3, 4))]), ([(2, 0), (1, 1), (None, 2), (3, 3), (0, 4)], [((1, 2), (0, 1)), (None, (0, 2)), (None, (1, 2)), ((2, 3), (0, 3)), (None, (2, 3)), ((0, 1), (1, 4)), ((0, 3), (3, 4)), (None, (0, 4))]), ([(2, 0), (3, 1), (0, 2), (1, 3), (None, 4)], [((2, 3), (0, 1)), ((0, 3), (1, 2)), (None, (0, 2)), ((0, 1), (2, 3)), ((1, 2), (0, 3)), (None, (0, 4)), (None, (1, 4)), (None, (3, 4))]), ([(2, 0), (3, 1), (None, 2), (1, 3), (0, 4)], [((2, 3), (0, 1)), (None, (0, 2)), (None, (1, 2)), ((1, 2), (0, 3)), (None, (2, 3)), ((0, 1), (3, 4)), ((0, 3), (1, 4)), (None, (0, 4))]), ([(2, 0), (None, 1), (1, 2), (0, 3), (3, 4)], [(None, (0, 1)), ((1, 2), (0, 2)), (None, (1, 2)), ((0, 1), (2, 3)), (None, (0, 3)), ((0, 3), (3, 4)), ((2, 3), (0, 4)), (None, (1, 4))]), ([(2, 0), (None, 1), (3, 2), (0, 3), (1, 4)], [(None, (0, 1)), ((2, 3), (0, 2)), (None, (1, 2)), ((0, 3), (2, 3)), (None, (0, 3)), ((0, 1), (3, 4)), ((1, 2), (0, 4)), (None, (1, 4))]), ([(3, 0), (0, 1), (1, 2), (2, 3), (None, 4)], [((0, 3), (0, 1)), ((0, 1), (1, 2)), (None, (0, 2)), ((1, 2), (2, 3)), ((2, 3), (0, 3)), (None, (0, 4)), (None, (1, 4)), (None, (3, 4))]), ([(3, 0), (0, 1), (None, 2), (2, 3), (1, 4)], [((0, 3), (0, 1)), (None, (0, 2)), (None, (1, 2)), ((2, 3), (0, 3)), (None, (2, 3)), ((0, 1), (1, 4)), ((1, 2), (3, 4)), (None, (0, 4))]), ([(3, 0), (1, 1), (0, 2), (None, 3), (2, 4)], [(None, (0, 1)), ((0, 1), (1, 2)), ((0, 3), (0, 2)), (None, (0, 3)), (None, (2, 3)), ((1, 2), (1, 4)), ((2, 3), (0, 4)), (None, (3, 4))]), ([(3, 0), (1, 1), (2, 2), (None, 3), (0, 4)], [(None, (0, 1)), ((1, 2), (1, 2)), ((2, 3), (0, 2)), (None, (0, 3)), (None, (2, 3)), ((0, 1), (1, 4)), ((0, 3), (0, 4)), (None, (3, 4))]), ([(3, 0), (2, 1), (1, 2), (0, 3), (None, 4)], [((2, 3), (0, 1)), ((1, 2), (1, 2)), (None, (0, 2)), ((0, 1), (2, 3)), ((0, 3), (0, 3)), (None, (0, 4)), (None, (1, 4)), (None, (3, 4))]), ([(3, 0), (2, 1), (None, 2), (0, 3), (1, 4)], [((2, 3), (0, 1)), (None, (0, 2)), (None, (1, 2)), ((0, 3), (0, 3)), (None, (2, 3)), ((0, 1), (3, 4)), ((1, 2), (1, 4)), (None, (0, 4))]), ([(3, 0), (None, 1), (0, 2), (1, 3), (2, 4)], [(None, (0, 1)), ((0, 3), (0, 2)), (None, (1, 2)), ((0, 1), (2, 3)), (None, (0, 3)), ((1, 2), (3, 4)), ((2, 3), (0, 4)), (None, (1, 4))]), ([(3, 0), (None, 1), (2, 2), (1, 3), (0, 4)], [(None, (0, 1)), ((2, 3), (0, 2)), (None, (1, 2)), ((1, 2), (2, 3)), (None, (0, 3)), ((0, 1), (3, 4)), ((0, 3), (0, 4)), (None, (1, 4))]), ([(None, 0), (0, 1), (1, 2), (2, 3), (3, 4)], [(None, (0, 1)), ((0, 1), (1, 2)), (None, (0, 2)), ((1, 2), (2, 3)), (None, (0, 3)), ((0, 3), (1, 4)), ((2, 3), (3, 4)), (None, (0, 4))]), ([(None, 0), (0, 1), (3, 2), (2, 3), (1, 4)], [(None, (0, 1)), ((0, 3), (1, 2)), (None, (0, 2)), ((2, 3), (2, 3)), (None, (0, 3)), ((0, 1), (1, 4)), ((1, 2), (3, 4)), (None, (0, 4))]), ([(None, 0), (1, 1), (0, 2), (3, 3), (2, 4)], [(None, (0, 1)), ((0, 1), (1, 2)), (None, (0, 2)), ((0, 3), (2, 3)), (None, (0, 3)), ((1, 2), (1, 4)), ((2, 3), (3, 4)), (None, (0, 4))]), ([(None, 0), (1, 1), (2, 2), (3, 3), (0, 4)], [(None, (0, 1)), ((1, 2), (1, 2)), (None, (0, 2)), ((2, 3), (2, 3)), (None, (0, 3)), ((0, 1), (1, 4)), ((0, 3), (3, 4)), (None, (0, 4))]), ([(None, 0), (2, 1), (1, 2), (0, 3), (3, 4)], [(None, (0, 1)), ((1, 2), (1, 2)), (None, (0, 2)), ((0, 1), (2, 3)), (None, (0, 3)), ((0, 3), (3, 4)), ((2, 3), (1, 4)), (None, (0, 4))]), ([(None, 0), (2, 1), (3, 2), (0, 3), (1, 4)], [(None, (0, 1)), ((2, 3), (1, 2)), (None, (0, 2)), ((0, 3), (2, 3)), (None, (0, 3)), ((0, 1), (3, 4)), ((1, 2), (1, 4)), (None, (0, 4))]), ([(None, 0), (3, 1), (0, 2), (1, 3), (2, 4)], [(None, (0, 1)), ((0, 3), (1, 2)), (None, (0, 2)), ((0, 1), (2, 3)), (None, (0, 3)), ((1, 2), (3, 4)), ((2, 3), (1, 4)), (None, (0, 4))]), ([(None, 0), (3, 1), (2, 2), (1, 3), (0, 4)], [(None, (0, 1)), ((2, 3), (1, 2)), (None, (0, 2)), ((1, 2), (2, 3)), (None, (0, 3)), ((0, 1), (3, 4)), ((0, 3), (1, 4)), (None, (0, 4))])]
Picking out just the first element of this list:
>>> paths[0]
([(0, 0), (1, 1), (2, 2), (3, 3), (None, 4)], [((0, 1), (0, 1)), ((1, 2), (1, 2)), (None, (0, 2)), ((0, 3), (0, 3)), ((2, 3), (2, 3)), (None, (0, 4)), (None, (1, 4)), (None, (3, 4))])
And then the first element of the first element:
>>> paths[0][0]
[(0, 0), (1, 1), (2, 2), (3, 3), (None, 4)]
And then the first element deeper:
>>> paths[0][0][0]
(0, 0)
The "Returns" section of the documentation is given as:
Returns:
edit_pathslist of tuples (node_edit_path, edge_edit_path)
node_edit_path : list of tuples (u, v) edge_edit_path : list of tuples ((u1, v1), (u2, v2))
I also noted that:
>>> [len(i) for i in paths]
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
I assume these give information about how each edit is applied, but I have not quite grasped what is going on from the terse explanation in the documentation.
How do I correctly interpret the output in terms of how edits were iteratively applied?