如何在Holoviews/Bokeh中为NetworkX图设置random_state生成可复现图?
解决Holoviews/Bokeh中固定图布局的报错问题
你遇到的TypeError: 'dict' object is not callable是因为Holoviews的from_networkx方法的第二个参数需要接收一个布局函数,而不是已经计算好的布局字典。NetworkX的spring_layout()返回的是节点到坐标的字典,直接传进去当然会报错啦~
下面给你两种可行的解决方法:
方法一:传递带固定随机状态的布局函数
你可以用lambda或者functools.partial把布局函数和random_state参数绑定在一起,传给from_networkx:
%pylab inline import pandas as pd import networkx as nx import holoviews as hv # 生成图 G = nx.Graph() ndxs = [1, 2, 3, 4] G.add_nodes_from(ndxs) G.add_weighted_edges_from([(1,2,0), (1,3,1), (1,4,-1), (2,4,1), (2,3,-1), (3,4,10)]) # Holoviews/Bokeh绘图 hv.extension('bokeh') %opts Graph [width=400 height=400] # 用lambda封装带random_state的布局函数 layout_func = lambda G: nx.spring_layout(G, random_state=100) hv.Graph.from_networkx(G, layout_func)
或者用functools.partial更清晰一点:
from functools import partial layout_func = partial(nx.spring_layout, random_state=100) hv.Graph.from_networkx(G, layout_func)
方法二:手动设置节点位置属性
如果已经提前计算好了布局字典,可以把坐标作为节点属性添加到图里,然后让Holoviews读取这个属性来固定位置:
# 提前计算布局 fixed_layout = nx.spring_layout(G, random_state=100) # 把坐标添加为节点的'pos'属性 for node, pos in fixed_layout.items(): G.nodes[node]['pos'] = pos # Holoviews使用节点的'pos'属性布局 hv.Graph.from_networkx(G, nx.layout.fruchterman_reingold_layout).opts(node_position='pos')
这里注意,虽然我们传了一个布局函数,但通过node_position='pos'参数,Holoviews会直接使用我们预先设置的节点位置,忽略传入的布局函数计算的结果,这样也能保证布局固定。
这样两种方法都能让你生成可复现的Holoviews图表,和NetworkX里的效果一致~
内容的提问来源于stack exchange,提问作者Soerendip
相关产品推荐
相关产品推荐

