例如,我们有如下 igraph 对象
查看对象
在第一行中, 16 进制数后面的字符分别代表:
还有两个字符
后面的两个数值 (10 9) 表示节点和边的数量
第二行为节点和边的属性,其中括号中的字符分别表示:
例子中的 name 为节点的字符型属性
获取图的大小
以传递节点 ID 的方式,获取指定节点及这些节点之间的边,构建子图
以指定边 ID 的方式,获取包含指定边及边所涉及到的节点,构建子图
最直接的表示图的方法是邻接矩阵,行列与节点对应,如果两个节点之间存在连接,则矩阵中对应位置的值为 1 ,否则为 0 。对于加权图来说,值代表的是边的权重。
对于无向图来说,邻接矩阵总是对称的,而对于有向图来说并不一定是对称的。
使用 [] 可以返回对象的邻接矩阵,也可以使用 get.adjacency(g) 来获取
返回的是一个稀疏矩阵
获取对应的边
0 表示不存在 A 到 F 的边,我们可以将其设置为 1 ,意味着会添加这条边
如果要删除一条边,可以将邻接矩阵对应位置的值设置为 0 ,例如
查询多条边会返回一个矩阵
获取一个节点与其他所有节点之间的连接
以数字索引的方式
条件查询
配对节点
将会查询的边为 A-C 、 B-D 、 C-E ,需要保证 from 和 to 的长度一致
获取邻接节点
邻接表是以表的形式来表示图的,只存储每个节点中与其相连的节点
获取节点的邻接节点
不同方向的邻接节点
显示边
获取两个节点集合之间的边
使用 E() 和 V() 函数,可以获取 igraph 对象的边和节点。例如
V() 的返回值是根据结点的 ID 进行了排序。由于我们的节点是字符型的,会根据节点添加的顺序自动为节点设置 ID ,第一个节点的 ID 为 1
可以使用两个节点名称之间添加一个竖线组成的字符串来引用连接两个节点的边,如果是无向图,则两个节点的顺序不影响边的引用
使用 ends() 可以获取边的矩阵表示
对于有向图, head_of 和 tail_of 可以获取边的头尾两个端点,有箭头的一端为头
使用 neighbors 来获取节点的邻接节点
对于无向图,两种模式的邻接节点是一样的
计算边和节点的数量
节点序列 *** 作
根据邻接节点索引
查询条件
反转、去重和集合 *** 作
获取边涉及的结点
边序列 *** 作与节点类似
获取涉及到节点的边
条件索引
获取两个节点集合之间存在的边
集合 *** 作、去重和反转和节点 *** 作一样
注意 :我们在中括号中使用的简写函数只能在对应条件下使用,无法单独使用
我们可以将节点和边的元数据(附加信息)作为属性值的方式添加到节点和边的属性中
使用 $ 可以获取和设置属性,例如,获取节点的 name 属性
为节点新建一个名为 class 的属性
为边设置属性值
也可以使用 set_edge_attr 和 set_vertex_attr 函数来设置,效果是一样的
获取所有节点和边的属性
可以使用 delete_edge_attr 和 delete_vertex_attr 删除属性
获取图属性
设置图的属性
删除图属性
上面的属性设置都是在已经构建完图之后,我们也可以在构建图的时候添加属性。例如
在这里,我们使用 add_edges 和 add_vertices 函数来添加边和节点,对应的,可以使用 delete_edges 和 delete_vertices 来删除边和节点
有几个特殊的属性:
输入矩阵是连接权重时,如何利用R中的igraph包生成图
————————————————————————————————————————————
library(igraph)#加载包
mygraph=read.csv("d:/desktop/n.csv", header=TRUE,sep = ",",row.names=1)#读取数据
我的数据长这样
m<- as.matrix(mygraph)#输入数据转换为matrix
g <- graph.adjacency(adjmatrix=m, mode="directed", weighted=TRUE, diag=FALSE)#生成有向图,权重设置TRUE
plot(g, edge.label=round(E(g)$weight, 3))#$带权重标注的网络图,可以通过——?igraph.plotting 查看igraph绘图相关参数
输出的图如下:
E(g)$weight#查看连边权重
结果如下:
[1] 0.83 0.76 0.78 0.40 0.67 0.73 0.79 0.71 0.75 0.65 0.69 0.48 0.72 0.82 0.88 0.58 0.70
[18] 0.73 0.60 0.54 0.65 0.56 0.68 0.54 0.61 0.59 0.47 0.67 0.64 0.64 0.47 0.51 0.60 0.50
[35] 0.47 0.61 0.44 0.56 0.66 0.72 0.71 0.72 0.65 0.63 0.51 0.69 0.66 0.59 0.68 0.73 0.62
[52] 0.71 0.51 0.76 0.77 0.51 0.88 0.92 0.70 0.77 0.44 0.80 0.87 0.77 0.66 0.51 0.52 0.77
[69] 0.64 0.68 0.47 0.52
——————————————————————————————
最近需要绘制一些网络演示图,没找到合适的绘图工具,找了半天感觉学习成本都挺高的,感觉还是用Python搞效率高一些。之前用igraph的时候凑巧看过networkx,觉得和igraph-python相比,这个库至少是给人类用的,而且这个包好像是内置Graphviz的,不如我也用这个加matplotlib去绘图试试。今天试着画一个二分网络无向图,并且用圈圈表现出其社团关系,颜色表示节点种类。
1. 创建网络
G = nx.Graph()
G.add_node('1')
G.add_nodes_from(['2', '3'])
#注意如果加进去临边有未出现的节点,会自动创建节点
G.add_edge(1, 2)
G.add_edge('1', '2')
#实际上edges是个hash的key,还可以对应一个value
G.add_edge(n1, n2, object=x)
G.add_edges_from([('1', '2'), ('1', '3')])
list(G.adj['1'])
G.degree['1']
G.remove_node('2')
G.remove_edge('1', '3')
2. 为节点添加属性
G[1][3]['color'] = "blue"
G.edges[1, 2]['color'] = "red"
3. 快速遍历所有临边
FG = nx.Graph()
FG.add_weighted_edges_from([(1, 2, 0.125), (1, 3, 0.75), (2, 4, 1.2), (3, 4, 0.375)])
for n, nbrs in FG.adj.items():
for nbr, eattr in nbrs.items():
wt = eattr['weight']
if wt <0.5: print('(%d, %d, %.3f)' % (n, nbr, wt))
4. 为图,节点,边添加属性
G = nx.Graph(day="Friday")
G.graph
5. 为节点添加属性
G.add_node(1, time='5pm')
G.add_nodes_from([3], time='2pm')
G.nodes[1]
G.nodes[1]['room'] = 714
G.nodes.data()
6. 为临边添加属性
G.add_edge(1, 2, weight=4.7 )
G.add_edges_from([(3, 4), (4, 5)], color='red')
G.add_edges_from([(1, 2, {'color': 'blue'}), (2, 3, {'weight': 8})])
G[1][2]['weight'] = 4.7
G.edges[3, 4]['weight'] = 4.2
#注意的是weight这个属性不能胡乱用,这个是算法库里面处理时看做临边权重的属性,必须是数值型的。
7. 创建有向图
DG = nx.DiGraph()
DG.add_weighted_edges_from([(1, 2, 0.5), (3, 1, 0.75)])
#这个方向是按照第一个元素->第二个元素的
DG.out_degree(1, weight='weight') #0.5
DG.degree(1, weight='weight') #1.25
H = nx.Graph(DG)#有向图转为无向图
8. 创建multigraph
>>>MG = nx.MultiGraph()
>>>MG.add_weighted_edges_from([(1, 2, 0.5), (1, 2, 0.75), (2, 3, 0.5)])
>>>dict(MG.degree(weight='weight'))
{1: 1.25, 2: 1.75, 3: 0.5}
>>>GG = nx.Graph()
>>>for n, nbrs in MG.adjacency():
... for nbr, edict in nbrs.items():
... minvalue = min([d['weight'] for d in edict.values()])
... GG.add_edge(n, nbr, weight = minvalue)
...
>>>nx.shortest_path(GG, 1, 3)
[1, 2, 3]
9. 基础做图
G = nx.petersen_graph()
plt.subplot(121)
nx.draw(G, with_labels=True, font_weight='bold')
plt.subplot(122)
#这个draw_shell好像是按照某种叫shell的布局绘制
nx.draw_shell(G, nlist=[range(5, 10), range(5)], with_labels=True, font_weight='bold')
#传入选项
options = {undefined
'node_color': 'black',
'node_size': 100,
'width': 3,
}
# 四种布局
plt.subplot(221)
nx.draw_random(G, **options)
plt.subplot(222)
nx.draw_circular(G, **options)
plt.subplot(223)
nx.draw_spectral(G, **options)
plt.subplot(224)
nx.draw_shell(G, nlist=[range(5,10), range(5)], **options)
1. 实战
1.1 画一个二分网络图,两类节点不同颜色,每个节点上有id,临边的颜色代表值,然后画两个区域。
B = nx.Graph()
B.add_nodes_from(['u1','u2','u3','u4'], bipartite='user')
B.add_nodes_from(['i1','i2','i3'], bipartite='item')
B.add_edge('u1','i1',weight=3)
B.add_edge('u1','i2',weight=4)
B.add_edge('u2','i1',weight=5)
B.add_edge('u2','i3',weight=1)
B.add_edge('u3','i3',weight=3)
B.add_edge('u4','i3',weight=4)
from networkx.algorithms import bipartite
import matplotlib as mpl
#区域就算了 搞了一下午还是没捣鼓出来怎么画
X = ['u1','u2','u3','u4']
Y = ['i1','i2','i3']
Edges = []
pos = dict()
pos.update( (n, (1, i)) for i, n in enumerate(X) )
pos.update( (n, (2, i+0.5)) for i, n in enumerate(Y) )
nx.draw_networkx_nodes(B, pos, nodelist=X, node_color='slategray',alpha=0.95, node_size = 350, with_labels=False)
nx.draw_networkx_nodes(B, pos, nodelist=Y, node_color='steelblue',alpha=0.95, node_size = 350, with_labels=False)
nx.draw_networkx_labels(B,pos)
colors = [ B.edges[u,i]['weight'] for u,i in B.edges]
edges = nx.draw_networkx_edges(B, pos = pos, edge_color = colors,
width=3, edge_cmap=plt.cm.Blues, with_labels=False, edge_vmin = 0, alpha=0.9)
pc = mpl.collections.PatchCollection(Edges, cmap=plt.cm.Blues)
pc.set_array(colors)
plt.colorbar(pc)
ax = plt.gca()
ax.set_axis_off()
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)