力导布局图是一种用来展示节点以及节点之间网络关系数据的图表,其布局算法模型建立在粒子物理理论的基础上,将节点模拟成为原子,通过原子间的引力和斥力得到节点的速度与加速度,计算其移动方位与距离,达到一个稳定平衡的状态,从而完成布局,便于描述节点间关系。 在专利分析中,力导布局图可以用来描述专利技术合作关系,帮助挖掘研发团队,进行技术聚类分析等。(相关链接:图表介绍 | 力导布局图)。 今天的教程教大家使用pyecharts来绘制自动聚类的动态力导布局图(如上图)。 准备数据: 绘图所用的excel数据表格如下: (链接:https://pan.baidu.com/s/1AuxyEiKjnk_Od7Hse0q-yw 密码:fz7p) 数据横行表示数据源节点,即发射数据的节点,纵行表示数据目标节点,即接收数据的节点。横行和竖行的内容实际上是完全一样的发明人名称。表格中的数据表示两两发明人之间的合作申请量。 绘图思路: 导入绘图所需的两个扩展包python-igraph和pyecharts; python-igraph和pyecharts其实都是用于绘制力导布局图的,但是为什么需要两个扩展包呢? 因为pyecharts的力导布局图的算法没有办法实现计算机自动根据远近关系对节点(即发明人)进行聚类,而python-igraph可以实现自动聚类。但是python-igraph的图表没有pyecharts那么美。 所以结合两者优点,需要导入两个扩展包。首先采用python-igraph对从excel中读取的数据进行计算分类,对分类后的数据标记分类信息,继而调用pyecharts绘图。 具体步骤如下: STEP 1 导入绘图所需要的扩展包 作图需安装如下两个额外扩展包:
STEP 2 利用python-igraph实现自动聚类 导入绘图所需包: frompyechartsimport Graph#导入echarts库中的力导布局图 import pandas aspd#导入pandas,用于操作excel文件 importnumpyasnp#导入numpy库,用于数值计算 importigraph#导入python-igraph库,用于对数据聚类 使用pandas读入excel数据: df=pd.read_excel('力导布局图.xlsx')#打开excel文件 将数据处理为规定格式及采用igraph扩展包分类: g=igraph.Graph(1)#实例化一个igraph对象 g.add_vertices(df.index)#添加igraph顶点(就是力导布局图中的节点),数据来自excel文件的行索引 weights=[]#备用空列表,用于存储igraph聚类所需要的权重信息 my_links=[] #备用空列表,用于存储pyecharts的链接信息 foriindf.index:#外层循环,轮询excel每个列 for j indf.columns:#内层循环,轮询excel每一行 ifdf[j][i] >0:#大于0的值有效 my_links.append({'source':i,'target':(j),'value':df[j][i]})#从excel中读取数据,填入上面的备用列表中 g.add_edge(i,j)#添加边信息到igraph中,igraph的边对应pyecharts的links weights.append(df[j][i])#添加权重信息到igraph的备用列表中 else: pass#小于等于0的数不操作 ifnotg.vs[0]['name']:#判断igraph是否自动生成了‘None’顶点 g.delete_vertices(0)#删除None顶点 result=g.community_multilevel(weights,True)#运行聚类算法,结果存放在result变量里,包含两种聚类结果 igraph.plot(result[1],mark_groups = True, margin = 20, vertex_label=[str(i) foriin range(len(df.index))])#根据聚类结果,使用igraph的绘图函数绘图,显示聚类结果 colors_list=['yellowgreen', 'gold', 'lightskyblue', 'lightcoral', 'darkslateblue','#ADD8E6','#DDA0DD', '#FAA460','#F0E68C','#8c564b','#e377c2', '#7f7f7f','#bcbd22','#17becf']#备用颜色列表 category_dic={}#备用空字典,存放每个顶点(节点)对应的分类 forlist_datain result[1]:#取第一种聚类结果,循环访问聚类结果中的每一个“小团伙” for data inlist_data:#循环访问每一个“小团伙”中的顶点,以便标记团伙内的顶点的分类 category_dic[df.index[data]]=df.index[list_data[0]]#把“小团伙”内每个顶点标记为同一个分类,分类名称以团伙第一个认的名字命名,记录到备用字典中 sym_x=[]#备用空列表,用于存放excel中每一行的数据和,即该顶点向其他顶点发射的数据总和 sym_y=[]#备用空列表,用于存放excel中每一列的数据和,即该顶点接收其他顶点发射的数据总和 sym=[]#备用空列表,用于存放excel中每一个顶点所在的行列的数据值的和,即一个顶点发射和接收的数据总和 foriindf.index:#对每个顶点循环 sym_x.append(sum(df.loc[i]))#计算每个顶点的发射数据总和,填入备用列表 foriindf.columns:#对每个顶点循环 sym_y.append(sum(df[i]))#计算顶点的接收数据总和,填入备用列表 fora,bin zip(sym_x,sym_y):#对每个顶点的发射和接收数据同时进行循环 sym.append(a b)#计算总和,填入备用列表 my_nodes=[{'name':i,'symbolSize':int(np.sqrt(j)*np.sqrt(max(sym))/max(sym)*25), 'category':category_dic[i],'value':j,'draggable':1} fori,jinzip(df.index,sym)]#生成节点数据,填入每个节点的名字,图标大小,分类,数据总数。 category=[{'name':df.index[i[0]]} foriin result[1]]#pyecharts需要知道一共有多少种分类,固定格式 在这一过程中,会弹出python-igraph计算后分类生成的图片,如下: 上图中每个不同颜色的分组为计算机自动聚类的结果。这张图的每个小圆圈表示一个节点,节点内的数字代表这个节点点在excel行或者列中的顺序(其实就是代表一个发明人),当然也可以直接用文字代替数字显示,但是会很杂乱。 STEP 3 利用pyecharts利用分类后的数据绘图: graph = Graph('合作关系图',width=1000, height=900)#实例化pyecharts里的力导布局图 graph.add('', my_nodes, my_links, category,graph_gravity=1.0, is_legend_show=True,label_color=colors_list, is_label_show=True,label_pos='right',line_curve=0)#绘制力导布局图,节点间距离通过graph_gravity参数调节。 graph.render('graph.html')#保存图表,在当前目录下生成‘graph.html’文件,需要手动用浏览器打开 STEP 4 生成HTML格式的动态图表 Pyecharts生成的所有图表均为html网页格式,手动用双击文件就可以通过浏览器打开。 在浏览器中,我们可以进行整体拖拽,放大操作: 也可以关闭某些节点的显示: 将鼠标放在我们感兴趣的节点上,使其高亮: 拖拽节点,观察与之有关系的其他节点: 本篇教程完整代码如下: frompyechartsimport Graph#导入echarts库中的力导布局图 import pandas aspd#导入pandas,用于操作excel文件 importnumpyasnp#导入numpy库,用于数值计算 importigraph#导入python-igraph库,用于对数据聚类 df=pd.read_excel('力导布局图.xlsx')#打开excel文件 g=igraph.Graph(1)#实例化一个igraph对象 g.add_vertices(df.index)#添加igraph顶点(就是力导布局图中的节点),数据来自excel文件的行索引 weights=[]#备用空列表,用于存储igraph聚类所需要的权重信息 my_links=[] #备用空列表,用于存储pyecharts的链接信息 foriindf.index:#外层循环,轮询excel每个列 for j indf.columns:#内层循环,轮询excel每一行 ifdf[j][i] >0:#大于0的值有效 my_links.append({'source':i,'target':(j),'value':df[j][i]})#从excel中读取数据,填入上面的备用列表中 g.add_edge(i,j)#添加边信息到igraph中,igraph的边对应pyecharts的links weights.append(df[j][i])#添加权重信息到igraph的备用列表中 else: pass#小于等于0的数不操作 ifnotg.vs[0]['name']:#判断igraph是否自动生成了‘None’顶点 g.delete_vertices(0)#删除None顶点 result=g.community_multilevel(weights,True)#运行聚类算法,结果存放在result变量里,包含两种聚类结果 igraph.plot(result[1],mark_groups = True, margin = 20, vertex_label=[str(i) foriin range(len(df.index))])#根据聚类结果,使用igraph的绘图函数绘图,显示聚类结果 colors_list=['yellowgreen', 'gold', 'lightskyblue', 'lightcoral', 'darkslateblue','#ADD8E6','#DDA0DD', '#FAA460','#F0E68C','#8c564b','#e377c2', '#7f7f7f','#bcbd22','#17becf']#备用颜色列表 category_dic={}#备用空字典,存放每个顶点(节点)对应的分类 forlist_datain result[1]:#取第一种聚类结果,循环访问聚类结果中的每一个“小团伙” for data inlist_data:#循环访问每一个“小团伙”中的顶点,以便标记团伙内的顶点的分类 category_dic[df.index[data]]=df.index[list_data[0]]#把“小团伙”内每个顶点标记为同一个分类,分类名称以团伙第一个认的名字命名,记录到备用字典中 sym_x=[]#备用空列表,用于存放excel中每一行的数据和,即该顶点向其他顶点发射的数据总和 sym_y=[]#备用空列表,用于存放excel中每一列的数据和,即该顶点接收其他顶点发射的数据总和 sym=[]#备用空列表,用于存放excel中每一个顶点所在的行列的数据值的和,即一个顶点发射和接收的数据总和 foriindf.index:#对每个顶点循环 sym_x.append(sum(df.loc[i]))#计算每个顶点的发射数据总和,填入备用列表 foriindf.columns:#对每个顶点循环 sym_y.append(sum(df[i]))#计算顶点的接收数据总和,填入备用列表 fora,bin zip(sym_x,sym_y):#对每个顶点的发射和接收数据同时进行循环 sym.append(a b)#计算总和,填入备用列表 my_nodes=[{'name':i,'symbolSize':int(np.sqrt(j)*np.sqrt(max(sym))/max(sym)*25), 'category':category_dic[i],'value':j,'draggable':1} fori,jinzip(df.index,sym)]#生成节点数据,填入每个节点的名字,图标大小,分类,数据总数。 category=[{'name':df.index[i[0]]} foriin result[1]]#pyecharts需要知道一共有多少种分类,固定格式 graph = Graph('合作关系图',width=1000, height=900)#实例化pyecharts里的力导布局图 graph.add('', my_nodes, my_links, category,graph_gravity=1.0, is_legend_show=True,label_color=colors_list, is_label_show=True,label_pos='right',line_curve=0)#绘制力导布局图,节点间距离通过graph_gravity参数调节。 graph.render('graph.html')#保存图表,在当前目录下生成‘graph.html’文件,需要手动用浏览器打开 |
|