Assign color to NetworkX node based on column name

前端 未结 2 1573
Happy的楠姐
Happy的楠姐 2021-01-07 10:56

I am attempting to build a network graph using NetworkX and Bokeh. I am using the NetworkX from_pandas_edgelist function to add data for the graph. I would like

相关标签:
2条回答
  • 2021-01-07 11:04

    Good question, and accepted answer (from which I was able to extend my code to give colored nodes based on the Pandas dataframe column).

    import warnings
    warnings.filterwarnings("ignore", category=UserWarning)
    
    import networkx as nx
    import matplotlib.pyplot as plt
    import pandas as pd
    
    df = pd.read_csv('pers_org.tsv', sep='\t')
    # (TSV copied from a PostgreSQL database, hence the "id" column.)
    df.sort_values(by=['id'])
    '''
          id          person      organization
      0    1  Robert_Bigelow             BAASS
      1    2  Robert_Bigelow             AATIP
      2    3  Robert_Bigelow              NIDS
      3    4  Robert_Bigelow  Skinwalker_Ranch
      14   5   Luis_Elizondo             AATIP
      4    6   Colm_Kelleher             AATIP
      5    7   Colm_Kelleher              NIDS
      6    8   Colm_Kelleher  Skinwalker_Ranch
      7    9     Tom_DeLonge              TTSA
      8   10   Luis_Elizondo              TTSA
      9   11     Hal_Puthoff              TTSA
      10  12    Chris_Mellon              TTSA
      11  13   Douglas_Kurth           US_Navy
      12  14   Douglas_Kurth          Lockheed
      13  15   Douglas_Kurth             BAASS
    '''
    
    G = nx.from_pandas_edgelist(df, source='person', target='organization', \
        create_using=nx.DiGraph)
    colors = []
    for node in G:
        if node in df["person"].values:
            colors.append("lightblue")
        else: colors.append("lightgreen")
    
    print(colors)
    # ['lightblue', 'lightgreen', 'lightgreen', 'lightgreen', 'lightgreen',
    #  'lightblue', 'lightblue', 'lightgreen', 'lightblue', 'lightblue',
    #  'lightblue', 'lightblue', 'lightgreen', 'lightgreen']
    
    plt.figure(figsize=(15,10))
    # <Figure size 1500x1000 with 0 Axes>
    
    nx.draw(G, pos = nx.nx_pydot.graphviz_layout(G), \
        node_size=1200, node_color=colors, linewidths=0.25, \
        font_size=10, font_weight='bold', with_labels=True)
    plt.show()
    

    See also How to set colors for nodes in networkx python?

    pers_org.tsv

    id  person  organization
    1   Robert_Bigelow  BAASS
    2   Robert_Bigelow  AATIP
    3   Robert_Bigelow  NIDS
    4   Robert_Bigelow  Skinwalker_Ranch
    5   Luis_Elizondo   AATIP
    6   Colm_Kelleher   AATIP
    7   Colm_Kelleher   NIDS
    8   Colm_Kelleher   Skinwalker_Ranch
    9   Tom_DeLonge TTSA
    10  Luis_Elizondo   TTSA
    11  Hal_Puthoff TTSA
    12  Chris_Mellon    TTSA
    13  Douglas_Kurth   US_Navy
    14  Douglas_Kurth   Lockheed
    15  Douglas_Kurth   BAASS
    
    


    Although I did not do this here, if you want to add node borders and thicken the node border lines (node edge thickness: linewidths), do the following.

    nx.draw(G, pos = nx.nx_pydot.graphviz_layout(G), \
        node_size=1200, node_color=colors, linewidths=2.0, \
        font_size=10, font_weight='bold', with_labels=True)
    
    # Get current axis:
    ax = plt.gca()
    ax.collections[0].set_edgecolor('r')
    # r : red (can also use #FF0000) | b : black (can also use #000000) | ...
    plt.show()
    
    0 讨论(0)
  • 2021-01-07 11:13

    After the old Edit:

    Can't give too much context as I am not super familiar with bokeh, but looks like you can use a similar approach to what I did initially just instead of passing the "color_map" do your draw function you have to stick your data in here graph_renderer.node_renderer.data_source.data['colors'] Anyway this seems to do the job, Good luck dude.

    relation = pd.DataFrame({
                    "company":["Google", "Google", "Amazon", "Amazon", "Amazon",
                                "Apple", "Apple", "Apple"],
                    "client":["AT&T", "Cisco", "Facebook", "Snap", "Microsoft",
                              "Intel", "IBM", "Visa"]})
    
    G=nx.from_pandas_edgelist(relation, 'company', 'client')
    colors = []
    
    for node in G:
        if node in relation["client"].values:
            colors.append("blue")
        else: colors.append("green")
    
    plot = Plot(plot_width=1000, plot_height=800,
                x_range=Range1d(-1.1, 1.1), y_range=Range1d(-1.1, 1.1))
    plot.title.text = "Company - Client Network"
    
    node_hover_tool = HoverTool(tooltips=[("Company Name", "@index")])
    plot.add_tools(node_hover_tool, BoxZoomTool(), ResetTool())
    
    graph_renderer = from_networkx(G, nx.spring_layout, scale=1, center=(0, 0))
    
    graph_renderer.node_renderer.data_source.data['colors'] = colors
    graph_renderer.node_renderer.glyph = Circle(size=20, fill_color='colors')
    
    graph_renderer.edge_renderer.glyph = MultiLine(line_color="red", line_alpha=0.8, line_width=1)
    plot.renderers.append(graph_renderer)
    
    output_file("boo.html")
    show(plot)
    
    
    
    0 讨论(0)
提交回复
热议问题