简体   繁体   中英

Position of images as nodes in networkx plot?

After using this answer to generate a plot with images as nodes, I am experiencing some difficulties in making the y-coordinate positions of the nodes line up with the y-coordinate positions of the images: 在此处输入图像描述

The x,y -positions of the nodes is set as:

pos={
0: [0, 0], 
1: [1, 0], 
2: [2, 0], 
3: [3, 0], 
4: [4, 0], 
5: [5, 0], 
6: [6, 0], 
7: [5, 1]
}

and the code to generate the plot is:

pos:Dict={}
    for nodename in G.nodes:
        pos[nodename]=G.nodes[nodename]["pos"]
    print(f'pos={pos}')
    

    fig=plt.figure(figsize=(1,1))
    ax=plt.subplot(111)
    ax.set_aspect('equal')
    nx.draw_networkx_edges(G,pos,ax=ax)
    

    # plt.xlim(-1,10)
    # plt.ylim(-1.5,1.5)

    trans=ax.transData.transform
    trans2=fig.transFigure.inverted().transform

    piesize=0.3 # this is the image size
    p2=piesize/2.0
    for n in G:
        xx,yy=trans(pos[n]) # figure coordinates
        #print(f'xx,yy={xx,yy}')
        xa,ya=trans2((xx,yy)) # axes coordinates
        print(f'xa,ya={xa,ya}')
        a = plt.axes([xa-p2,ya-p2, piesize, piesize])
        a.set_aspect('equal')
        a.imshow(G.nodes[n]['image'])
        a.axis('off')
    ax.axis('off')
    plt.show()

However, the y-coordinates of the edges does not align with the y-coordinates of the images. I expect this is because the coordinate transformation applied for the plt.axes[[xa-p2... line, is not applied to the edge drawings.

Question

How can I ensure the images are placed on their x,y coordinate positions a figure with size [x_min,x_max,y_min,y_max] whilst ensuring the edges of the.networkx Graph also point to the accompaning coordinates?

Try not to set the axes ratio to equal (ie remove this line ax.set_aspect('equal') ).

Though this will hopefully solve the question, there will probably the additional problem, that the arrow heads are hidden behind the images. A solution is to set the node_size parameter when calling nx.draw.networkx_edges() .

When doing so an additional challenge is, that the image size seems to have different length and height values. A workaround is to first draw the vertical edges with a larger node_size . Then add the horizontal edges and set a smaller node_size (the vertical edges will be drawn again, but their arrow heads are hidden behind the image). You will probably have to play around with the values a bit.


pos={
0: [0, 0], 
1: [1, 0], 
2: [2, 0], 
3: [3, 0], 
4: [4, 0], 
5: [5, 0], 
6: [6, 0], 
7: [5, 1]
}

img=mpimg.imread(sample_img_path)
G=nx.DiGraph()
G.add_node(0,image=img)
G.add_node(1,image=img)
G.add_node(2,image=img)
G.add_node(3,image=img)
G.add_node(4,image=img)
G.add_node(5,image=img)
G.add_node(6,image=img)
G.add_node(7,image=img)


fig=plt.figure(figsize=(12,3))
ax=plt.subplot(111)
#ax.set_aspect('equal') # <-- not set the aspect ratio to equal

# draw vertical edges using a larger node size
G.add_edge(4,7)
G.add_edge(5,7)
G.add_edge(6,7)
nx.draw_networkx_edges(G,pos,ax=ax, node_size=8000, arrowsize=30)

# add the horizontal edges with a smaller node size
G.add_edge(0,1)
G.add_edge(1,2)
G.add_edge(2,3)
G.add_edge(3,4)
G.add_edge(4,5)
G.add_edge(6,5)
nx.draw_networkx_edges(G,pos,ax=ax, node_size=3000, arrowsize=30)

trans=ax.transData.transform
trans2=fig.transFigure.inverted().transform

piesize=0.4 # this is the image size
p2=piesize/2.0
for n in G:
    xx,yy=trans(pos[n]) # figure coordinates
    xa,ya=trans2((xx,yy)) # axes coordinates
    a = plt.axes([xa-p2,ya-p2, piesize, piesize])
    a.set_aspect('equal')
    a.imshow(G.nodes[n]['image'])
    a.axis('off')
ax.axis('off')
plt.show()

样本图

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM