我正在尝试使用NetworkX和Bokeh构建网络图。我正在使用NetworkX from_pandas_edgelist
函数为图形添加数据。我想根据初始数据输入中的列为图的节点着色。
relation
数据帧如下:
company client
Google AT&T
Google Cisco
Amazon Facebook
Amazon Snap
Amazon Microsoft
Apple Intel
Apple IBM
Apple Visa
上面的代码片段只是DataFrame的一部分。
我希望company
中的所有节点以与client
不同的颜色返回。
下面的代码生成一个网络图,其中所有节点都是相同的颜色。
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)
任何人都能提供的帮助将不胜感激。
答案 0 :(得分:3)
在旧的Edit之后:
不能提供太多的上下文信息,因为我对bokeh并不十分熟悉,但是看起来您可以使用与我最初所做的类似的方法,而不必通过“ color_map”来完成绘制功能,因此必须粘贴graph_renderer.node_renderer.data_source.data['colors']
中的数据
无论如何,好运,老兄。
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)
答案 1 :(得分:0)
一个好问题,一个可以接受的答案(通过它我可以将代码扩展为基于Pandas数据框列的彩色节点)。
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()
另请参阅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
尽管我在这里没有这样做,但是如果要添加节点边界并加粗节点边界线(节点边缘厚度:linewidths
),请执行以下操作。
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()