ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [NetworkX] 멀티그래프, Multigraph (파이썬 네트워크 분석 4)
    Data & ML & AI/NetworkX 2022. 8. 2. 22:11
    반응형

    멀티 그래프(Multi Graph) 생성하고 그리기

    노드와 노드는 단 하나의 관계만으로 정의되지 않는 경우가 많습니다.

    친구이면서도 직장동료일 수도 있고, 학교 선후배이면서도 커플일 수도 있습니다.

     

    한 쌍의 노드가 여러개의 관계, 엣지를 동시에 가질 수 있는 그래프를 멀티그래프(Multigraphs)라고 부릅니다.

     

    그래프 생성하기

    import networkx as nx
    # %matplotlib notebook
    
    G = nx.MultiGraph()
    
    family = [('G','F'),('D','E')]
    friend = [('A','B'),('C','F'),('C','E'),('E','J')]
    coworker = [('B','C'),('C','F'),('I','J'),('E','H'),('G','F'),('E','I')]
    neighbor = [('E','I'),('A','B')]
    
    G.add_edges_from(family,relation='family')
    G.add_edges_from(friend,relation='friend')
    G.add_edges_from(coworker,relation='coworker')
    G.add_edges_from(neighbor,relation='neighbor')
    
    # 아래에 계속...

    그리고 그래프를 그릴때는 각 관계들마다 서로다른 색깔을 부여하고자 했습니다.

    pos=nx.spring_layout(G) # 각 노드, 엣지를 draw하기 위한 position 정보
    relation = nx.get_edge_attributes(G, 'relation')
    
    
    nx.draw(G,pos, with_labels=True, edge_color='white')
    nx.draw_networkx_edges(G,pos, edgelist=family, edge_color='Y')
    nx.draw_networkx_edges(G,pos, edgelist=friend, edge_color='B')
    nx.draw_networkx_edges(G,pos, edgelist=coworker, edge_color='R')
    nx.draw_networkx_edges(G,pos, edgelist=neighbor, edge_color='violet')

    draw_networkx_edges에서 edge_color를 추가해주면 해당 엣지들의 색상을 지정할 수 있습니다.

    nx.draw에서 아예 선을 안그리는 방법을 못찾겠어서 그냥 edge_color='white'라고 해버렸습니다 (머쓱)

    어... 엣지가 다 겹쳐서 나오네??

    하지만 이렇게 하니 문제가 발생했습니다.

    서로 다른 엣지가 겹쳐서 나온다는 것입니다.

     

    이를 해결해주려면 엣지에 곡선을  부여해 줘야 합니다.

     

     

    그래프 그리기

    하지만 불행하게도 MultiGraph()로 만든 그래프는 엣지가 휘지 않았습니다. (혹시라도 방법을 아는 분께서는 댓글 부탁드리겠습니다ㅜㅜ)

    그래서 여기저기 검색한 내용을 짜깁기 해서 다른 방법으로 그려보았습니다.

    import networkx as nx
    # %matplotlib notebook
    
    G = nx.DiGraph()
    
    family = [('G','F'),('D','E')]
    friend = [('A','B'),('C','F'),('C','E'),('E','J')]
    coworker = [('B','C'),('C','F'),('I','J'),('E','H'),('G','F'),('E','I')]
    neighbor = [('E','I'),('A','B')]
    
    G.add_edges_from(family,relation='family')
    G.add_edges_from(friend,relation='friend')
    G.add_edges_from(coworker,relation='coworker')
    G.add_edges_from(neighbor,relation='neighbor')
    
    pos=nx.spring_layout(G) # 각 노드, 엣지를 draw하기 위한 position 정보
    relation = nx.get_edge_attributes(G, 'relation')
    
    
    nx.draw(G,pos, with_labels=True, edge_color='white')
    nx.draw_networkx_edges(G,pos, edgelist=family, edge_color='Y', connectionstyle='arc3, rad = 0.2', arrowstyle='-')
    nx.draw_networkx_edges(G,pos, edgelist=friend, edge_color='B', connectionstyle='arc3, rad = 0.2', arrowstyle='-')
    nx.draw_networkx_edges(G,pos, edgelist=coworker, edge_color='R', connectionstyle='arc3, rad = -0.2', arrowstyle='-')
    nx.draw_networkx_edges(G,pos, edgelist=neighbor, edge_color='violet', connectionstyle='arc3, rad = -0.4', arrowstyle='-')

    한결 낫군요...

    stackoverflow에서는 "엣지 여러개 그리려면 어떻게 해야돼요?"라는 질문들에

    대다수 DiGraph()를 사용해서 해결법을 제시하고 있었습니다. (.....)

     

    MultiGraphDiGraph는 무방향성, 방향성이라는 점에서 매우 다르지만,

    여기서는 단순히 그래프를 그려보려는 것 뿐이니까 그들의 방법을 빌려왔습니다.

     

    그리고 connectionstyle을 이용해서 각 엣지에 곡선 성질을 부여해 주었습니다.

    그리고 우리는 화살표가 없는 엣지를 그리고 싶으므로,

    DiGraph(Direction Graph)의 엣지를 그릴때의 디폴트 값인 arrowstyle='-\|>'arrowstyle='-'로 변경해 주었습니다.

     

    반응형

    댓글

Designed by Tistory.