matplotlib 如何更好地可视化Networkx自循环图?

mbskvtky  于 2022-11-15  发布在  其他
关注(0)|答案(1)|浏览(173)

我怎样才能把自循环画得更大,它太小了,看起来不太好。

G = nx.DiGraph()
G.add_nodes_from(my_graph.vertex_list)
G.add_weighted_edges_from(my_graph.edges_list)
weight = nx.get_edge_attributes(G, 'weight')
nx.draw_networkx(G, with_labels=True, pos=my_graph.position, node_size= 200, node_color='r',
                 edge_color='g',
                 arrowsize=23, font_size=16)
nx.draw_networkx_edge_labels(G, my_graph.position, edge_labels=weight, font_size=16)
nx.to_pandas_edgelist(G)
nx.to_pandas_adjacency(G)
plt.show()
xuo3flqw

xuo3flqw1#

这是一个有趣的问题。简单(但不可靠)的修复imo是改变图形大小:

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

G = nx.DiGraph()

G.add_edge('A','A')
G.add_edge('A','B')
G.add_edge('C','B')
G.add_edge('D','B')

pos = {'A':(0,1),'B':(1,1),'C':(0,0),'D':(1,0)}

G['A']['B']['weight'] = 1
G['C']['B']['weight'] = 1
G['D']['B']['weight'] = 1

weight = nx.get_edge_attributes(G, 'weight')

fig, ax = plt.subplots(figsize=(20,20))

nx.draw_networkx_nodes(G, pos = pos, node_size= 800, node_color='r')
nx.draw_networkx_labels(G, pos = pos, font_size = 23)
nx.draw_networkx_edge_labels(G, pos = pos, edge_labels=weight, font_size=23)
nx.draw_networkx_edges(G, pos = pos, edge_color='g', arrowsize=50, node_size = 800)

plt.show()

结果:x1c 0d1x
我会如何做,以获得更多的控制权:查看路径是如何生成的,并在networkx包(networkx_draw_edges的源代码)中模拟路径的生成:

class SelfLoop():
    def __init__(self, v_scale=0.25, h_scale=0.25, nodesize=100):
        self.v_scale = v_scale
        self.h_scale = h_scale
        self.nodesize = nodesize

    def selfloopstyle(self, posA, posB, *args, **kwargs):
        from matplotlib.path import Path

        selfloop_ht = 0.005 * self.nodesize

        data_loc = ax.transData.inverted().transform(posA)
        v_shift = self.v_scale * selfloop_ht
        h_shift = v_shift * self.h_scale

        path = [
            data_loc + np.asarray([0, v_shift]),
            data_loc + np.asarray([h_shift, v_shift]),
            data_loc + np.asarray([h_shift, 0]),
            data_loc,
            data_loc + np.asarray([-h_shift, 0]),
            data_loc + np.asarray([-h_shift, v_shift]),
            data_loc + np.asarray([0, v_shift]),
        ]

        ret = Path(ax.transData.transform(path), [1, 4, 4, 4, 4, 4, 4])

        return ret
    
    def style(self):
        return self.selfloopstyle

现在你必须操作networkx创建的self循环。改变边的_connector属性并将其重新应用到axes-object。

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

G = nx.DiGraph()

G.add_edge('A','A')
G.add_edge('A','B')
G.add_edge('C','B')
G.add_edge('D','B')
G.add_edge('D','D')

pos = {'A':(0,1),'B':(1,1),'C':(0,0),'D':(1,0)}

G['A']['A']['weight'] = 1
G['A']['B']['weight'] = 1
G['C']['B']['weight'] = 1
G['D']['B']['weight'] = 1
G['D']['D']['weight'] = 1

weight = nx.get_edge_attributes(G, 'weight')


fig, ax = plt.subplots(figsize=(10,10))

nx.draw_networkx_nodes(G, pos = pos, node_size= 800, node_color='r')
nx.draw_networkx_labels(G, pos = pos, font_size = 23)
nx.draw_networkx_edge_labels(G, pos = pos, edge_labels=weight, font_size=23)

e = nx.draw_networkx_edges(G, pos = pos, edge_color='g', arrowsize=50, node_size = 800)
nx.draw_networkx_edge_labels(G, pos = pos, edge_labels=weight, font_size=23)

e[0]._connector = SelfLoop(1,1).style() #select self loop and change connector
ax.add_patch(e[0]) #add the patch to ax 

e[-1]._connector = SelfLoop(-2,1).style()
ax.add_patch(e[-1])

ax.autoscale_view() #rescale so all edges are shown

plt.show()

结果,具有不同的self循环:

我很感激你能给我一些建议,告诉我你该如何做得更好。

相关问题