在散景中使用Networkx绘图:如何根据图形边缘权重设置边缘宽度

时间:2018-03-06 17:38:01

标签: python networkx bokeh

对于给定的networkx图G,我想将边线line_width调整为Bokeh中图形权重的函数。简化示例:

import networkx as nx
import pandas as pd
from bokeh.models import Plot, ColumnDataSource, Range1d, from_networkx, Circle,MultiLine
from bokeh.io import show, output_file
from bokeh.palettes import Viridis

#define graph
source = ['A', 'A', 'A','a','B','B','B','b']
target = ['a', 'B','b','b','a','b','A','a']
weight = [.1,.2,.3,.4,.4,.3, .2, .1]
df = pd.DataFrame([source,target,weight])
df = df.transpose()
df.columns = ['source','target','weight']
G=nx.from_pandas_dataframe(df, 'source', 'target', ['weight'])

#set node attributes
node_color = {'A':Viridis[10][0], 'B':Viridis[10][9],'a':Viridis[10][4],'b':Viridis[10][4]}
node_size = {'A':50, 'B':40,'a':10,'b':10}
node_initial_pos = {'A':(-0.5,0), 'B':(0.5,0),'a':(0,0.25),'b':(0,-0.25)}
nx.set_node_attributes(G, 'node_color', node_color)
nx.set_node_attributes(G, 'node_size', node_size)
nx.set_node_attributes(G, 'node_initial_pos', node_initial_pos)

#source with node color, size and initial pos (perhaps )
node_source = ColumnDataSource(pd.DataFrame.from_dict({k:v for k,v in G.nodes(data=True)}, orient='index'))

plot = Plot(plot_width=400, plot_height=400,
            x_range=Range1d(-1.1,1.1), y_range=Range1d(-1.1,1.1))

graph_renderer = from_networkx(G, nx.spring_layout, scale=0.5, center=(0,0))

#style
graph_renderer.node_renderer.data_source = node_source
graph_renderer.node_renderer.glyph = Circle(fill_color = 'node_color',size = 'node_size', line_color = None)

graph_renderer.edge_renderer.glyph = MultiLine(line_color="#CCCCCC", line_alpha=0.8, line_width=2)


plot.renderers.append(graph_renderer)
output_file('test.html')

show(plot)

这提供了一个图,但是我无法将G的权重链接到edge_renderer的line_width属性。而不是line_width = 2,我希望line_width是图权重。我尝试根据传递给G的df创建一个新的ColumnDataSource,但没有运气。例如,下面给出了“未定义的Bokeh错误无法读取属性'长度”:

nodal_relation_df['weight'] = nodal_relation_df['weight'].apply(float)
graph_source = ColumnDataSource(nodal_relation_df)
graph_renderer.edge_renderer.data_source = graph_source

将graph_renderer.edge_renderer.glyph的line_width与图表权重配对的其他方法是什么?

Bokeh 0.12.14,Networkx 2.1,Python 3.5.4,Jupyter 5.0.0

2 个答案:

答案 0 :(得分:1)

在输出之前添加以下行:

Iterable<String>

答案 1 :(得分:1)

给定一个名为 G 的加权边的networkX图和一个名为 plot 的散景图对象,我提出了一个更紧凑的形式:

graph_renderer.edge_renderer.data_source.data["line_width"] = [G.get_edge_data(a,b)['weight'] for a, b in G.edges()]
graph_renderer.edge_renderer.glyph.line_width = {'field': 'line_width'}
plot.renderers.append(graph_renderer)