简体   繁体   中英

How to align nodes and edges in networkx

I am going through an O'Reilly data science book and it gives you the python code to more or less create this node viz ...

在此处输入图像描述

But it doesn't tell you how to make the viz as its not really relevant to the subject but I wanted to take a crack at it anyway and so far this is as close as I've come

users = [
{ "id": 0, "name": "Hero" },
{ "id": 1, "name": "Dunn" },
{ "id": 2, "name": "Sue" },
{ "id": 3, "name": "Chi" },
{ "id": 4, "name": "Thor" },
{ "id": 5, "name": "Clive" },
{ "id": 6, "name": "Hicks" },
{ "id": 7, "name": "Devin" },
{ "id": 8, "name": "Kate" },
{ "id": 9, "name": "Klein" },
{ "id": 10, "name": "Jen" }
]

friendships = [(0, 1), (0, 2), (1, 2), (1, 3), (2, 3), (3, 4),
           (4, 5), (5, 6), (5, 7), (6, 8), (7, 8), (8, 9)]

import networkx as nx
import matplotlib as plt
%matplotlib inline
G=nx.Graph()
G.add_nodes_from([user["id"] for user in users])
G.add_edges_from(friendships)
pos = nx.spring_layout(G)
nx.draw_networkx(G, pos, node_size=1000)

在此处输入图像描述

This is brand new to me both python and networkx - I can't seem to figure out from their documentation what actual graph I should be using - I tried just about every one of them and none get me there - is it possible in networkx to align nodes this way and what is the correct graph to use?

Is networkx the right tool for this job is there a better python lib for this task?

UPDATE

@Aric answer was perfect but I made a couple changes to make the nodes match the data rather than the static type array. I don't think this is the 'best' way to do the calculation someone with more python experience would know better. I played with the minimum sizes and positions for a bit and STILL I could not get it pixel perfect but still I'm pretty happy with the end result

import networkx as nx
import matplotlib.pyplot as plt
G=nx.Graph()
G.add_nodes_from([user["id"] for user in users])
G.add_edges_from(friendships)
pos = {0: [0,0],
       1: [4,-0.35],
       2: [4,0.35],
       3: [8,0],
       4: [12,0],
       5: [16,0],
       6: [20,0.35],
       7: [20,-0.35],
       8: [24,0],
       9: [28,0],
       10: [32,0]}

nodes = [user["id"] for user in users]
def calcSize(node):
    minSize = 450
    friends = number_of_friends(node)
    if friends <= 0:
        return minSize
    return minSize * friends

node_size = [(calcSize(user)) for user in users]
nx.draw_networkx(G, pos, nodelist=nodes, node_size=node_size, node_color='#c4daef')
plt.ylim(-1,1)
plt.axis('off')

You can do something similar with NetworkX. You'll need use a different layout method than "spring_layout" or set the node positions explicitly like this:

import networkx as nx
import matplotlib.pyplot as plt
G=nx.Graph()
G.add_nodes_from([user["id"] for user in users])
G.add_edges_from(friendships)
pos = {0: [0,0],
       1: [1,-0.25],
       2: [1,0.25],
       3: [2,0],
       4: [3,0],
       5: [4,0],
       6: [5,0.25],
       7: [5,-0.25],
       8: [6,0],
       9: [7,0],
       10: [8,0]}

nodes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
node_size = [500, 1000, 1000, 1000,  500, 1000, 500, 500 , 1000, 300, 300]
nx.draw_networkx(G, pos, nodelist=nodes, node_size=node_size, node_color='#c4daef')
plt.ylim(-1,1)
plt.axis('off')

在此处输入图像描述

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