如何在bokeh中的networkx图的节点上添加永久名称标签(非交互式标签)? [英] How to add permanent name labels (not interactive ones) on nodes for a networkx graph in bokeh?

查看:401
本文介绍了如何在bokeh中的networkx图的节点上添加永久名称标签(非交互式标签)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用spring_layout和bokeh库在networkx图的节点上添加永久标签.我希望此标签可以按图比例缩放或刷新,就像字符串布局一样,可以根据图比例缩放或刷新来重新定位节点.

I am trying to add a permanent label on nodes for a networkx graph using spring_layout and bokeh library. I would like for this labels to be re-positioned as the graph scales or refreshed like what string layout does, re-positioning the nodes as the graph scales or refreshed.

我试图创建图形和布局,然后从string_layout获得pos.但是,当我调用pos=nx.spring_layout(G)时,它将为图G中的节点生成一组位置,我可以获取这些位置的坐标放入LabelSet中.但是,我必须调用graph = from_networkx(G, spring_layout, scale=2, center=(0,0))来绘制网络图.这将为节点创建一组新的位置.因此,节点和标签的位置将不同.

I tried to create the graph, and layout, then got pos from the string_layout. However, as I call pos=nx.spring_layout(G), it will generated a set of positions for the nodes in graph G, which I can get coordinates of to put into the LabelSet. However, I have to call graph = from_networkx(G, spring_layout, scale=2, center=(0,0)) to draw the network graph. This will create a new set of position for the node. Therefore, the positions of the nodes and the labels will not be the same.

如何解决此问题?

推荐答案

感谢您提出这个问题.通过它的工作,我已经意识到它目前的工作量超出了应有的程度.我强烈建议您打开 GitHub问题,以便我们讨论可以进行哪些改进最好使用户更轻松地进行此类操作.

Thanks for asking this question. Working through it, I've realized that it is currently more work than it should be. I'd very strongly encourage you to open a GitHub issue so that we can discuss what improvements can best make this kind of thing easier for users.

这是一个完整的示例:

import networkx as nx

from bokeh.io import output_file, show
from bokeh.models import CustomJSTransform, LabelSet
from bokeh.models.graphs import from_networkx

from bokeh.plotting import figure

G=nx.karate_club_graph()

p = figure(x_range=(-3,3), y_range=(-3,3))
p.grid.grid_line_color = None

r = from_networkx(G, nx.spring_layout, scale=3, center=(0,0))
r.node_renderer.glyph.size=15
r.edge_renderer.glyph.line_alpha=0.2

p.renderers.append(r)

到目前为止,这都是相当正常的散景图布局代码.这是您需要为每个节点添加永久标签的附加部分:

So far this is all fairly normal Bokeh graph layout code. Here is the additional part you need to add permanent labels for each node:

from bokeh.transform import transform    

# add the labels to the node renderer data source
source = r.node_renderer.data_source
source.data['names'] = [str(x*10) for x in source.data['index']]

# create a transform that can extract the actual x,y positions
code = """
    var result = new Float64Array(xs.length)
    for (var i = 0; i < xs.length; i++) {
        result[i] = provider.graph_layout[xs[i]][%s]
    }
    return result
"""
xcoord = CustomJSTransform(v_func=code % "0", args=dict(provider=r.layout_provider))
ycoord = CustomJSTransform(v_func=code % "1", args=dict(provider=r.layout_provider))

# Use the transforms to supply coords to a LabelSet 
labels = LabelSet(x=transform('index', xcoord),
                  y=transform('index', ycoord),
                  text='names', text_font_size="12px",
                  x_offset=5, y_offset=5,
                  source=source, render_mode='canvas')

p.add_layout(labels)

show(p)

基本上,由于Bokeh(潜在地)在浏览器中计算布局,因此实际的节点位置仅可通过布局提供程序"获得,当前访问起来有点繁琐.就像我说的,请打开GitHub问题,建议为用户提供更好的解决方案.我们可能需要做一些非常简单快捷的操作,以使用户更轻松地进行操作.

Basically, since Bokeh (potentially) computes layouts in the browser, the actual node locations are only available via the "layout provider" which is currently a bit tedious to access. As I said, please open a GitHub issue to suggest making this better for users. There are probably some very quick and easy things we can do to make this much simpler for users.

上面的代码导致:

这篇关于如何在bokeh中的networkx图的节点上添加永久名称标签(非交互式标签)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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