【问题标题】:NetworkX node labels relative positionNetworkX 节点标签相对位置
【发布时间】:2017-10-09 06:00:42
【问题描述】:

我正在努力解决以下问题。根据之前所做的分类,我想绘制一个包含大约 100 个节点的圆形图,我必须在其中手动定位它们。这些节点有一个描述它们的分配标签,具有不同的文本长度,我想把这个标签放在节点旁边。下图是我想要获得的(我绘制蓝色圆圈只是为了表明标签在外围完全对齐): https://i.stack.imgur.com/Qre0Z.png

目前我只画了这个:https://i.stack.imgur.com/U7bZG.png

这是 MWE:

import numpy as np
import networkx as nx
import matplotlib.pyplot as plt

n = 7
G = nx.complete_graph(n)
node_list = sorted(G.nodes())
angle = []
angle_dict = {}
for i, node in zip(xrange(n),node_list):
    theta = 2.0*np.pi*i/n
    angle.append((np.cos(theta),np.sin(theta)))
    angle_dict[node] = theta
pos = {}
for node_i, node in enumerate(node_list):
    pos[node] = angle[node_i]

labels = {0:'zero',1:'oneone',2:'twotwo',3:'threethreethree',4:'fourfourfourfour',5:'fivefivefivefivefive',6:'sixsixsixsixsixsix'}

# figsize is intentionally set small to condense the graph
f = plt.figure(figsize=(2,2))
r = f.canvas.get_renderer()
plt.axis('equal')
nx.draw(G,pos=pos,with_labels=True)
description = nx.draw_networkx_labels(G,pos,labels=labels)
for node, t in description.items():
    t.set_rotation(angle_dict[node]*360.0/(2.0*np.pi))
plt.show()

我想我必须添加和玩

x, y = t.get_position()
bb = t.get_window_extent(renderer=r)
radius = 1.0+2.0*bb.width/r.width
t.set_position((radius*x,radius*y))

在我设置标签旋转的循环中。但是,我不知道如何正确设置它以及如何避免裁剪画布。

【问题讨论】:

    标签: python matplotlib graph networkx


    【解决方案1】:

    为了在轴外显示标签,您需要使轴与图形相比较小,例如通过在轴周围引入较大的边距。您还需要设置文本的剪辑状态,使其不会被轴截断。

    根据边界框的宽度定位标签需要首先将边界框从显示坐标转换为数据坐标。

    完整的解决方案:

    import numpy as np
    import networkx as nx
    import matplotlib.pyplot as plt
    
    n = 7
    G = nx.complete_graph(n)
    node_list = sorted(G.nodes())
    angle = []
    angle_dict = {}
    for i, node in zip(xrange(n),node_list):
        theta = 2.0*np.pi*i/n
        angle.append((np.cos(theta),np.sin(theta)))
        angle_dict[node] = theta
    pos = {}
    for node_i, node in enumerate(node_list):
        pos[node] = angle[node_i]
    
    labels = {0:'zero',1:'oneone',2:'twotwo',3:'threethreethree',4:'fourfourfourfour',5:'fivefivefivefivefive',6:'sixsixsixsixsixsix'}
    
    # figsize is intentionally set small to condense the graph
    fig, ax = plt.subplots(figsize=(5,5))
    margin=0.33
    fig.subplots_adjust(margin, margin, 1.-margin, 1.-margin)
    ax.axis('equal')
    
    nx.draw(G,pos=pos,with_labels=True, ax=ax)
    description = nx.draw_networkx_labels(G,pos,labels=labels)
    
    r = fig.canvas.get_renderer()
    trans = plt.gca().transData.inverted()
    for node, t in description.items():
        bb = t.get_window_extent(renderer=r)
        bbdata = bb.transformed(trans)
        radius = 1.2+bbdata.width/2.
        position = (radius*np.cos(angle_dict[node]),radius* np.sin(angle_dict[node]))
        t.set_position(position)
        t.set_rotation(angle_dict[node]*360.0/(2.0*np.pi))
        t.set_clip_on(False)
    
    plt.show()
    

    【讨论】:

    • 如果你继续我标记节点的方式,例如 n = 10,那么 (zero, one, twotwo, ... , Nineninenineninenineninenineninenine) 然后使用plt.savefig 保存图形,保存的图形被裁剪。应该在代码中添加什么以避免裁剪?
    • 这是图形大小figsize=(5,5)和你需要调整的边距之间的相互作用。也可以使用 bbox_inches = "tight" 参数为保存的图形自动缩放图形大小。您还可以减小字体大小。这完全取决于您的目标。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-03
    • 1970-01-01
    • 2021-08-17
    相关资源
    最近更新 更多