我正在尝试使用networkx和bokeh创建有向图,但是,我还想显示每个边缘的箭头。我发现Holoviews库具有向其图构造函数添加“ directed = true”参数的功能。但是,我也想利用Bokeh的设计功能,例如根据先前设置的节点属性调整节点颜色/大小。仅当我使用Bokeh的from_networkx()获取bokeh.models.renderers.GraphRender对象,然后使用其属性node_renderer和edge_renderer时,后者才有效。
问题是使用Holoviews渲染器将Bokeh指定为后端时,它返回bokeh.plotting.figure.Figure而不是GraphRenderer。最终,我想知道如何能够通过散景可能的某些属性来控制节点的大小/颜色,并同时使用Holoviews在每个边缘上显示箭头。
import networkx as nx
import holoviews as hv
from holoviews import opts
hv.extension('bokeh')
from bokeh.io import show, output_file
# ... some code for I/O ...
G = nx.DiGraph(edgeList) # Directed networkx graph
# Set Node/Edge attributes to display upon hover
numConnections = {k:v for k,v in G.out_degree()}
nx.set_node_attributes(G, numConnections, name='numConnections')
# Returns Holoviews graph
hvGraph = hv.Graph.from_networkx(G, nx.spring_layout).opts(tools=['hover'], directed=True, arrowhead_length=0.01)
# Renders Holoviews graph into bokeh.plotting.figure.Figure
hvRendered = hv.render(hvGraph, 'bokeh')
output_file("out.html")
show(hvRendered)
# # The below code runs as expected using Bokeh only, and not Holoviews
# # to produce the directed graph (without arrowed edges):
# from bokeh.models import Plot, Range1d, MultiLine, Circle
# from bokeh.models import LinearColorMapper, ColorBar, BasicTicker
# import bokeh.models as bm
# from bokeh.models.graphs import from_networkx
# from bokeh.models.graphs import NodesAndLinkedEdges, EdgesAndLinkedNodes
# # Returns GraphRenderer from bokeh.models.renderers.DateRenderer
# graphRenderer = from_networkx(G, nx.spring_layout)
# mapper = LinearColorMapper(palette="Viridis256", low=76, high=0)
# # Node size/color when unselected / selected / hover
# graphRenderer.node_renderer.glyph = Circle(
# size='node_size',
# fill_color= {'field': "numConnections", "transform": mapper},
# fill_alpha=.8
# )
# graphRenderer.node_renderer.selection_glyph = Circle(
# size=25,
# fill_color=Inferno6[4]
# )
# graphRenderer.node_renderer.hover_glyph = Circle(
# size=20,
# fill_color=Inferno6[3]
# )
# # Edge size/color when unselected / selected / hover
# graphRenderer.edge_renderer.glyph = MultiLine(
# line_color="#CCCCCC",
# line_alpha=0.8,
# line_width=3
# )
# graphRenderer.edge_renderer.selection_glyph = MultiLine(
# line_color=Inferno6[4],
# line_width=4
# )
# graphRenderer.edge_renderer.hover_glyph = MultiLine(
# line_color=Inferno6[3],
# line_width=4
# )
# graphRenderer.node_renderer.data_source.data['numConnections'] = [v for k,v in
nx.get_node_attributes(G,'numConnections').items()]
# graphRenderer.selection_policy = NodesAndLinkedEdges()
# graphRenderer.inspection_policy = NodesAndLinkedEdges()
# bar = ColorBar(color_mapper=mapper, location=(0,0), title='#connections')
# # Create Bokeh Plot
# plot = Plot(
# plot_width=20,
# plot_height=20,
# x_range=Range1d(-1.1,1.1),
# y_range=Range1d(-1.1,1.1)
# )
# plot.add_tools(
# bm.HoverTool(tooltips=[("#connections", "@numConnections")]),
# bm.TapTool(),
# bm.BoxSelectTool()
# )
# plot.renderers.append(graphRenderer)
# output_file("bokeh.html")
# show(plot)
在将Holoview图渲染到Bokeh Figure(而不是models.GraphRenderer)之后,如果我尝试使用渲染的Bokeh Figure对象调用属性node_renderer,则显然会引发异常。
回溯(最近一次通话最近):hvRenderedGraph.node_renderer.selection_glyph = Circle()中的文件“ holoview.py”,第106行,AttributeError:“ BokehRenderer”对象没有属性“ node_renderer”
答案 0 :(得分:1)
您可以通过以下代码获取GraphRender对象:
[*]
然后使用from bokeh.models import GraphRenderer
gr = hvRendered.select_one(GraphRenderer)
和gr.node_renderer
调整样式。