Matplotlib 使用networkx绘制三个人的普通朋友连接
我有三个人(可以选择添加更多的人),我想将每个人的朋友列表显示为一个圆圈。每人一圈。接下来,如果两个人有相同的朋友,我想添加边(连接)Matplotlib 使用networkx绘制三个人的普通朋友连接,matplotlib,python-3.5,networkx,Matplotlib,Python 3.5,Networkx,我有三个人(可以选择添加更多的人),我想将每个人的朋友列表显示为一个圆圈。每人一圈。接下来,如果两个人有相同的朋友,我想添加边(连接) Mike_friends = ['Al', 'Niki', 'Silvia', 'Anna', 'Matt', 'Gia', 'Nick', 'Maud', 'Sarah', 'Lisa', 'Kelvin'] Alex_friends = ['Harvey', 'Steve', 'Michael', 'Maud', 'Al', 'Kam', 'Hank'] S
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个带连接的圆圈没有出现。谢谢你的帮助。删除了“返回G” 这里有一种方法。首先,你会发现迈克、亚历克斯和斯蒂芬是多少普通朋友。我使用
set
;这是迈克和亚历克斯的例子
M_A_common = len(set(Mike_friends) & set(Alex_friends))
我的图表中的节点称为Mike
、Alex
和Stephen
。我在下面设置了edgeMike--Alex
,因此它的值为M_A_common
G.add_edge('Mike', 'Alex', common_friends=M_A_common)
下面是所有朋友的完整示例,我用nx.draw
绘制网络,用nx.draw\u networkx\u edge\u标签绘制边缘标签
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()
你可以不写普通朋友的数量,例如,用边缘厚度显示普通朋友的数量
当然,有了更多的朋友,你会有更多的组合,所以你可能会想自动计算普通朋友
此外,如果您希望每个普通朋友都有多条边,则需要使用MultiGraph
而不是Graph
。要绘制多条边,请查看
编辑:
要为上述代码添加自定义节点标签(例如节点名称+好友总数),您可以使用nx。绘制\u networkx\u标签
,如下所示:
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
的字典中
要获得所有可能的边,我使用
输出:
编辑2:
我更正了代码中的一行,该行现在提供了不同的边缘标签(仅值不带边缘标签的键)。@Bonlenfum您在我之前的networkx问题中提供了帮助,对我如何绘制社交朋友连接有何建议?您需要真正备份并再次访问。代码中的误会太多了。@Joel感谢您的评论。我调用了这个函数。N1、N2、N3中的i代表列表中的每个项目。”现在将在所有迭代之后调用returng。我从add.edge编辑到add.edges\u。同样的问题也存在,只是没有圆的空正方形。还有一个问题是G
发生了什么。它目前是一个全局变量。您的函数也在返回G
,但返回的值不会发送到任何地方。@Joel更好吗?非常感谢@edo有办法显示每个节点的好友总数吗?我可以用同样的方法为10-20个朋友创建这个社交圈,对吗?我有一个无关的问题:有没有一种快速的方法来显示节点Mike和Alex之间的两个普通朋友的名字?你可以设置一个边缘属性,将普通朋友的名字保存在一个字符串中,例如,,'。join(list(set(friends[node_1])和set(friends[node_2]))
,这就画出了这个新的边缘标签。非常感谢,它很好用。最后,如果我使用20、50或100个节点的网络,而不是这里的3个节点,您还会使用这个networkx库吗?或者,对于更多具有高维数据的节点,是否有更好的可视化效果?Networkx适合处理数据,但如果您有很多节点,则值得研究其他图形可视化解决方案。我只使用了networkx,所以我没有任何可供推荐的替代工具。
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()