Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python How to pass networkx layout arguments through Bokeh's from_networkx

I'm trying to plot a networkx graph with bokeh using bokeh's from_networkx function with the nx.spring_layout argument. I'm trying to define my graph and its attributes in a pandas dataframe as much as possible. I would like to initialize positions of my nodes; how do I pass these positions to the spring_layout? (If it is passed into the nx.spring_layout(...), I'm not getting the format correct.) Any direction would be helpful.

Put another way, for bokeh.from_networkx(G, networkx.spring_layout...), how to I pass arguments to spring_layout as I would when not using bokeh (e.g., networkx.spring_layout(G, dim=2, k=None, pos=None...))

Simple example:

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,-1000,1,1,1,1, -1000, 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 )
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 = 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=5)


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

show(plot)

Ideally, I wouldn't be creating dictionaries for positions (or color or size), but entering them as part of the df passed to the graph, G.

Bokeh 0.12.14, Networkx 2.1, Python 3.6.3

like image 451
Docuemada Avatar asked Jun 18 '26 17:06

Docuemada


1 Answers

EDIT: You can pass on the positional argument in the from_networkx(pos=) function.

I tested your code with networkx 2.2 and python 3.5. It works with minor tweaks.

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,-1000,1,1,1,1, -1000, 1]
df = pd.DataFrame([source,target,weight])
df = df.transpose()
df.columns = ['source','target','weight']
G=nx.from_pandas_edgelist(df) # function signature changes

#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, name='node_color') # function signature changes
nx.set_node_attributes(G,  node_size, name='node_size') # function signature changes
nx.set_node_attributes(G,  node_initial_pos, name='node_initial_pos') # function signature changes

#source with node color, size and initial pos (perhaps )
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), pos=node_initial_pos)

#style
graph_renderer.node_renderer.data_source = 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=5)


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

show(plot)

Output: Without positional argument

enter image description here

Output: With positional argument

enter image description here

like image 164
michaelg Avatar answered Jun 20 '26 07:06

michaelg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!