节点大小取决于 NetworkX 上的节点度数。

33

我将我的Facebook数据以.json文件的形式导入到了电脑上。这些数据的格式如下:

{
  "nodes": [
    {"name": "Alan"},
    {"name": "Bob"}
  ],
  "links": [
    {"source": 0, "target: 1"}
  ]
}

然后,我使用这个函数:

def parse_graph(filename):
    """
    Returns networkx graph object of facebook
    social network in json format
    """
    G = nx.Graph()
    json_data = open(filename)
    data = json.load(json_data)
    # The nodes represent the names of the respective people
    # See networkx documentation for information on add_* functions
    nodes = data["nodes"]
    G.add_nodes_from([n["name"] for n in nodes])
    G.add_edges_from(
        [
            nodes[e["source"]]["name"],
            nodes[e["target"]]["name"]) for e in data["links"]
        ]
    )
    json_data.close()
    return G

为了使这个 .json 文件能够在 NetworkX 上用作图形,如果我要查找节点的度数,我唯一知道如何使用的方法是:
degree = nx.degree(p)

这里的p是我所有朋友的图形。现在,我想绘制这个图形,使得节点的大小与该节点的度数相同。我该怎么做?

使用:

nx.draw(G, node_size=degree)

这个方法不起作用,我想不到其他的方法了。

3个回答

54

对于使用networkx 2.x的人的更新

API已经从v1.x更改为v2.x。networkx.degree不再返回一个dict,而是按照文档返回一个DegreeView对象。

有一个从1.x迁移到2.x的指南 在这里

在这种情况下,基本上可以使用dict(g.degree)代替d = nx.degree(g)

更新后的代码如下:

import networkx as nx
import matplotlib.pyplot as plt

g = nx.Graph()
g.add_edges_from([(1,2), (2,3), (2,4), (3,4)])

d = dict(g.degree)

nx.draw(g, nodelist=d.keys(), node_size=[v * 100 for v in d.values()])
plt.show()

nx.degree(p) 返回一个字典,而node_size关键字参数需要一个标量或一组大小数组。您可以像这样使用nx.degree返回的字典:

import networkx as nx
import matplotlib.pyplot as plt

g = nx.Graph()
g.add_edges_from([(1,2), (2,3), (2,4), (3,4)])

d = nx.degree(g)

nx.draw(g, nodelist=d.keys(), node_size=[v * 100 for v in d.values()])
plt.show()

在此输入图片描述


很棒的答案!正如我在下面提到的,如果数据中有零度节点需要显示给用户,那么节点大小应该加上一些值,例如:[(v+1) * 100 for v in d.values()],这样零度节点就会出现。 - Tchotchke
第一段代码在节点@miles82中不带任何字符串打印。 - alper

4

@miles82提供了一个很好的答案。但是,如果您已经使用类似于G.add_nodes_from(nodes)的方法将节点添加到图形中,则我发现d = nx.degree(G)可能不会按照节点相同的顺序返回度数。

在之前的答案基础上,您可以稍微修改解决方案以确保度数以正确的顺序排列:

d = nx.degree(G)
d = [(d[node]+1) * 20 for node in G.nodes()]

请注意 d[node]+1 ,这将确保度为零的节点被添加到图表中。

你有没有检查过 G.nodes() 是否总是以一定的顺序返回节点?在这种情况下,最终的代码将是degrees = nx.degree(G) nx.draw(g, nodelist=G.nodes(), node_size=[(degrees[v] + 1) * 100 for v in G.nodes()]) - A.Ametov
这很棒,应该被接受的答案! - Rea Haas
这个答案对我有用。@miles82的答案给了我“'dict_keys' object has no attribute 'index'”错误。使用d = [(d[node]+1) * 100 for node in G.nodes()]生成了与@miles82答案相同的图表。 - curtisp

4

如果您仍然遇到“DiDegreeView”对象没有属性“keys”的问题,以下是其他方法:

1)您可以首先将每个节点的度数作为元组列表获取

2)从元组的第一个值构建节点列表,并从元组的第二个值构建度数列表。

3)最后,使用您创建的节点列表和度数列表绘制网络。

以下是代码:

    list_degree=list(G.degree()) #this will return a list of tuples each tuple is(node,deg)
    nodes , degree = map(list, zip(*list_degree)) #build a node list and corresponding degree list
    plt.figure(figsize=(20,10))
    nx.draw(G, nodelist=nodes, node_size=[(v * 5)+1 for v in degree])
    plt.show() #ploting the graph 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接