首页 > 解决方案 > 图形工具中具有边缘捆绑和标签的圆形布局

问题描述

我对图形可视化和图形工具(gt)等软件非常陌生。我的主要领域是数学,但我对 Python 和一般编程有点熟悉。但是,我不是程序员,所以我的代码可能不够优雅;任何改进建议将不胜感激。

描述:

我非常喜欢用于可视化非常大的图形的带有边缘捆绑的圆形布局。例如,我正在尝试使用Tiago Peixoto的精彩 Python 模块图形工具绘制 C.Elegans 连接组。为此,我使用以下内容:

import graph_tool.all as gt
g_celegans = gt.load_graph("c.elegans_neural.male_1.graphml")
v_prop = g_celegans.vertex_properties
celegans_state = gt.minimize_nested_blockmodel_dl(g_celegans)
celegans_state.draw(vertex_text = v_prop['name'], bg_color = 'w')

产生:

C.elegans连接组

问题:

  1. 我如何(在 gt 中)将顶点标签放在从中心绘制的线上?像这样
  2. 我可以绘制一个类似的布局,即圆形和边缘捆绑​​,但使用我自己的聚类(顶点的分区),而不是随机块模型?从某种意义上说,我想我只是希望能够自己使用圆形+边缘捆绑功能。还是我有点遗漏了重点?
  3. (有人会推荐一个很好的关于图形可视化的介绍性处理,包括这种类型(连接图)吗?)

尝试问题 1: 所以,我至少设法做到了这一点:

def getAngle(vec):
    norm_vec = vec / np.linalg.norm(vec)
    one_vec = np.array([1,0])
    dot_product = np.dot(norm_vec, one_vec)
    return np.arccos(dot_product)
    
text_rot = [0]*len(list(text_pos))
for i, p in enumerate(text_pos):
    if p[0]>=0 and p[1]>=0:
        text_rot[i] = getAngle(p)
    elif p[0]>=0 and p[1]<0:
        text_rot[i] = -getAngle(p)
    elif p[0]<0 and p[1]>=0:
        text_rot[i] = getAngle(p)-np.pi
    elif p[0]<0 and p[1]<0:
        text_rot[i] = -getAngle(p)+np.pi

text_rot = np.asarray(text_rot)
t_rot = g_celegans.new_property('v','float', vals = text_rot)

options = {'pos': pos,
           'vertex_text': v_prop['name'],
           'vertex_text_rotation':t_rot,
           'bg_color': 'w',
           'vertex_shape': 'none',
           'vertex_font_size': 5,
           'edge_end_marker': 'none'
          }

celegans_state.draw(**options)

产生: 在此处输入图像描述

所以,旋转很好,但我想将标签偏移得更远一些。现在它们位于一个不可见顶点的中心。有两个顶点属性称为“text_position”和“text_offset”,您可以在此处阅读。

现在,'vertex_text_position' 的任何值,例如 -1 或 'centered',或者如果我传递一个 VertexPropertyMap 对象,如上面的 'vertex_text_rotation',都会生成一个 IndexError:

    ---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-197-d529fcf5647e> in <module>
      9           }
     10 
---> 11 celegans_state.draw(**options)

~/anaconda3/envs/gt/lib/python3.9/site-packages/graph_tool/inference/nested_blockmodel.py in draw(self, **kwargs)
    986         draws the hierarchical state."""
    987         import graph_tool.draw
--> 988         return graph_tool.draw.draw_hierarchy(self, **kwargs)
    989 
    990 

~/anaconda3/envs/gt/lib/python3.9/site-packages/graph_tool/draw/cairo_draw.py in draw_hierarchy(state, pos, layout, beta, node_weight, vprops, eprops, hvprops, heprops, subsample_edges, rel_order, deg_size, vsize_scale, hsize_scale, hshortcuts, hide, bip_aspect, empty_branches, **kwargs)
   2121             kwargs[k] = u.own_property(v.copy())
   2122 
-> 2123     pos = graph_draw(u, pos, vprops=t_vprops, eprops=t_eprops, vorder=tvorder,
   2124                      **kwargs)
   2125 

~/anaconda3/envs/gt/lib/python3.9/site-packages/graph_tool/draw/cairo_draw.py in graph_draw(g, pos, vprops, eprops, vorder, eorder, nodesfirst, output_size, fit_view, fit_view_ink, adjust_aspect, ink_scale, inline, inline_scale, mplfig, output, fmt, bg_color, **kwargs)
   1074                       vprops.get("fill_color", _vdefaults["fill_color"]),
   1075                       vcmap)
-> 1076         vprops["text_color"] = auto_colors(g, bg,
   1077                                            vprops.get("text_position",
   1078                                                       _vdefaults["text_position"]),

~/anaconda3/envs/gt/lib/python3.9/site-packages/graph_tool/draw/cairo_draw.py in auto_colors(g, bg, pos, back)
    724             return color_contrast(back)
    725     c = g.new_vertex_property("vector<double>")
--> 726     map_property_values(bgc_pos, c, conv)
    727     return c
    728 

~/anaconda3/envs/gt/lib/python3.9/site-packages/graph_tool/__init__.py in map_property_values(src_prop, tgt_prop, map_func)
   1189     u = GraphView(g, directed=True, reversed=g.is_reversed(),
   1190                   skip_properties=True)
-> 1191     libcore.property_map_values(u._Graph__graph,
   1192                                 _prop(k, g, src_prop),
   1193                                 _prop(k, g, tgt_prop),

~/anaconda3/envs/gt/lib/python3.9/site-packages/graph_tool/draw/cairo_draw.py in conv(x)
    722             return color_contrast(bgc)
    723         else:
--> 724             return color_contrast(back)
    725     c = g.new_vertex_property("vector<double>")
    726     map_property_values(bgc_pos, c, conv)

~/anaconda3/envs/gt/lib/python3.9/site-packages/graph_tool/draw/cairo_draw.py in color_contrast(color)
    694 def color_contrast(color):
    695     c = np.asarray(color)
--> 696     y = c[0] * .299 + c[1] * .587 + c[2] * .114
    697     if y < .5:
    698         c[:3] = 1

IndexError: too many indices for array: array is 0-dimensional, but 1 were indexed

问题似乎是旋转的中心是顶点的中心,如果将文本从顶点移出,这并不理想。所以,即使上面的 'vertex_text_position' 会起作用,我猜旋转也会把它搞砸。

我最终做的是使用顶点属性'text_out_color'和'text_out_width',宽度为0.003。这为文本提供了一种很好的粗体样式,使其在彩色背景下更具可读性。

但是,现在我几乎没有想法。

有人知道我的问题的解决方案吗?即像我有它们一样放置标签,但将它们移到更远(从中心向外的方向)或将它们框成白色,以便它们更具可读性,但这样情节仍然看起来不错;以及上面的问题2。

标签: visualizationgraph-tool

解决方案


这已经晚了几个月,所以希望你能弄清楚,但我会把它留在这里以供将来参考:

在这种情况下,要让这些标签看起来像您想要的那样,当您调用绘图函数时,您需要指定顶点文本的位置,如下所示:

celegans_state.draw(vertex_text = v_prop['name'], bg_color = 'w', vertex_text_position='centered')

(从文档中的属性列表中可以看出,“居中”给出了这种确切的效果:https ://graph-tool.skewed.de/static/doc/draw.html#graph_tool.draw.graph_draw )

要获得圆形图,我认为您想使用径向树布局(https://graph-tool.skewed.de/static/doc/draw.html?highlight=radial_tree_layout#graph_tool.draw.radial_tree_layout

希望这会有所帮助!


推荐阅读