在网络上的节点间距xplotly网络和标签。

问题描述 投票:0回答:1

(...

edges = df.stack().reset_index()
edges.columns = ['var_1','var_2','correlation']
edges = edges.loc[ (edges['correlation'] < -0.6) | (edges['correlation'] > 0.6) & (edges['var_1'] != edges['var_2']) ].copy()

#create undirected graph with weights corresponding to the correlation magnitude
G0 = nx.from_pandas_edgelist(edges, 'var_1', 'var_2', edge_attr=['correlation'])

mst = G0
# assign colours to edges depending on positive or negative correlation
# assign edge thickness depending on magnitude of correlation
edge_colours = []
edge_width = []
for key, value in nx.get_edge_attributes(mst, 'correlation').items():
    edge_colours.append(assign_colour(value))
    edge_width.append(assign_thickness(value))

node_size = []
degrees = [val for key, val in dict(G0.degree).items()]
max_deg = max(degrees)
min_deg = min(degrees)
for value in degrees:
    node_size.append(assign_node_size(value,min_deg,max_deg))



#draw the network:
nx.draw(mst, pos=nx.fruchterman_reingold_layout(mst),
        node_size=15, edge_color=edge_colours, node_colour="black",
        edge_width=0.2)
plt.show()

def get_coordinates(G=mst):
    """Returns the positions of nodes and edges in a format for Plotly to draw the network"""
    # get list of node positions
    pos = nx.fruchterman_reingold_layout(mst)

    Xnodes = [pos[n][0] for n in mst.nodes()]
    Ynodes = [pos[n][1] for n in mst.nodes()]

    Xedges_red = []
    Yedges_red = []
    Xedges_green = []
    Yedges_green = []

    def insert_edge(Xedges, Yedges):
        Xedges.extend([pos[e[0]][0], pos[e[1]][0], None])
        Yedges.extend([pos[e[0]][1], pos[e[1]][1], None])

    search_dict = nx.get_edge_attributes(mst, 'correlation')
    for e in mst.edges():
        correlation = search_dict[(e[0], e[1])]
        if correlation <= 0 :  # red_edges
          insert_edge(Xedges_red, Yedges_red)
        else:
          insert_edge(Xedges_green, Yedges_green)
        # x coordinates of the nodes defining the edge e

    return Xnodes, Ynodes, Xedges_red, Yedges_red, Xedges_green, Yedges_green

node_label = list(mst.nodes())
node_label = [fix_string(x) for x in node_label]

# get coordinates for nodes and edges
Xnodes, Ynodes, Xedges_red, Yedges_red, Xedges_green, Yedges_green = get_coordinates()

external_data = [list(x) for x in coding_names_df.values]
external_data = {fix_string(x[0]): x[1] for x in external_data}
external_data2 = [list(y) for y in coding_names_df.values]
external_data2 = {fix_string(y[0]): y[2] for y in external_data2}
external_data3 = [list(z) for z in coding_names_df.values]
external_data3 = {fix_string(z[0]): z[3] for z in external_data3}
external_data4 = [list(s) for s in coding_names_df.values]
external_data4 = {fix_string(s[0]): s[4] for s in external_data4}




# =============================================================================
description = [f"<b>{index}) {node}</b>"
                "<br><br>Realm: " +
                "<br>" + external_data.get(node, 'No external data found') +
                "<br><br>Type: " +
                "<br>" + external_data2.get(node, 'No external data found')
               for index, node in enumerate(node_label)]
# =============================================================================

# def nodes colours:
node_colour = [assign_node_colour(node, external_data3, coding_names_df) for node in node_label]
node_shape = [assign_node_shape(node, external_data4, coding_names_df) for node in node_label]
# edges
# negative:
tracer_red = go.Scatter(x=Xedges_red, y=Yedges_red,
                    mode='lines',
                    line= dict(color="#FA0000", width=1),
                    hoverinfo='none',
                    showlegend=False)
# positive:
tracer_green = go.Scatter(x=Xedges_green, y=Yedges_green,
                    mode='lines',
                    line= dict(color= "#29A401", width=1),
                    hoverinfo='none',
                    showlegend=False)

# nodes
tracer_marker = go.Scatter(x=Xnodes, y=Ynodes,
                           mode='markers+text',
                           textposition='top center',
                           marker=dict(size=node_size,
                                            line=dict(width=0.8, color='black'),
                                            color=node_colour,
                                                                    symbol=node_shape),
                                       hovertext=description,
                           hoverinfo='text',
                           textfont=dict(size=7),
                           showlegend=False)

axis_style = dict(title='',
                  titlefont=dict(size=20),
                  showgrid=False,
                  zeroline=False,
                  showline=False,
                  ticks='',
                  showticklabels=False)

layout = dict(title='',
              width=1300,
              height=900,
              autosize=False,
              showlegend=False,
              xaxis=axis_style,
              yaxis=axis_style,
              hovermode='closest',
             plot_bgcolor = '#fff')

fig = dict(data=[tracer_red, tracer_green, tracer_marker], layout=layout)
display(HTML("""<p>Node sizes are proportional to the size of annualised returns.<br>
                Node colours signify positive or negative returns since beginning of the timeframe.</p> """))
plot(fig)

Something you could try is setting the parameter in the layout algorithm, which as mentioned in the

docs

  1. it sets:
  2. k

: (float (default=None)) – Optimal distance between nodes. If None the distance is set to 1

然后我得到了这个图
python plotly networkx
1个回答
0
投票

我怎样才能把中间的间距拉开?(但还是要保持fruchterman_reingold的特性)k我怎么能只添加一些特定的标签?任何帮助将是graet! Tnx:)

  • 我使用 networkx 和 plotly 创建了一个网络,如下所示: edges = df.stack().reset_index() edges.columns = ['var_1','var_2','correlation'] edges = edges.loc[ (edges['correlation'] < -0.6) sqrt(n) 其中 n 是节点数。增加这个值可以使节点之间的距离更远。

所以通过玩一玩这个值,并相应增加,我们可以得到一个更分散的布局,并避免节点标签之间的重叠.这里有一个简单的例子来说明行为是什么。

result_set = {('plant','tree'), ('tree','oak'), ('flower', 'rose'), ('flower','daisy'), ('plant','flower'), ('tree','pine'), ('plant','roots'), ('animal','fish'),('animal','bird'), ('bird','robin'), ('bird','falcon'), ('animal', 'homo'),('homo','homo-sapiens'), ('animal','reptile'), ('reptile','snake'),('fungi','mushroom'), ('fungi','mold'), ('fungi','toadstool'),('reptile','crocodile'), ('mushroom','Portabello'), ('mushroom','Shiitake'),('pine','roig'),('pine','pinyer'), ('tree','eucaliptus'),('rose','Floribunda'),('rose','grandiflora')}
G=nx.from_edgelist(result_set)

pos=nx.fruchterman_reingold_layout(G)
plt.figure(figsize=(8,5))
nx.draw(G, pos=pos,
        with_labels=True, 
        nodesize=1000, 
        node_color='lightgreen')

enter image description here

如果我们增加这个值 k0.5我们在布局中得到一个很好的节点分布。

pos_spaced=nx.fruchterman_reingold_layout(G, k=0.5, iterations=100)

plt.figure(figsize=(10,6))
nx.draw(G,
        pos=pos_spaced,
        with_labels=True, 
        nodesize=1000, 
        node_color='lightgreen')

enter image description here

我怎么能只添加几个特定的标签?

为此,您可以设置 labels 中的参数 draw 到一个包含您希望显示的标签的字典。如果节点名称与标签相同,只需创建一个字典映射到 node->node 以下是:

show_labels = ['plant', 'tree', 'oak', 'eucaliptus']

pos_spaced=nx.fruchterman_reingold_layout(G, k=0.54, iterations=100)

plt.figure(figsize=(10,6))
nx.draw(G,
        pos=pos_spaced,
        with_labels=True, 
        nodesize=1000, 
        labels=dict(zip(show_labels,show_labels)),
        node_color='lightgreen')

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.