pythongraphnetworkxgraph-visualizationknowledge-graph

NetworkX multigraph plot does not show labels


I am trying to plot a knowledge graph using Python, have looked at many examples and answers, but still did not manage to plot the edge labels automatically from an edgelist. Here is a reduced working example of what I am trying to do:

import pandas as pd
import networkx as nx
minidf = pd.DataFrame(data={'relation': ['subject', 'subject', 'broader'], 
                       'source': ['pmt3423', 'pmt2040', 'category:myoblasts'], 
                       'target': ['conceito', 'frio', 'category:non-terminally_differentiated_(blast)']})
miniG = nx.from_pandas_edgelist(minidf,'source', 'target',
                      edge_key='relation', create_using=nx.MultiDiGraph())
nx.draw_networkx(miniG, with_labels=True)

The output I get is the following:

Graph without labels

I have also tried draw_circular and others. I have also tried using pyvis and generating a dot file + converting to png using neato. Didn't quite get it yet. Any help is appreciated.


Solution

  • Here is how you can add edge labels to your graph:

    import pandas as pd
    import networkx as nx
    from matplotlib import pyplot as plt
    
    minidf = pd.DataFrame(data = {'relation': ['subject', 'subject', 'broader'],
                           'source': ['pmt3423', 'pmt2040', 'category:myoblasts'],
                           'target': ['conceito', 'frio', 'category:non-terminally_differentiated_(blast)']})
    
    miniG = nx.from_pandas_edgelist(minidf,'source', 'target', create_using=nx.MultiDiGraph())
    
    pos = nx.spring_layout(miniG)
    e_labels = {(minidf.source[i], minidf.target[i]):minidf.relation[i]
              for i in range(len(minidf['relation']))}
    
    nx.draw_networkx_edge_labels(miniG, pos, edge_labels= e_labels)
    nx.draw(miniG, pos = pos,with_labels=True)
    plt.show()
    

    enter image description here

    However, as you see above, this can be messy because there is not much room for edge labels in your graph. A better solution would be to color-code the edges and provide a legend:

    import pandas as pd
    import networkx as nx
    from matplotlib import pyplot as plt
    
    minidf = pd.DataFrame(data = {'relation': ['subject', 'subject', 'broader'],
                           'source': ['pmt3423', 'pmt2040', 'category:myoblasts'],
                           'target': ['conceito', 'frio', 'category:non-terminally_differentiated_(blast)']})
    
    miniG = nx.from_pandas_edgelist(minidf,'source', 'target', create_using=nx.MultiDiGraph())
    
    #color-code the edges
    color_code = {'subject':'red', 'broader':'lime'}
    edge_color_list = [color_code[rel] for rel in minidf.relation]
    nx.draw(miniG, with_labels= True, edge_color= edge_color_list)
    
    #create a color-coded legend
    leg = plt.legend(color_code,labelcolor=color_code.values())
    for i, item in enumerate(leg.legendHandles):
        item.set_color(list(color_code.values())[i])
    
    plt.show()
    

    enter image description here