简体   繁体   English

如何在 Plotly Dash 的 networkx 图中单独更改节点大小

[英]How to change the node sizes individually in a networkx graph in Plotly Dash

I am creating a networkx graph and while developing in Python I can change the node size using the following code in networkx.draw_shell() -我正在创建一个 networkx 图,在 Python 中开发时,我可以使用 networkx.draw_shell() 中的以下代码更改节点大小 -

vertices = df_final.columns.values.tolist()
edges = [((u,v),df_final[u].corr(df_final[v])) for u,v in itertools.combinations(vertices, 2)]
edges = [(u,v,{'weight': abs(c)}) for (u,v),c in edges if abs(c) >= 0.5]
G = networkx.Graph()

G.add_edges_from(edges)

size = F_imp.Score.to_list()

from matplotlib.pyplot import figure

figure(figsize=(9,9), dpi=500)

networkx.draw_shell(G, with_labels=True, node_size= (np.array(size) *10000), font_size=8)
plt.show()

But when I am trying to integrate the same plot in Dash, I can't use the networkx.draw_shell() in built function anymore and hence can't use the node_size attribute anymore.但是当我试图在 Dash 中集成相同的 plot 时,我不能在内置的 function 中使用 networkx.draw_shell() ,因此不能再使用 node_size 属性。 Rather I have to transform the network graph into a plotly graph in the following way -相反,我必须通过以下方式将网络图转换为 plotly 图 -

vertices = df_final.columns.values.tolist()
edges = [((u,v),df_final[u].corr(df_final[v])) for u,v in itertools.combinations(vertices, 2)]
#edges = [(u,v,{'weight': c}) for (u,v),c in edges if abs(c) >= 0.5]
edges = [(u,v,{'weight': abs(c)}) for (u,v),c in edges if abs(c) >= 0.5]
G = networkx.Graph()

G.add_edges_from(edges)

#size = F_imp.Score.to_list()

pos = networkx.shell_layout(G)

networkx.shell_layout

import plotly.graph_objects as go
# edges trace
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(color='black', width=1),
    hoverinfo='none',
    showlegend=False,
    mode='lines')

# nodes trace
node_x = []
node_y = []
text = []
for node in G.nodes():
    x, y = pos[node]
    node_x.append(x)
    node_y.append(y)
    text.append(node)

node_trace = go.Scatter(
    x=node_x, y=node_y, text=text,
    mode='markers+text',
    showlegend=False,
    hoverinfo='none',
    marker=dict(
        color='pink',
        size=50,
        line=dict(color='black', width=1)))

# size nodes by degree
# deg_dict = {deg[0]:int(deg[1]) for deg in list(G.degree())}
# for node, degree in enumerate(deg_dict):
#     node_trace['marker']['size'] = (deg_dict[degree])

# layout
layout = dict(plot_bgcolor='white',
              paper_bgcolor='white',
              margin=dict(t=10, b=10, l=10, r=10, pad=0),
              xaxis=dict(linecolor='black',
                         showgrid=False,
                         showticklabels=False,
                         mirror=True),
              yaxis=dict(linecolor='black',
                         showgrid=False,
                         showticklabels=False,
                         mirror=True))

# figure
fig = go.Figure(data=[edge_trace, node_trace], layout=layout)


fig

This does generate the network graph but I am not being able to assign different node sizes to the nodes based on some score as I could in the first case.这确实会生成网络图,但我无法像在第一种情况下那样根据某些分数为节点分配不同的节点大小。

The size component in the node_trace['marker']['size'] seems to be applicable for all nodes and cannot be changed for each node. node_trace['marker']['size'] 中的大小组件似乎适用于所有节点,并且不能针对每个节点进行更改。 Here I tried to change the node size as per degree.在这里,我尝试根据度数更改节点大小。 The code has been commented out above under #size nodes by degree代码已在上面的 #size 个节点下按程度注释掉

As reference, I have followed the following questions -作为参考,我遵循了以下问题 -

  1. Plotly Dash: Plotting networkx in Python Plotly 破折号:在 Python 中绘制网络 x
  2. Customizing a Networkx graph (or Scatter) with Python Plotly 使用 Python Plotly 自定义 Networkx 图(或散点图)

Does anyone know the solution?有谁知道解决方案?

You can define a dictionary containing the node sizes and pass it list to the node_trace variable.您可以定义包含节点大小的字典并将其列表传递给node_trace变量。

I do not have your dataset, so I made just a small example.我没有你的数据集,所以我只做了一个小例子。

Let's say this is your dictionary containing the sizes:假设这是包含大小的字典:

node_size = {
        'Brown bear': 4,
        'fur': 3,
        'claw': 3,
        'sharp': 2,
        'brown': 2 
        }

While looping over your nodes, you create a list that contains the sizes of the corresponding nodes:在遍历节点时,您会创建一个包含相应节点大小的列表:

# nodes trace
node_x = []
node_y = []
text = []
sizes = []

for node in G.nodes():
    x, y = pos[node]
    node_x.append(x)
    node_y.append(y)
    text.append(node)
    # Append the sizes
    size = node_size[node]
    sizes.append(size)

You pass this list as a parameter to the go.Scatter() :您将此列表作为参数传递给go.Scatter()

node_trace = go.Scatter(
    x=node_x, y=node_y, text=text,
    mode='markers+text',
    showlegend=False,
    # Add the sizes,
    size=node_sizes,
    hoverinfo='none',
    marker=dict(
        color='pink',
        size=50,
        line=dict(color='black', width=1)))

Run the rest of your code, and your plot has not variable node sizes.运行代码的 rest,并且您的 plot 没有可变节点大小。 See my output screenshot as example:以我的 output 截图为例:

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM