使用 nx.degree_histogram 绘制图的度分布
Plotting the degree distribution of a graph using nx.degree_histogram
我尝试使用以下代码绘制 networkx.DiGraph
G
的度数分布:
def plot_degree_In(G):
in_degrees = G.in_degree()
in_degrees=dict(in_degrees)
in_values = sorted(set(in_degrees.values()))
in_hist = [list(in_degrees.values()).count(x) for x in in_values]
plt.figure()
plt.grid(False)
plt.loglog(in_values, in_hist, 'r.')
#plt.loglog(out_values, out_hist, 'b.')
#plt.legend(['In-degree', 'Out-degree'])
plt.xlabel('k')
plt.ylabel('p(k)')
plt.title('Degree Distribution')
plt.xlim([0, 2*100**1])
但后来我意识到这不是正确的方法,所以我将其更改为:
def plot_degree_dist(G):
degree_hist = nx.degree_histogram(G)
degree_hist = np.array(degree_hist, dtype=float)
degree_prob = degree_hist/G.number_of_nodes()
plt.loglog(np.arange(degree_prob.shape[0]),degree_prob,'b.')
plt.xlabel('k')
plt.ylabel('p(k)')
plt.title('Degree Distribution')
plt.show()
但这给了我一个没有数据的空图。
用测试代码打印(in- plus-)degree 直方图的一种方法:
import matplotlib.pyplot as plt
import networkx as nx
def plot_degree_dist(G):
degrees = [G.degree(n) for n in G.nodes()]
plt.hist(degrees)
plt.show()
plot_degree_dist(nx.gnp_random_graph(100, 0.5, directed=True))
可以通过向 plt.hist
添加第二个参数来调整直方图的 bin 数。
今天遇到同样的问题。一些典型的度数分布图 (examples) 不会对度数进行分箱。相反,他们分散对数对数图上每个度数的计数。
这是我想出的。由于在常见的直方图函数中关闭分箱似乎很困难,我决定选择标准 Counter
来完成这项工作。
degrees
预计在节点度数上是可迭代的(由 networkx 返回)。
Counter.items()
给出了对 [(degree, count)] 的列表。将列表解压缩到 x 和 y 后,我们可以准备具有对数刻度的轴,并发布散点图。
from collections import Counter
from operator import itemgetter
import matplotlib.pyplot as plt
# G = some networkx graph
degrees = G.in_degree()
degree_counts = Counter(degrees)
x, y = zip(*degree_counts.items())
plt.figure(1)
# prep axes
plt.xlabel('degree')
plt.xscale('log')
plt.xlim(1, max(x))
plt.ylabel('frequency')
plt.yscale('log')
plt.ylim(1, max(y))
# do plot
plt.scatter(x, y, marker='.')
plt.show()
我手动裁剪了 xlim
和 ylim
,因为自动缩放会使对数缩放中的点有点丢失。小点标记效果最好。
希望对您有所帮助
编辑: 这个 post 的早期版本包括对度数对进行排序,当然,这对于具有明确定义的散点图来说不是必需的x 和 y。查看示例图片:
我们可以使用 nx.degree_histogram
,其中 returns 网络中度数的频率列表,其中度值是列表中的相应索引。但是,此功能仅适用于无向图。我将首先说明如何在无向图的情况下使用它,然后显示一个有向图的示例,我们是否可以看到如何通过稍微调整 nx.degree_histogram
.[=27= 来获得度分布]
- 对于无向图
对于有向图,我们可以使用nx.degree_histogram
。下面是使用随机图生成器 nx.barabasi_albert_graph
.
的示例
通常在绘制度分布时取 x
和 y
轴的对数,这有助于查看 networkx 是否为 scale-free (a network with a degree distribution following a power law), so we can use matplotlib's plt.loglog
:
m=3
G = nx.barabasi_albert_graph(1000, m)
degree_freq = nx.degree_histogram(G)
degrees = range(len(degree_freq))
plt.figure(figsize=(12, 8))
plt.loglog(degrees[m:], degree_freq[m:],'go-')
plt.xlabel('Degree')
plt.ylabel('Frequency')
- 对于有向图
对于有向图,我们可以稍微修改函数 nx.degree_histogram
以考虑入度和出度:
def degree_histogram_directed(G, in_degree=False, out_degree=False):
"""Return a list of the frequency of each degree value.
Parameters
----------
G : Networkx graph
A graph
in_degree : bool
out_degree : bool
Returns
-------
hist : list
A list of frequencies of degrees.
The degree values are the index in the list.
Notes
-----
Note: the bins are width one, hence len(list) can be large
(Order(number_of_edges))
"""
nodes = G.nodes()
if in_degree:
in_degree = dict(G.in_degree())
degseq=[in_degree.get(k,0) for k in nodes]
elif out_degree:
out_degree = dict(G.out_degree())
degseq=[out_degree.get(k,0) for k in nodes]
else:
degseq=[v for k, v in G.degree()]
dmax=max(degseq)+1
freq= [ 0 for d in range(dmax) ]
for d in degseq:
freq[d] += 1
return freq
和上面类似,我们可以为入度 or/and 和出度生成一个图。这是一个带有随机尺度-gree 图的示例:
G = nx.scale_free_graph(5000)
in_degree_freq = degree_histogram_directed(G, in_degree=True)
out_degree_freq = degree_histogram_directed(G, out_degree=True)
degrees = range(len(in_degree_freq))
plt.figure(figsize=(12, 8))
plt.loglog(range(len(in_degree_freq)), in_degree_freq, 'go-', label='in-degree')
plt.loglog(range(len(out_degree_freq)), out_degree_freq, 'bo-', label='out-degree')
plt.xlabel('Degree')
plt.ylabel('Frequency')
我尝试使用以下代码绘制 networkx.DiGraph
G
的度数分布:
def plot_degree_In(G):
in_degrees = G.in_degree()
in_degrees=dict(in_degrees)
in_values = sorted(set(in_degrees.values()))
in_hist = [list(in_degrees.values()).count(x) for x in in_values]
plt.figure()
plt.grid(False)
plt.loglog(in_values, in_hist, 'r.')
#plt.loglog(out_values, out_hist, 'b.')
#plt.legend(['In-degree', 'Out-degree'])
plt.xlabel('k')
plt.ylabel('p(k)')
plt.title('Degree Distribution')
plt.xlim([0, 2*100**1])
但后来我意识到这不是正确的方法,所以我将其更改为:
def plot_degree_dist(G):
degree_hist = nx.degree_histogram(G)
degree_hist = np.array(degree_hist, dtype=float)
degree_prob = degree_hist/G.number_of_nodes()
plt.loglog(np.arange(degree_prob.shape[0]),degree_prob,'b.')
plt.xlabel('k')
plt.ylabel('p(k)')
plt.title('Degree Distribution')
plt.show()
但这给了我一个没有数据的空图。
用测试代码打印(in- plus-)degree 直方图的一种方法:
import matplotlib.pyplot as plt
import networkx as nx
def plot_degree_dist(G):
degrees = [G.degree(n) for n in G.nodes()]
plt.hist(degrees)
plt.show()
plot_degree_dist(nx.gnp_random_graph(100, 0.5, directed=True))
可以通过向 plt.hist
添加第二个参数来调整直方图的 bin 数。
今天遇到同样的问题。一些典型的度数分布图 (examples) 不会对度数进行分箱。相反,他们分散对数对数图上每个度数的计数。
这是我想出的。由于在常见的直方图函数中关闭分箱似乎很困难,我决定选择标准 Counter
来完成这项工作。
degrees
预计在节点度数上是可迭代的(由 networkx 返回)。
Counter.items()
给出了对 [(degree, count)] 的列表。将列表解压缩到 x 和 y 后,我们可以准备具有对数刻度的轴,并发布散点图。
from collections import Counter
from operator import itemgetter
import matplotlib.pyplot as plt
# G = some networkx graph
degrees = G.in_degree()
degree_counts = Counter(degrees)
x, y = zip(*degree_counts.items())
plt.figure(1)
# prep axes
plt.xlabel('degree')
plt.xscale('log')
plt.xlim(1, max(x))
plt.ylabel('frequency')
plt.yscale('log')
plt.ylim(1, max(y))
# do plot
plt.scatter(x, y, marker='.')
plt.show()
我手动裁剪了 xlim
和 ylim
,因为自动缩放会使对数缩放中的点有点丢失。小点标记效果最好。
希望对您有所帮助
编辑: 这个 post 的早期版本包括对度数对进行排序,当然,这对于具有明确定义的散点图来说不是必需的x 和 y。查看示例图片:
我们可以使用 nx.degree_histogram
,其中 returns 网络中度数的频率列表,其中度值是列表中的相应索引。但是,此功能仅适用于无向图。我将首先说明如何在无向图的情况下使用它,然后显示一个有向图的示例,我们是否可以看到如何通过稍微调整 nx.degree_histogram
.[=27= 来获得度分布]
- 对于无向图
对于有向图,我们可以使用nx.degree_histogram
。下面是使用随机图生成器 nx.barabasi_albert_graph
.
通常在绘制度分布时取 x
和 y
轴的对数,这有助于查看 networkx 是否为 scale-free (a network with a degree distribution following a power law), so we can use matplotlib's plt.loglog
:
m=3
G = nx.barabasi_albert_graph(1000, m)
degree_freq = nx.degree_histogram(G)
degrees = range(len(degree_freq))
plt.figure(figsize=(12, 8))
plt.loglog(degrees[m:], degree_freq[m:],'go-')
plt.xlabel('Degree')
plt.ylabel('Frequency')
- 对于有向图
对于有向图,我们可以稍微修改函数 nx.degree_histogram
以考虑入度和出度:
def degree_histogram_directed(G, in_degree=False, out_degree=False):
"""Return a list of the frequency of each degree value.
Parameters
----------
G : Networkx graph
A graph
in_degree : bool
out_degree : bool
Returns
-------
hist : list
A list of frequencies of degrees.
The degree values are the index in the list.
Notes
-----
Note: the bins are width one, hence len(list) can be large
(Order(number_of_edges))
"""
nodes = G.nodes()
if in_degree:
in_degree = dict(G.in_degree())
degseq=[in_degree.get(k,0) for k in nodes]
elif out_degree:
out_degree = dict(G.out_degree())
degseq=[out_degree.get(k,0) for k in nodes]
else:
degseq=[v for k, v in G.degree()]
dmax=max(degseq)+1
freq= [ 0 for d in range(dmax) ]
for d in degseq:
freq[d] += 1
return freq
和上面类似,我们可以为入度 or/and 和出度生成一个图。这是一个带有随机尺度-gree 图的示例:
G = nx.scale_free_graph(5000)
in_degree_freq = degree_histogram_directed(G, in_degree=True)
out_degree_freq = degree_histogram_directed(G, out_degree=True)
degrees = range(len(in_degree_freq))
plt.figure(figsize=(12, 8))
plt.loglog(range(len(in_degree_freq)), in_degree_freq, 'go-', label='in-degree')
plt.loglog(range(len(out_degree_freq)), out_degree_freq, 'bo-', label='out-degree')
plt.xlabel('Degree')
plt.ylabel('Frequency')