简体   繁体   中英

Scaling NetworkX nodes and edges proportional to adjacency matrix

Does NetworkX have a built-in way of scaling the nodes and edges proportional to the adjacency matrix frequency / node-node frequency? I am trying to scale the size of the nodes and text based on the adjacency matrix frequency and the weight of the edge based on the node-node frequency. I have created a frequency attribute for the graph, but that doesn't solve my problem of passing information to the graph about the node-node frequency.

So two part question:
1) What are best practices transferring an adjacency matrix into a networkX graph?
2) How do I use that information to scale the size of the nodes and the weight of the edges?

## Compute Graph (G)
G = nx.Graph(A)

## Add frequency of word as attribute of graph
def Freq_Attribute(G, A):
    frequency = {}  # Dictionary Declaration
    for node in G.nodes():
        frequency[str(node)] = A[str(node)][str(node)]
    return nx.set_node_attributes(G, 'frequency', frequency)

Freq_Attribute(g,A) # Adds attribute frequency to graph, for font scale

## Plot Graph with Labels
plt.figure(1, figsize=(10,10))

# Set location of nodes as the default
pos = nx.spring_layout(G, k=0.50, iterations=30)  

# Nodes
node_size = 10000
nodes1 = nx.draw_networkx_nodes(G,pos,
                       node_color='None',
                       node_size=node_size,
                       alpha=1.0)  # nodelist=[0,1,2,3],
nodes1.set_edgecolor('#A9C1CD') # Set edge color to black

# Edges
edges = nx.draw_networkx_edges(G,pos,width=1,alpha=0.05,edge_color='black')
edges.set_zorder(3)

# Labels
nx.draw_networkx_labels(G,pos,labels=nx.get_node_attributes(G,'label'),
                        font_size=16, 
                        font_color='#062D40',
                        font_family='arial')  # sans-serif, Font=16
# node_labels = nx.get_node_attributes(g, 'name') 
# Use 'g.graph' to find attribute(s): {'name': 'words'}

plt.axis('off')
#plt.show()

I have tried setting label font_size, but this didn't work.: font_size=nx.get_node_attributes(G,'frequency')) + 8)

I tried the following to match your need:

import networkx as nx
import matplotlib.pyplot as plt

## create nx graph from adjacency matrix
def create_graph_from_adj(A):
    # A=[(n1, n2, freq),....]
    G = nx.Graph()
    for a in A:
        G.add_edge(a[0], a[1], freq=a[2])
    return G

A = [(0, 1, 0.5), (1, 2, 1.0), (2, 3, 0.8), (0, 2, 0.2), (3, 4, 0.1), (2, 4, 0.6)]
## Compute Graph (G)
G = create_graph_from_adj(A)

plt.subplot(121)

# Set location of nodes as the default
spring_pose = nx.spring_layout(G, k=0.50, iterations=30)  

nx.draw_networkx(G,pos=spring_pose)


plt.subplot(122)
# Nodes
default_node_size = 300
default_label_size = 12
node_size_by_freq = []
label_size_by_freq = []
for n in G.nodes():
    sum_freq_in = sum([G.edge[n][t]['freq'] for t in G.neighbors(n)])
    node_size_by_freq.append(sum_freq_in*default_node_size)
    label_size_by_freq.append(int(sum_freq_in*default_label_size))

nx.draw_networkx_nodes(G,pos=spring_pose,
                       node_color='red',
                       node_size=node_size_by_freq,
                       alpha=1.0)  
nx.draw_networkx_labels(G,pos=spring_pose,
                        font_size=12,  #label_size_by_freq is not allowed
                        font_color='#062D40',
                        font_family='arial') 

# Edges
default_width = 5.0
edge_width_by_freq = []
for e in G.edges():
    edge_width_by_freq.append(G.edge[e[0]][e[1]]['freq']*default_width)
nx.draw_networkx_edges(G,pos=spring_pose,
                       width=edge_width_by_freq,
                       alpha=1.0,
                       edge_color='black')

plt.show()

在此处输入图片说明

First of all, the adjacency reaction is not given in Matrix format, but IMHO that's too tedious.

Secondly, nx.draw_networkx_labels does not allow different font size for the labels. Can't help there.

Last, the edge width and node size however allows that. So they are scaled based on its frequency and summation of incoming frequency, respectively.

Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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