前言
在gradio框架下对蛋白质-蛋白质相互作用网络(PPI网络)进行可视化,并将其在网页前端进行展示。
方法
其实很简单
可以直接使用networkx画图后保存图片,然后使用Gradio框架的image组件进行展示即可。
但实际上gradio还配置了Plot组件,可以用于将matplotlib的figure进行展示
又由于networkx绘图本身又基于matplotlib,所以也可以完成展示。
接下来主要麻烦的地方就是networkx绘图的使用
networkx的设计模式是分离的,图结构的存储和绘制是分开的两个步骤
绘制的时候,需要传入点的坐标,这些坐标有一套成体系的算法,也就是layout算法。
首先绘制点,传入图G,传入layout算法的输出结果pos,然后可以自己设定节点颜色
边也是同理,由于边也是基于点计算的,所以传入点的pos和图的结构G就可以得知边应该怎么绘制,同样线条粗细、样式、颜色、alpha通道也都是可以调整的。
最后是标注label和图例legend绘制,字体、大小也都是可以调整的。
代码:
import random
import networkx as nx
from matplotlib import pyplot as plt
import gradio as grdef get_ppi_figure(xxx):# 假设这是查询PPI网络后的结果图GG = nx.Graph()G.add_edge('1','2',is_infer=True,weight=0.1)G.add_edge('2','1',is_infer=True,weight=0.3)G.add_edge('2','1',is_infer=True,weight=0.3)G.add_edge('2','1',is_infer=True,weight=0.3)G.add_edge('3','4',is_infer=True,weight=0.5)G.add_edge('4','5',is_infer=True,weight=0.7)G.add_edge('a','b',is_infer=False,weight=1.0)#设置查询中心点的颜色nodes = []node_color = []for u in G.nodes():nodes.append(u)if u == 'a':node_color.append("#FFFF00")else:node_color.append('r')#读取边的推理权重edge_is=[]infer_weight=[]edge_not=[]for u,v,d in G.edges(data=True):if d['is_infer']:edge_is.append((u,v))infer_weight.append(d['weight'])else:edge_not.append((u,v))fig =plt.figure()fig.add_subplot()pos = nx.spring_layout(G)# 在node_color传入颜色的list,即可实现每个点有不同的颜色nx.draw_networkx_nodes(G, pos, nodelist=nodes, node_color=node_color)nx.draw_networkx_edges(G, pos, edgelist=edge_not, edge_color='g', label="From Experiment")# 这里使用透明度alpha来表示推理的置信度nx.draw_networkx_edges(G, pos, edgelist=edge_is, edge_color='r', alpha=infer_weight, style="dashed", label="From Prediction")nx.draw_networkx_labels(G, pos)plt.legend(loc="upper right")plt.axis('off')return figdemo = gr.Interface(get_ppi_figure,gr.Textbox(label='Protein ID'),gr.Plot(label='PPI Graph'))
demo.launch(server_port=7000,share=False,debug=True,show_error=True)
采用circular layout
但实践下来,还是感觉不够美观,使用Plot组件始终只是绘制了图片而已,并没有可以交互的图功能(比如拖拽节点,节点缓慢漂浮运动,双击节点整理layout,三维查看图结构等很帅的可视化)
后来搜索了一下cytoscape的可视化js插件,但是由于自己并不是开发前端的专业人员,没能看懂如何把cytoscape.js嵌入进gradio网页端,最后就不了了之了。
所以占坑待填吧,如果有大佬能在评论区给一点建议JS嵌入gradio的建议,感激不尽。