使用networkx吸引三个人的共同朋友联系 [英] Draw common friends connections of three people using networkx

查看:101
本文介绍了使用networkx吸引三个人的共同朋友联系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有3个人(可以选择添加更多人),我想将每个人的朋友列表显示为一个圈子.因此,每人1个圈子.接下来,如果两个人有相同的朋友,我想添加边(连接).

I have three people (with option of adding more people) and I want to show each person friends list as a circle. So, 1 circle per person. Next, I want to add edges(connections) if two people have same friend.

Mike_friends = ['Al', 'Niki', 'Silvia', 'Anna', 'Matt', 'Gia', 'Nick', 'Maud', 'Sarah', 'Lisa', 'Kelvin']
Alex_friends = ['Harvey', 'Steve', 'Michael', 'Maud', 'Al', 'Kam', 'Hank']
Stephen_friends = ['Lisa','Rosie','Mango','Kate','Nate','Maud','Kelvin','Elvis','Arstad','Jesus','Johan','Jay','Gia','Niki','Harvey','Paul','Mike','Alex','Anna']
import networkx as nx
import matplotlib.pyplot as plt

def link_networks(N1, N2, N3, N4=None, N5=None, N6=None, N7=None, N8=None, N9=None):
    G = nx.Graph()
    for item1 in N1:
        for item2 in N2:
            for item3 in N3:
                if item1 in N1 == item2 in N2:
                    G.add_edge(item1, item2)
                elif item1 in N1 == item3 in N3:
                    G.add_edge(item1, item3)
                elif item2 in N2 == item3 in N3:
                    G.add_edge(item2, item3)
link_networks(Mike_friends, Alex_friends, Stephen_friends)
plt.figure(figsize = (20, 10))
mytitle = "friend circle connections"
plt.title(mytitle, fontsize=40)
nx.draw_networkx(G, font_size=10, node_size=2000, alpha=0.6)
plt.savefig("friend_circles.pdf")

问题:我得到一个空的数字,有连接的3个圆圈没有显示.感谢帮助.删除了"Return G".

The problem: I get empty figure, 3 circles with connections do not show up. Thanks for help. Removed 'Return G'.

推荐答案

这是一种实现方法.首先,您发现有多少个普通朋友有Mike,Alex和Stephen.我通过使用set来做到这一点;这是迈克和亚历克斯的例子.

Here is one way of doing it. First you find how many common friends have Mike, Alex and Stephen. I do this by using set; here's the example for Mike and Alex.

M_A_common = len(set(Mike_friends) & set(Alex_friends))

我图中的节点称为MikeAlexStephen.在下面,我设置边缘Mike -- Alex,使其值为M_A_common.

The nodes in my graph are called Mike, Alex and Stephen. Below I set the edge Mike -- Alex so it has the value of M_A_common.

G.add_edge('Mike', 'Alex', common_friends=M_A_common)

这是所有朋友的完整示例,其中我使用nx.draw绘制了网络,并使用了nx.draw_networkx_edge_labels绘制了边缘标签.

Here is the full example with all friends where I draw the network with nx.draw and the edge labels with nx.draw_networkx_edge_labels.

import networkx as nx
import matplotlib.pyplot as plt

Mike_friends = ['Al', 'Niki', 'Silvia', 'Anna', 'Matt', 'Gia', 'Nick', 'Maud', 'Sarah', 'Lisa', 'Kelvin']
Alex_friends = ['Harvey', 'Steve', 'Michael', 'Maud', 'Al', 'Kam', 'Hank']
Stephen_friends = ['Lisa','Rosie','Mango','Kate','Nate','Maud','Kelvin','Elvis','Arstad','Jesus','Johan','Jay','Gia','Niki','Harvey','Paul','Mike','Alex','Anna']

G = nx.Graph()
G.add_node('Mike')
G.add_node('Alex')
G.add_node('Stephen')

M_A_common = len(set(Mike_friends) & set(Alex_friends))  # number of common friends
M_S_common = len(set(Mike_friends) & set(Stephen_friends))  # number of common friends
S_A_common = len(set(Stephen_friends) & set(Alex_friends))  # number of common friends

G.add_edge('Mike', 'Alex', common_friends=M_A_common)
G.add_edge('Mike', 'Stephen', common_friends=M_S_common)
G.add_edge('Stephen', 'Alex', common_friends=S_A_common)

pos = nx.circular_layout(G)
nx.draw(G, pos, node_size=2000, with_labels=True)
edge_labels = nx.get_edge_attributes(G, 'common_friends')
nx.draw_networkx_edge_labels(G, pos, labels=edge_labels)
plt.show()

例如,您可以写一些常见的朋友,而不必写一些用边缘粗细显示常用朋友的数量.

Instead of writing the number of common friends you could e.g. show the amount of common friends with edge thickness.

当然,有了更多的朋友,您将拥有更多的组合,因此您可能希望自动计算常见朋友.

Of course, with more friends you will have more combinations so you'll probably want to automate the calculation of common friends.

此外,如果您希望每个共同的朋友有多个优势,则需要使用MultiGraph而不是Graph.要绘制多个边缘,请此处.

Also, if you want multiple edges for each common friend you need to use MultiGraph instead of Graph. For drawing multiple edges take a look here.

要为上面的代码添加自定义节点标签(例如,节点名称+好友总数),可以使用nx.draw_networkx_labels,如下所示:

To add custom node labels (e.g. node name + number of total friends) for the code above you could use nx.draw_networkx_labels like this:

pos = nx.circular_layout(G)
nx.draw(G, pos, node_size=2000, with_labels=False)
node_labels = {
    'Mike': 'Mike (' + str(len(Mike_friends)) + ' total)',
    'Alex': 'Alex (' + str(len(Alex_friends)) + ' total)',
    'Stephen': 'Stephen (' + str(len(Stephen_friends)) + ' total)'
}
nx.draw_networkx_labels(G, pos, labels=node_labels)
edge_labels = nx.get_edge_attributes(G, 'common_friends')
nx.draw_networkx_edge_labels(G, pos, labels=edge_labels)
plt.show()

如果您有20个朋友,则上面的代码会变得非常混乱.下面是一种更优雅的方法,其中将节点及其朋友存储在名为friends的字典中.

If you had 20 friends the code above would get really messy. Below is a more elegant approach where I store the nodes and their friends in a dictionary called friends.

要获得所有可能的优势,我使用 itertools.combinations

To get all possible edges I use itertools.combinations

import networkx as nx
import matplotlib.pyplot as plt
from itertools import combinations

G = nx.Graph()
friends = {
    'Mike': ['Al', 'Niki', 'Silvia', 'Anna', 'Matt', 'Gia', 'Nick', 'Maud', 'Sarah', 'Lisa', 'Kelvin'],
    'Alex': ['Harvey', 'Steve', 'Michael', 'Maud', 'Al', 'Kam', 'Hank'],
    'Stephen': ['Lisa','Rosie','Mango','Kate','Nate','Maud','Kelvin','Elvis','Arstad','Jesus','Johan','Jay','Gia','Niki','Harvey','Paul','Mike','Alex','Anna']
}

persons = list(friends.keys())  # Mike, Alex, Stephen
G.add_nodes_from(persons)
combos = list(combinations(persons, 2))  # all 2-combinations of `persons`

for edge in combos:
    node_1, node_2 = edge[0], edge[1]
    common = len(set(friends[node_1]) & set(friends[node_2]))  # number of common friends
    G.add_edge(node_1, node_2, common_friends=common)

node_labels = {person: person + ' (' + str(len(friends[person])) + ' total)' for person in persons}
edge_labels = nx.get_edge_attributes(G, 'common_friends')

pos = nx.circular_layout(G)
nx.draw(G, pos, node_size=2000, with_labels=False)
nx.draw_networkx_labels(G, pos, labels=node_labels)
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
plt.show()

输出:

我更正了代码中的一行,该行现在提供了不同的边缘标签(仅edge_labels的不带键的值).

I corrected a line in my code that now gives different edge labels (only values without keys for edge_labels).

这篇关于使用networkx吸引三个人的共同朋友联系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆