pythongraphnetworkx

Networkx graph from nested dict containing lists


Question

Given the following dict as input:

{'apple': [{'colours': ['red', 'yellow', 'green']}, {'type': ['granny smith']}, {'price': ['0.10']}]}

How do I create a graph, with the following edges, using networkx:

enter image description here

What have I tried?

I can create a simple graph but not containing all the edges:

g = nx.Graph(d["apple"][0])

Solution

  • Fairly straightforward with a recursive function, as your data structure always has a key mapping to a list, and each item in the list is either another dictionary (on which you can recurse) or a leaf node.

    enter image description here

    #!/usr/bin/env python
    import matplotlib.pyplot as plt
    import networkx as nx
    
    from netgraph import Graph # pip install netgraph
    
    def parse(data):
        edges = []
        if isinstance(data, dict):
            for key, items in data.items():
                for item in items:
                    if isinstance(item, dict):
                        edges.extend([(key, subitem) for subitem in item])
                        edges.extend(parse(item))
                    else:
                        edges.append((key, item))
        return edges
    
    
    if __name__ == '__main__':
    
        sample_data = {'apple': [{'colours': ['red', 'yellow', 'green']}, {'type': ['granny smith']}, {'price': ['0.10']}]}
        edges = parse(sample_data)
        g = nx.from_edgelist(edges, create_using=nx.DiGraph)
        Graph(g, node_layout='dot', node_labels=True, node_label_fontdict=dict(size=20),
              edge_color='black', edge_alpha=1., edge_width=0.1, node_edge_width=0.)
        plt.show()