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 to color the node of the graph based on the column in the initial data input.
The relation DataFrame is as follows:
company client
Google AT&T
Google Cisco
Amazon Facebook
Amazon Snap
Amazon Microsoft
Apple Intel
Apple IBM
Apple Visa
The above snippet is only a portion of the DataFrame.
I would like all of the nodes from company to return in a different color to client.
The code below produces a network graph where all nodes are the same color.
G=nx.from_pandas_edgelist(relation, 'company', 'client')
# Show with Bokeh
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.glyph = Circle(size=20)
graph_renderer.edge_renderer.glyph = MultiLine(line_color="red", line_alpha=0.8, line_width=1)
plot.renderers.append(graph_renderer)
output_file("interactive_graphs.html")
show(plot)
Any assistance anyone could provide would be greatly appreciated.
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With