如何在 NetworkX 中的其余节点上为前 20 个节点着色
How to color the top 20 nodes over the rest of the nodes in NetworkX
有谁知道如何在 NetworkX 的其余节点上为前 20 个节点着色?
我想用绿色为前 20 个节点着色,其余为灰色。
但是,输出仅显示灰色,因为绿色节点位于灰色节点下方。
是否可以在灰色节点上制作那些绿色节点?
此外,是否可以显示前 20 个绿色节点的大小为 20,其余灰色节点的大小为 10?当前,所有节点的大小都为 10。
尝试:
设置一个MRE
import pandas as pd
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import string
df = pd.DataFrame({'ID': list(string.ascii_uppercase),
'PageRank': np.random.randint(10, 100, len(string.ascii_uppercase))})
top_5_lst = df.sort_values('PageRank')['ID'].head(5).tolist()
not_top_5_lst = df.loc[~df['ID'].isin(top_5_lst), 'ID'].tolist()
edges = pd.DataFrame({'from': np.random.choice(list(string.ascii_uppercase), 1000),
'to': np.random.choice(list(string.ascii_uppercase), 1000)})
G = nx.from_pandas_edgelist(edges, source='from', target='to')
为了达到您的期望,您必须手动控制图形绘制,尤其是 z 顺序。你可以这样做:
# Compute positions
pos = nx.spring_layout(G)
# Draw nodes not in top5
pc1 = nx.draw_networkx_nodes(G, pos, nodelist=not_top_5_lst,
node_color='gray', node_size=10)
# Draw top5 nodes
pc2 = nx.draw_networkx_nodes(G, pos, nodelist=top_5_lst,
node_color='#00D992', node_size=20)
pc2.zorder = 3 # set z-order to 3 (2 by default for gray nodes)
# Draw edges
lc = nx.draw_networkx_edges(G, pos, width=0.2)
plt.show()
应@Corralien 的要求,我将尝试添加一些内容。
如果您可以使用非 networkx 包,您也可以使用 Plotly 执行您要求的操作,这提供了交互性的额外好处。您可以按照类似的示例 here
设置完全相同的 MRE
import pandas as pd
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import plotly.graph_objects as go
import string
df = pd.DataFrame({'ID': list(string.ascii_uppercase),
'PageRank': np.random.randint(10, 100, len(string.ascii_uppercase))})
top_5_lst = df.sort_values('PageRank')['ID'].head(5).tolist()
not_top_5_lst = df.loc[~df['ID'].isin(top_5_lst), 'ID'].tolist()
edges = pd.DataFrame({'from': np.random.choice(list(string.ascii_uppercase), 1000),
'to': np.random.choice(list(string.ascii_uppercase), 1000)})
G = nx.from_pandas_edgelist(edges, source='from', target='to')
pos = nx.spring_layout(G)
将页面排名设置为节点的属性。我们将使用它来添加工具提示
rank_dict = dict(zip(df.ID, df.PageRank))
for entry in rank_dict:
rank_dict[entry] = {'Page Rank': rank_dict[entry]}
nx.set_node_attributes(G, rank_dict)
设置边缘:
edge_x = []
edge_y = []
for edge in G.edges():
x0, y0 = pos[edge[0]]
x1, y1 = pos[edge[1]]
edge_x.append(x0)
edge_x.append(x1)
edge_x.append(None)
edge_y.append(y0)
edge_y.append(y1)
edge_y.append(None)
edge_trace = go.Scatter(
x=edge_x, y=edge_y,
line=dict(width=0.5, color='#888'),
hoverinfo='none',
mode='lines')
为页面排名前 5 的节点和其余节点各设置一个跟踪。
# Not Top 5 Nodes
g1_node_x = []
g1_node_y = []
g1_texts = []
# Top 5 Nodes
g2_node_x = []
g2_node_y = []
g2_texts = []
for node in G.nodes():
x, y = pos[node]
if node in not_top_5_lst:
g1_node_x.append(x)
g1_node_y.append(y)
g1_texts.append('Page Rank: '+str(G.nodes[node]['Page Rank']))
else:
g2_node_x.append(x)
g2_node_y.append(y)
g2_texts.append('Page Rank: '+str(G.nodes[node]['Page Rank']))
node_trace = go.Scatter(
x=g1_node_x, y=g1_node_y,
mode='markers',
hoverinfo='text',
marker=dict(
color='grey',
size=10,
line_width=2))
node_trace2 = go.Scatter(
x=g2_node_x, y=g2_node_y,
mode='markers',
hoverinfo='text',
marker=dict(
color='green',
size=20,
line_width=2))
node_trace.text = g1_texts
node_trace2.text = g2_texts
最后,创建您的绘图并添加每条轨迹。然后根据需要更新布局。按照添加到轨迹中的顺序对元素进行绘图排序,因此只要顶部元素节点绘制在底部元素节点之后,它们就会出现在前面
fig = go.Figure(edge_trace)
fig = fig.add_trace(node_trace)
fig = fig.add_trace(node_trace2)
fig = fig.update_layout(titlefont_size=16,
showlegend=False,
hovermode='closest',
margin=dict(b=20,l=5,r=5,t=40),
annotations=[ dict(
text="",
showarrow=False,
xref="paper", yref="paper",
x=0.005, y=-0.002 ) ],
xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
yaxis=dict(showgrid=False, zeroline=False, showticklabels=False)
fig.show()
结果:
有谁知道如何在 NetworkX 的其余节点上为前 20 个节点着色? 我想用绿色为前 20 个节点着色,其余为灰色。 但是,输出仅显示灰色,因为绿色节点位于灰色节点下方。 是否可以在灰色节点上制作那些绿色节点?
此外,是否可以显示前 20 个绿色节点的大小为 20,其余灰色节点的大小为 10?当前,所有节点的大小都为 10。
尝试:
设置一个MRE
import pandas as pd
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import string
df = pd.DataFrame({'ID': list(string.ascii_uppercase),
'PageRank': np.random.randint(10, 100, len(string.ascii_uppercase))})
top_5_lst = df.sort_values('PageRank')['ID'].head(5).tolist()
not_top_5_lst = df.loc[~df['ID'].isin(top_5_lst), 'ID'].tolist()
edges = pd.DataFrame({'from': np.random.choice(list(string.ascii_uppercase), 1000),
'to': np.random.choice(list(string.ascii_uppercase), 1000)})
G = nx.from_pandas_edgelist(edges, source='from', target='to')
为了达到您的期望,您必须手动控制图形绘制,尤其是 z 顺序。你可以这样做:
# Compute positions
pos = nx.spring_layout(G)
# Draw nodes not in top5
pc1 = nx.draw_networkx_nodes(G, pos, nodelist=not_top_5_lst,
node_color='gray', node_size=10)
# Draw top5 nodes
pc2 = nx.draw_networkx_nodes(G, pos, nodelist=top_5_lst,
node_color='#00D992', node_size=20)
pc2.zorder = 3 # set z-order to 3 (2 by default for gray nodes)
# Draw edges
lc = nx.draw_networkx_edges(G, pos, width=0.2)
plt.show()
应@Corralien 的要求,我将尝试添加一些内容。 如果您可以使用非 networkx 包,您也可以使用 Plotly 执行您要求的操作,这提供了交互性的额外好处。您可以按照类似的示例 here
设置完全相同的 MRE
import pandas as pd
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import plotly.graph_objects as go
import string
df = pd.DataFrame({'ID': list(string.ascii_uppercase),
'PageRank': np.random.randint(10, 100, len(string.ascii_uppercase))})
top_5_lst = df.sort_values('PageRank')['ID'].head(5).tolist()
not_top_5_lst = df.loc[~df['ID'].isin(top_5_lst), 'ID'].tolist()
edges = pd.DataFrame({'from': np.random.choice(list(string.ascii_uppercase), 1000),
'to': np.random.choice(list(string.ascii_uppercase), 1000)})
G = nx.from_pandas_edgelist(edges, source='from', target='to')
pos = nx.spring_layout(G)
将页面排名设置为节点的属性。我们将使用它来添加工具提示
rank_dict = dict(zip(df.ID, df.PageRank))
for entry in rank_dict:
rank_dict[entry] = {'Page Rank': rank_dict[entry]}
nx.set_node_attributes(G, rank_dict)
设置边缘:
edge_x = []
edge_y = []
for edge in G.edges():
x0, y0 = pos[edge[0]]
x1, y1 = pos[edge[1]]
edge_x.append(x0)
edge_x.append(x1)
edge_x.append(None)
edge_y.append(y0)
edge_y.append(y1)
edge_y.append(None)
edge_trace = go.Scatter(
x=edge_x, y=edge_y,
line=dict(width=0.5, color='#888'),
hoverinfo='none',
mode='lines')
为页面排名前 5 的节点和其余节点各设置一个跟踪。
# Not Top 5 Nodes
g1_node_x = []
g1_node_y = []
g1_texts = []
# Top 5 Nodes
g2_node_x = []
g2_node_y = []
g2_texts = []
for node in G.nodes():
x, y = pos[node]
if node in not_top_5_lst:
g1_node_x.append(x)
g1_node_y.append(y)
g1_texts.append('Page Rank: '+str(G.nodes[node]['Page Rank']))
else:
g2_node_x.append(x)
g2_node_y.append(y)
g2_texts.append('Page Rank: '+str(G.nodes[node]['Page Rank']))
node_trace = go.Scatter(
x=g1_node_x, y=g1_node_y,
mode='markers',
hoverinfo='text',
marker=dict(
color='grey',
size=10,
line_width=2))
node_trace2 = go.Scatter(
x=g2_node_x, y=g2_node_y,
mode='markers',
hoverinfo='text',
marker=dict(
color='green',
size=20,
line_width=2))
node_trace.text = g1_texts
node_trace2.text = g2_texts
最后,创建您的绘图并添加每条轨迹。然后根据需要更新布局。按照添加到轨迹中的顺序对元素进行绘图排序,因此只要顶部元素节点绘制在底部元素节点之后,它们就会出现在前面
fig = go.Figure(edge_trace)
fig = fig.add_trace(node_trace)
fig = fig.add_trace(node_trace2)
fig = fig.update_layout(titlefont_size=16,
showlegend=False,
hovermode='closest',
margin=dict(b=20,l=5,r=5,t=40),
annotations=[ dict(
text="",
showarrow=False,
xref="paper", yref="paper",
x=0.005, y=-0.002 ) ],
xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
yaxis=dict(showgrid=False, zeroline=False, showticklabels=False)
fig.show()
结果: