igraph 用法
详细请参考http://www.cs.rhul.ac.uk/home/tamas/development/igraph/tutorial/tutorial.html
#导入包
import igraph
from igraph import Graph,summary,plot
#查看安装包的版本,Tutorial中版本为0.6的
igraph.version
‘0.7.1’
一、Creating a graph from scratch
g = Graph(1) #生成的graph是只有一个顶点的无向图
g
<igraph.Graph at 0x5c58048>
print g #U:无向的,1:1个顶点,0:0条边
IGRAPH U— 1 0 –
- 添加顶点 add_vertices()
g.add_vertices(2) #添加两个顶点
print g #输出:目前有3个顶点
IGRAPH U— 3 0 – - 添加边 add_edges()
#igraph使用连续性的整数从0开始用于顶点的索引,用索引对来表示边
#如下[(0,1),(1,2)]表示两条边,一个是第一个顶点和第二个顶点之间的边,第二个表示第二个顶点和第三个顶点之间的边
g.add_edges([(0,1),(1,2)]) #添加两条边
print g #输出多了边的数量及具体的边
IGRAPH U— 3 2 –
- edges:
0–1 1–2
type(g.add_edges([(2,0)])) #add_edges方法返回值为NoneType,即不返回igraph对象,与0.6版本的不同,所以不能g.add_edges([2,0]).add_edges([1,2])
NoneType
g.add_vertices(3) #增加3个顶点,此时顶点最大索引是5
g.add_edges([(2,3),(3,4),(4,5),(5,3)]) #增加四条边
print g #输出共有6个顶点,7条边
IGRAPH U— 6 7 – - edges:
0–1 1–2 0–2 2–3 3–4 4–5 3–5
- 删除顶点 delete_vertices() 删除边 delete_edges()
igraph的图和边的ID(索引)都是连续的,和列表索引类似,如果删除其中的边,后面的ID会自动更新,删除顶点亦如此。更甚者,如果删除了边,顶点的ID也会变
print g
IGRAPH U— 6 7 –
- edges:
0–1 1–2 0–2 2–3 3–4 4–5 3–5
g.delete_vertices((2,3))
#删除顶点ID为2和3的,剩余顶点ID为(0,1,4,5),同时会将涉及到的边删去(顶点都没有了,边自然也无用了),剩余边有两条[(0,1),(4,5)]
#而后,后面的顶点ID会自动补齐,即ID变为(0,1,2,3)(4变为2,5变为3),涉及的边也要变更,则边为[(0,1),(2,3)]
print g
IGRAPH U— 4 2 – - edges:
0–1 2–3
g.add_vertices(2)
g.add_edges([(1,5),(3,5)])
print g
IGRAPH U— 6 4 – - edges:
0–1 2–3 1–5 3–5
g.get_eid(1,5),g.get_eid(3,5)
(2, 3)
g.delete_edges(2)
print g
IGRAPH U— 6 3 – - edges:
0–1 2–3 3–5
g.get_eid(3,5)
2
- summary
summary输出结果和str或者print出的结果类似,只是更加灵活些
有如下参数,具体可看官方文档 graph, verbosity=0, width=78, edge_list_format=’auto’,max_rows=99999, print_graph_attributes=False,print_vertex_attributes=False, print_edge_attributes=False, full=False
summary(g) #默认情况下verbosity=1:只输出head line,即只显示一些汇总信息之类的
IGRAPH U— 6 3 –
summary(g,verbosity=1)
IGRAPH U— 6 3 –
- edges:
0–1 2–3 3–5
summary(g, verbosity=1, print_graph_attributes=True, print_vertex_attributes=True, print_edge_attributes=True, full=True)
IGRAPH U— 6 3 – - edges:
0–1 2–3 3–5
g.str()
‘IGRAPH U— 6 3 --\n+ edges:\n0–1 2–3 3–5’
二、Generating graphs
igraph有很多生成器,主要分为两大类:确定性的(deterministic)和随机性的(stochastic)。前者如果每次同一个方法且参数值相同,则生成的图相同,而后者则每次生成的图是不同的。
#Tree:确定性的图生成器
g_1 = Graph.Tree(127,2) #Tree :每个顶点有两个孩子节点和一个父节点
g_2 = Graph.Tree(127,2)
print g_1
IGRAPH U— 127 126 – - edges:
0–1 0–2 1–3 1–4 2–5 2–6 3–7 3–8 4–9 4–10 5–11 5–12 6–13 6–14
7–15 7–16 8–17 8–18 9–19 9–20 10–21 10–22 11–23 11–24 12–25 12–26
13–27 13–28 14–29 14–30 15–31 15–32 16–33 16–34 17–35 17–36 18–37
18–38 19–39 19–40 20–41 20–42 21–43 21–44 22–45 22–46 23–47 23–48
24–49 24–50 25–51 25–52 26–53 26–54 27–55 27–56 28–57 28–58 29–59
29–60 30–61 30–62 31–63 31–64 32–65 32–66 33–67 33–68 34–69 34–70
35–71 35–72 36–73 36–74 37–75 37–76 38–77 38–78 39–79 39–80 40–81
40–82 41–83 41–84 42–85 42–86 43–87 43–88 44–89 44–90 45–91 45–92
46–93 46–94 47–95 47–96 48–97 48–98 49–99 49–100 50–101 50–102
51–103 51–104 52–105 52–106 53–107 53–108 54–109 54–110 55–111
55–112 56–113 56–114 57–115 57–116 58–117 58–118 59–119 59–120
60–121 60–122 61–123 61–124 62–125 62–126
#GRG:随机性的图
g_3 = Graph.GRG(100,0.2) #GRG:geometric random graph
g_4 = Graph.GRG(100,0.2)
get_edgelist()
#获取有顶点ID对组成的列表,即图的边的信息
#g_1.get_edgelist()
g_1.get_edgelist()[0:5]
[(0, 1), (0, 2), (1, 3), (1, 4), (2, 5)]
g_1.get_edgelist() == g_2.get_edgelist() #确定性的图,每次生成的是一样的
True
g_3.get_edgelist() == g_4.get_edgelist() #随机性的图,每次生成的不一样
False
g_3 == g_4,g_1 == g_2
(False, False)
isomorphic() 检验两个Graph对象是否是同构的
g_1.isomorphic(g_2)
True
g_3.isomorphic(g_4)
False
三、Setting and retrieving attributes
#g_5是一个简易的社交网络图,顶点代表人,边代表关系
g_5 = Graph([(0,1),(0,2),(2,3),(3,4),(4,2),(2,5),(5,0),(6,3),(5,6)])
print g_5
IGRAPH U— 7 9 – - edges:
0 – 1 2 5 2 – 0 3 4 5 4 – 2 3 6 – 3 5
1 – 0 3 – 2 4 6 5 – 0 2 6
vs & es:Graph对象包含两个比较特殊的成员vs,es,分别代表Graph对象的顶点序列和边序列VertexSeq,EdgeSeq
g_5.vs,g_5.es
(<igraph.VertexSeq at 0x5cad688>, <igraph.EdgeSeq at 0x5c5ceb8>)
可以将vs,es看作是个字典对象,进行属性设置
g_5.vs[‘name’]=[‘Alice’,‘Bob’,‘Claire’,‘Dennis’,‘Esther’,‘Frank’,‘Geprge’]
g_5.vs[‘age’]=[25,31,18,47,22,23,50]
g_5.vs[‘gender’]=[‘f’,‘m’,‘f’,‘m’,‘f’,‘m’,‘m’]
g_5.es[‘is_formal’]=[False,False,True,True,True,False,True,False,False]
g_5.vs.attributes() #attributes()查看有哪些属性
[‘gender’, ‘age’, ‘name’]
g_5.vs.get_attribute_values(‘age’) #get_attribute_values(key)查看属性有哪些值
[25, 31, 18, 47, 22, 23, 50]
print g_5
IGRAPH UN-- 7 9 – - attr: age (v), gender (v), name (v), is_formal (e)
- edges (vertex names):
Alice – Bob, Claire, Frank
Bob – Alice
Claire – Alice, Dennis, Esther, Frank
Dennis – Claire, Esther, Geprge
Esther – Claire, Dennis
Frank – Alice, Claire, Geprge
Geprge – Dennis, Frank
也可以将vs,es看作是列表对象,通过索引查看单个边或顶点对象
g_5.vs[0]
igraph.Vertex(<igraph.Graph object at 0x0000000005C58138>,0,{‘gender’: ‘f’, ‘age’: 25, ‘name’: ‘Alice’})
g_5.vs[0].attributes()
{‘age’: 25, ‘gender’: ‘f’, ‘name’: ‘Alice’}
g_5.es[2]
igraph.Edge(<igraph.Graph object at 0x0000000005C58138>, 2, {‘is_formal’: True})
g_5.es[2].attributes()
{‘is_formal’: True}
g_5.es[2][‘is_formal’]=False #对单个边或顶点对象可通过字典形式修改属性值
g_5.es[2].attributes()
{‘is_formal’: False}
Vertex,Edge对象一些常见的属性
#Edge
g_5.es[2]
igraph.Edge(<igraph.Graph object at 0x0000000005C58138>, 2, {‘is_formal’: False})
g_5.es[2].source #边的源顶点
2
g_5.es[2].target #边的目标顶点
3
g_5.es[2].tuple #返回边的源和目标顶点,以元组形式呈现
(2, 3)
g_5.es[2].attributes() #以字典形式返回该Vertex对象的属性
{‘is_formal’: False}
g_5.es[2].index #返回边的ID
2
#Vertex 没有tuple,source,target属性
g_5.vs[1]
igraph.Vertex(<igraph.Graph object at 0x0000000005C58138>,1,{‘gender’: ‘m’, ‘age’: 31, ‘name’: ‘Bob’})
g_5.vs[1].attributes()
{‘age’: 31, ‘gender’: ‘m’, ‘name’: ‘Bob’}
g_5.vs[1].index #返回顶点对象的ID
1
#修改属性
g_5.vs[3][‘foo’] = ‘bar’
g_5.vs[‘foo’]
[None, None, None, ‘bar’, None, None, None]
del g_5.vs[‘foo’] #可以使用del对属性进行删除
g_5.vs[‘foo’]
KeyError Traceback (most recent call last)
in ()
----> 1g_5.vs[‘foo’]
KeyError: ‘Attribute does not exist’
四、Structural properties of graphs
如下表格总结参考 http://blog.youkuaiyun.com/u010289316/article/details/51645064
指标名称 概念 比较 实际应用 对应iGraph中的方法
点度中心度 在某个点上,有多少条线 强调某点单独的价值 ★作为基本点的描述 Graph.degree()
接近中心度 该点与网络中其他点距离之和的倒数,越大说明越在中心,越能够很快到达其他点 强调点在网络的价值,越大,越在中心 ★★基本描述,用户价值 Graph.closeness()
中间中心度 代表最短距离是否都经过该点,如果都经过说明这个点很重要,其中包括线的中心度 强调点在其他点之间调节能力,控制能力指数,中介调节效应 ★★推荐算法,用户的控制力 Graph.betweenness()
特征向量中心度 根据相邻点的重要性来衡量该点的价值。首先计算邻接矩阵,然后计算邻接矩阵的特征向量。 强调点在网络的价值,并且比接近中心度厉害的是,点价值是根据近邻点来决定的 ★★★推荐算法,用户潜在价值 Graph.evcent()
- Graph.degree() 返回图的度(点度中心度)
g_5.vs.str()
‘<igraph.VertexSeq object at 0x0000000005CC0F48>’
g_5.get_edgelist()
[(0, 1), (0, 2), (2, 3), (3, 4), (2, 4), (2, 5), (0, 5), (3, 6), (5, 6)]
#degree:求顶点的度,即有多少个边包含该顶点,参数中传入一个列表,可以返回指定顶点的度
g_5.degree(), g_5.degree([0,2,4])
([3, 1, 4, 3, 2, 3, 2], [3, 4, 2])
#入度和出度
g_5.degree(mode=‘in’), g_5.degree(mode=‘out’)
([3, 1, 4, 3, 2, 3, 2], [3, 1, 4, 3, 2, 3, 2])
g_5.indegree(),g_5.outdegree()
([3, 1, 4, 3, 2, 3, 2], [3, 1, 4, 3, 2, 3, 2]) - Graph.closeness() 返回图对象的接近中心度
g_5.closeness()
[0.6666666666666666,
0.42857142857142855,
0.75,
0.6,
0.5454545454545454,
0.6666666666666666,
0.5454545454545454] - Graph.edge_betweenness() 返回边的中间中心度、Graph.betweenness() 返回顶点的中间中心度
g_5.edge_betweenness()
[6.0, 6.0, 4.0, 2.0, 4.0, 3.0, 4.0, 3.0, 4.0]
g_5.get_edgelist()
[(0, 1), (0, 2), (2, 3), (3, 4), (2, 4), (2, 5), (0, 5), (3, 6), (5, 6)]
ebs = g_5.edge_betweenness()
max_eb = max(ebs)
max_eb
6.0
返回中心度最大的边
[g.es[idx].tuple for idx,eb in enumerate(ebs) if eb==max_eb]
[(0, 1), (2, 3)]
g_5.betweenness()
[5.0, 0.0, 5.5, 1.5, 0.0, 2.5, 0.5]
4) Graph.evcent():点的特征向量中心度
g_5.evcent()
[0.7111995450108003,
0.24860112203602627,
1.0,
0.7513988779639744,
0.6122047310756776,
0.7860026990612522,
0.5374015770252261]
plot(g_5)
五、Querying vertices and edges based on attributes
g_5.degree(), g_5.maxdegree()
([3, 1, 4, 3, 2, 3, 2], 4)
g_5.vs.select(_degree = g_5.maxdegree())[‘name’]
[‘Claire’]
g_5.vs.select(_degree = g_5.maxdegree())
<igraph.VertexSeq at 0x5cabef8>
select(self, *args, **kwds) 可以传位置参数和关键字参数
1)参数为位置参数
#若第一个位置参数为None,返回一个空的序列
seq = g.vs.select(None)
len(seq)
0
#若第一个位置参数为可调用对象(函数,方法,或者类似函数可调用的对象),若返回结果为True,则包含在返回序列中
graph = Graph.Full(10)
print graph
IGRAPH U— 10 45 –
- edges:
0 – 1 2 3 4 5 6 7 8 9 5 – 0 1 2 3 4 6 7 8 9
1 – 0 2 3 4 5 6 7 8 9 6 – 0 1 2 3 4 5 7 8 9
2 – 0 1 3 4 5 6 7 8 9 7 – 0 1 2 3 4 5 6 8 9
3 – 0 1 2 4 5 6 7 8 9 8 – 0 1 2 3 4 5 6 7 9
4 – 0 1 2 3 5 6 7 8 9 9 – 0 1 2 3 4 5 6 7 8
only_odd_vertices = graph.vs.select(lambda vertex: vertex.index % 2 ==1)
len(only_odd_vertices)
5
#若参数是可迭代的对象(列表,生成器,其他可迭代对象等),该对象必须返回整数序列,vertex的ID与返回的整数序列如有匹配上的,则包含在返回的序列中
seq = graph.vs.select([2,3,7])
len(seq)
3
[v.index for v in seq]
[2, 3, 7]
seq = seq.select([0,2]) #调用select的对象可以不必是Graph对象的完整的VexSeq
[v.index for v in seq]
[2, 7]
seq = graph.vs.select([2,3,7,‘foo’,4.5]) #只能是范围内的整数,字符串,浮点数会跳过,超过范围的整数,则报错
len(seq)
3
#若第一个位置参数为整数,则后面的参数也必须为整数,相当于传了一个整数类型的list
seq = graph.vs.select(2,3,7)
len(seq)
3
- 关键字参数
用来过滤属性或者图的结构性质,关键字包含两部分,一部分是属性或者结构性质的名字,另一部分过滤的操作符,后者可省略,此时默认为等于。因Python语法限制,参数中出现的操作符只能有=,不能出现>,<,in等。如下是可能的关键字:
Keyword argument Meaning
name_eq 属性/性质的值必须 等于 关键字参数的值
name_ne …不等于…
name_lt …小于…
name_le …小于等于…
name_gt …大于…
name_ge …大于等于…
name_in …包含…,此时参数必须是一个序列
name_notin …不包含…,此时参数必须是一个序列
print g_5
IGRAPH UN-- 7 9 –
- attr: age (v), gender (v), name (v), is_formal (e)
- edges (vertex names):
Alice – Bob, Claire, Frank
Bob – Alice
Claire – Alice, Dennis, Esther, Frank
Dennis – Claire, Esther, Geprge
Esther – Claire, Dennis
Frank – Alice, Claire, Geprge
Geprge – Dennis, Frank
g_5.vs[‘age’]
[25, 31, 18, 47, 22, 23, 50]
seq_lt = g_5.vs.select(age_lt=29) # 过滤属性age的值小于29的
#seq_lt = g_5.vs(age_lt=29) # 也可把select省去
[v.index for v in seq_lt]
[0, 2, 4, 5]
若属性和结构性质的重名了,会出现歧义,此时如果关键字指的是结构性质需要在前面加_,即_name。否则会认为是属性名字
g_5.get_edgelist()
[(0, 1), (0, 2), (2, 3), (3, 4), (2, 4), (2, 5), (0, 5), (3, 6), (5, 6)]
g_5.degree()
[3, 1, 4, 3, 2, 3, 2]
seq_stru = g_5.vs(_degree_gt=2)
[v.index for v in seq_stru]
[0, 2, 3, 5]
seq_stru = g_5.vs(degree_gt=2) #没有degree属性,报错
[v.index for v in seq_stru]
KeyError Traceback (most recent call last)
in ()
----> 1seq_stru = g_5.vs(degree_gt=2) #没有degree属性,报错
2 [v.index for v in seq_stru]
C:\Anaconda2\lib\site-packages\igraph_init_.pyc in call(self, *args, **kwds)
3511 This method simply passes all its arguments to L{VertexSeq.select()}.
3512 “”"
-> 3513return self.select(*args, **kwds)
3514
3515 ##############################################################
C:\Anaconda2\lib\site-packages\igraph_init_.pyc in select(self, *args, **kwds)
3500 values = getattr(vs.graph, attr[1:])(vs)
3501 else:
-> 3502values = vs[attr]
3503 filtered_idxs=[i for i, v in enumerate(values) if func(v, value)]
3504 vs = vs.select(filtered_idxs)
KeyError: ‘Attribute does not exist’
[vs.degree() for vs in g_5.vs]
[3, 1, 4, 3, 2, 3, 2]
六、Layouts and plotting
-
有很多种类的布局,如下为部分:
方法名 缩略名 算法描述
layout_circle circular 确定性布局,将顶点放在圆上
layout_drl drl 采用Distributed Recursive Layout算法,适用于比较大的图
layout_fruchterman_reingold fr 采用力引导布局的FR(Fruchterman-Reingold)算法
layout_kamada_kawai kk 采用力导向布局的KK(Kamada-Kawai)算法
layout_random random 图的顶点随机放置
layout_reingold_tilford rt,tree 大型树拓扑结构,紧凑分层的展示数据结构
可通过两种方式使用:1 将缩略名作为参数传入layout()方法中,2 直接调用方法名
layout = g_5.layout(‘circular’)
#layout = g_5.layout_circle()
plot(g_5,layout=layout) -
Drawing a Graph
layout = g_5.layout(‘kk’)
plot(g_5,layout = layout)
#为顶点加标签,用颜色区别gender属性,顶点标签默认使用顶点的label属性,顶点颜色默认使用color属性
g_5.vs[‘label’] = g_5.vs[‘name’]
color_dict = {‘m’:‘blue’,‘f’:‘pink’}
g_5.vs[‘color’] = [color_dict[gender] for gender in g_5.vs[‘gender’]]
plot(g_5,layout=layout,bbox=(300,300),margin=20)
除了利用label,color属性来画图外,还可以在plot传入关键字键值对来进行设定
color_dict = {‘m’:‘black’,‘f’:‘white’}
plot(g_5,layout=layout,vertex_color=[color_dict[gender] for gender in g_5.vs[‘gender’]],bbox=(300,300))
#可以将图的样式属性放在字典中,并通过**dict_style形式传入plot即可
visual_style = {}
visual_style[‘vertex_size’] = 20
visual_style[‘vertex_color’] = [color_dict[gender] for gender in g_5.vs[‘gender’]]
visual_style[‘vertex_label’] = g_5.vs[‘name’]
visual_style[‘edge_width’] = [1 + 2 * int(is_formal) for is_formal in g_5.es[‘is_formal’]]
visual_style[‘layout’] = layout
visual_style[‘bbox’] = (300,300)
visual_style[‘margin’] = 20
plot(g_5,**visual_style)
3)保存Graph
可以保存为文件PDF,PNG等格式
plot(g_5,‘social_network.pdf’,**visual_style)
List item