[NetworkX] 일단 그래프를 그려보자

김재동
zzolab
Published in
5 min readMar 20, 2021

교우 관계 분석 프로그램(이름은 쪼랩 프렌즈로 정했으므로 이하 쪼랩 프렌즈) 개발을 위해 본격적으로 NetworkX 공부에 돌입했다. 개발환경은 MacOS이고 Python3.6으로 개발하기 위해 brew로 파이썬과 NetworkX 모듈 설치도 마쳤다.

쪼랩 프렌즈의 가장 핵심 기능은 교우 관계 조사 결과를 ‘그래프’로 나타내는 것이다. 따라서 사회 관계망 분석 결과를 그래프로 제대로 그려낼 수 있는지 가장 먼저 확인해 보고 싶었다.

NetworkX의 홈페이지에 들어가 tutorial을 살펴보며 노드와 에지 생성법과 그래프를 그림으로 그리는 방법에 대해 살펴봤다.

그리고 다음과 같은 소스코드를 작성하고 실제로 제대로 그래프가 그려지는지 실행을 해보았다.

import networkx as nx
import matplotlib.pyplot as plt
DG = nx.DiGraph()DG.add_node('일번')
DG.add_node('이번')
DG.add_node('삼번')
DG.add_node('사번')
DG.add_edge('일번', '삼번')
DG.add_edge('삼번', '사번')
DG.add_edge('사번', '삼번')
nx.draw(DG)
plt.show()

그래프가 그려지기는 했는데 꼭짓점마다 이름이 자동으로 출력되지는 않는 것 같다. 검색을 좀 더 해보니 아래 코드처럼 draw 함수에서 with_labels = True 옵션을 주면 라벨이 함께 출력된다고 해서 수정 후 실행을 해보았다.

nx.draw(DG, with_labels = True)

그래프를 보아하니 한글이 깨진 것 같다. 그래프를 그려주는 라이브러리인 matplotlib와 관련이 있을 것 같아 matplotlib node label cjk character라는 키워드로 검색 후 stackoverflow의 답변 하나를 찾았다.

한글 폰트를 지정하고 테스트 삼아 그래프의 제목도 한글로 지정하기 위해 아래와 같은 코드를 추가하였다.

plt.rc('font', family='NanumBarunGothicOTF')
plt.title('쪼랩 프렌즈')

하지만 아래 그래프처럼 제목은 한글로 출력이 잘 되는데 노드는 여전히 한글이 깨져서 출력되었다.

혹시 노드 이름을 라벨로 바로 출력해서 그런 것인가 싶어 라벨을 따로 리스트로 지정해 출력해보았지만 큰 소득은 없었고 과연 노드 이름을 한글로 사용할 수 있는 것인지에 대해 확신을 할 수가 없었다. 쪼랩 프렌즈의 가장 핵심적인 부분이기 때문에 이것을 구현하지 못한다면 프로젝트를 진행하기가 매우 어려워질 것이라는 생각이 들었다.

몇 시간의 삽질 끝에 이유를 파악했는데 라벨에도 한글 폰트를 지정해줘야만 했다. 이것은 내가 NetworkX와 matplotlib의 관계를 잘 몰라서 발생한 문제이다. 처음에는 노드나 엣지, 그래프의 뼈대 생성과 같은 핵심 임무를 NetworkX가 수행하고 그것을 그림으로 나타내는 것은 모두 matplotlib가 하는 일이라고 생각했다. 그런데 제목만 한글로 잘 출력이 되고 노드는 출력이 제대로 되지 않는 것을 보고 그래프를 그리는 것 자체는 NetworkX에서 처리하고 matplotlib는 제목, 가로축, 세로축 등을 표현할 수 있는 바탕을 제공하는 것 같다는 생각이 들었다.

그래서 다음과 같이 소스코드를 수정하고 그래프를 그려보았다.

import networkx as nx
import matplotlib.pyplot as plt
plt.rc('font', family='NanumBarunGothicOTF')
plt.title('쪼랩 프렌즈')
DG = nx.DiGraph()DG.add_node('김연아')
DG.add_node('손연재')
DG.add_node('홍길동')
DG.add_node('윤종신')
DG.add_edge('김연아', '홍길동')
DG.add_edge('홍길동', '윤종신')
DG.add_edge('윤종신', '홍길동')
pos=nx.shell_layout(DG)nx.draw(DG)
nx.draw_networkx_labels(DG, pos, font_family='AppleGothic', font_size=10)
plt.show()

오오 한글이 나온다! 그런데 왜 저기에? 여러 번 실행을 해보아도 노드 위에 라벨이 제대로 출력되지 않았다. 그런데 여러 번 실행을 하면서 한 가지 공통점을 찾게 되었는데 노드의 위치는 변해도 노드 이름의 위치는 변하지 않는다는 것이었다. 그 무렵 나는 검색을 통해 Basic Graph Drawing이라는 글을 읽고 있었는데 이 글을 읽다가 그래프 레이아웃의 종류에 따라 그래프를 그리는 명령어가 따로 있다는 사실을 알게 되었다😅 nx.draw(DG)nx.draw_shell(DG)로 바꾸니 문제가 해결되었다.

그래프를 그릴 수 있다는 것을 확인했으니 다음에는

  • 실제 학급의 학생 수에 맞는 노드와 에지의 표현
  • 그래프 예쁘게 꾸미기

등을 간단히 점검해 보고 본격적인 프로그래밍에 들어가면 될 것 같다.

--

--

김재동
zzolab
Editor for

초등학교 교사. 초등교사 커뮤니티 인디스쿨 부대표 겸 기술연구팀장. Apple Distingsuiehd Educator.