如何将节点属性从NetworkX传递到bokeh [英] How to pass node attributes from NetworkX to bokeh

查看:136
本文介绍了如何将节点属性从NetworkX传递到bokeh的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种将在NetworkX节点构造中确定的颜色传递给Bokeh图的方法.

有很多很棒的方法可以在散景图生成后在Bokeh图中实现颜色,例如

  1. 我不太了解如何使用bokeh的from_networkx函数获取这些值.看来这并没有像预期的那样传递属性.实际传递的是什么,我该如何传递颜色?

  2. 是否有更好的方法通过构造的ColumnDataSource分配更多属性?我在想类似于将其传递到数据框,添加颜色列,然后重新生成ColumnDataSource的方法,因此我可以为每个节点值使用'@node_color'检索颜色.

  3. 我有每个数据集的列表,因此可以通过某种方式进行过滤,例如:

     如果list1中的node_id:node_color =红色"node_size = 10如果list2中的node_id:node_color =蓝色"node_size = 20 

我对bokeh还是很陌生,尽管看起来这些应该是简单的任务,但是我完全迷失了文档.仅使用散景来生成网络可能会更好吗?

解决方案

也许这个问题的答案可以帮助您: https://stackoverflow.com/a/54475870/8123623

创建一个dict,其中节点是键,颜色是值.

  colors = [...]颜色= dict(zip(network.nodes,colors))nx.set_node_attributes(network,{k:v for colors中的k,v,colors.items()},'colors')graph.node_renderer.glyph =圆(大小= 5,fill_color ='颜色') 

这是使用from_network()的方式

  graph = from_networkx(G,nx.dot,scale = 1,center =(0,0)) 

I am looking for a way to pass a color, as assinged in NetworkX's node construction, to a Bokeh plot.

There are some great ways to implement color in the Bokeh plot after it is generated, such as this, but this solution requires that I apply the transformation to the entire data set based on an attribute.

I wanted to do something even simpler and assign a color and size based on what I assign those to be in NetworkX. I normally plot node set 1 as red, then node set 2 as blue in NetworkX, then connect them through their mutual edges. While the colors and size of the nodes are not passed to matplotlib, it IS passed to gephi when I save the file as graphml, so these data are somewhere..

import networkx as nx
from bokeh.io import show, output_file
from bokeh.plotting import figure,show
from bokeh.models.graphs import from_networkx #I haven't been able to use this!
from bokeh.io import output_notebook
from bokeh.models import HoverTool, ColumnDataSource
from bokeh.resources import CDN
from bokeh.embed import file_html

Dataset1 = ['A','B','C','D','E','F']
Dataset2 = ['ONE','TWO','THREE','FOUR','FIVE','TWENTY_EIGHT']
Edgelist = [('A','ONE'),('B','ONE'),('E','ONE'),('A','TWO'),('A','THREE'),('A','FOUR'),('C','THREE'),('D','FIVE'),('D',"TWENTY_EIGHT")]
G = nx.Graph()
G.add_nodes_from(Dataset1,color= 'green')  
G.add_nodes_from(Dataset2,color='blue') 
G.add_edges_from(Edgelist,weight=0.8)
layout = nx.draw_spring(G, with_labels=True)
nx.write_graphml(G,"TEST.graphML")
network = nx.read_graphml("TEST.graphML")

#start Bokeh code
layout = nx.spring_layout(network,k=1.1/sqrt(network.number_of_nodes()),iterations=100) #pass the NX file to a spring layout

nodes, nodes_coordinates = zip(*sorted(layout.items()))
nodes_xs, nodes_ys = list(zip(*nodes_coordinates))
nodes_source = ColumnDataSource(dict(x=nodes_xs, y=nodes_ys,name=nodes)) #Can this pass the color? 

hover = HoverTool(tooltips=[('name', '@name')]) #would like to know how to add in more values here manually

plot = figure(plot_width=800, plot_height=400,tools=['tap', hover, 'box_zoom', 'reset'])

r_circles = plot.circle('x', 'y', source=nodes_source, size=10, color='orange', level = 'overlay')#this function sets the color of the nodes, but how to set based on the name of the node? 


def get_edges_specs(_network, _layout): 
    d = dict(xs=[], ys=[], alphas=[])
    weights = [d['weight'] for u, v, d in _network.edges(data=True)]
    max_weight = max(weights)
    calc_alpha = lambda h: 0.1 + 0.6 * (h / max_weight)

    # example: { ..., ('user47', 'da_bjoerni', {'weight': 3}), ... }
    for u, v, data in _network.edges(data=True):
        d['xs'].append([_layout[u][0], _layout[v][0]])
        d['ys'].append([_layout[u][1], _layout[v][1]])
        d['alphas'].append(calc_alpha(data['weight']))
    return d

lines_source = ColumnDataSource(get_edges_specs(network, layout))

r_lines = plot.multi_line('xs', 'ys', line_width=1.5,
                      alpha='alphas', color='navy',
                      source=lines_source)#This function sets the color of the edges

show(plot)

When opened in gephi, color is retained:

  1. I can't quite understand how to fetch these values using bokeh's from_networkx function. It seems that this doesn't pass the attributes over as expected. What is actually being passed and how would I pass color?

  2. Is there a better way to just assign more attributes through the ColumnDataSource that is constructed? I'm thinking something akin to passing it to a dataframe, adding a color column, then re-generating the ColumnDataSource, so I can retrieve the colors with '@node_color' for each node value.

  3. I have lists of each of these datasets, so would it be possible to filter somehow such as:

    if node_id in list1:
        node_color = "red"
        node_size = 10
    if node_id in list2:
        node_color = "blue"
        node_size = 20
    

I'm very new to bokeh, and although it seems like these should be easy tasks, I'm completely lost in the documentation. Is it perhaps better to just generate a network using purely bokeh?

解决方案

Maybe the answers under this question can help you: https://stackoverflow.com/a/54475870/8123623

Create a dict where the nodes are the keys and the colors the values.

colors = [...]
colors = dict(zip(network.nodes, colors))
nx.set_node_attributes(network, {k:v for k,v in colors.items()},'colors' )
graph.node_renderer.glyph = Circle(size=5, fill_color='colors')

This is how you can use from_network()

graph = from_networkx(G, nx.dot, scale=1, center=(0,0))

这篇关于如何将节点属性从NetworkX传递到bokeh的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆