지난 포스팅에서는 엑셀 파일을 csv 파일로 저장하고,
주피터 노트북에서 파이썬으로 csv 파일을 읽는 방법을 살펴보았다.
(https://agentsmith.tistory.com/6)

 

이번 포스팅에서는 읽어들인 csv 파일의 데이터를 이용해 그래프를 그리는 방법을 알아보자.
먼저 그래프를 그리는데 필요한 matplotlib 라이브러리를 설치 후 matplotlib.pyplot를 import 해준다.
그리고 한글 폰트를 그래프에서 사용하기 위해 marplotlib.font_manager 역시 import 해주자.

 

pip install matplotlib
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
 

아래와 같이 font_list 를 찍어보면 현재 컴퓨터에 설치되어있는 모든 ttf 폰트 리스트를 확인할 수 있다.

 

font_list = fm.findSystemFonts(fontpaths = None, fontext = 'ttf')
font_list
 

이 중에서 사용하고 싶은 폰트를 골라 아래처럼 지정해주면 한글 폰트가 깨지는 현상 없이 그래프에서
x축, y축의 이름 등으로 한글을 사용할 수 있다. 나는 'AppleGothic' 폰트를 기본 폰트로 지정해 주었다.

 

plt.rc('font', family='AppleGothic')
 

그 다음 지난 포스팅에서와 같은 방법으로 데이터를 담고 있는 csv 파일을 가져온다.
내 데이터 파일의 내용은 아래 그림과 같다.

 

import pandas as pd
# csv파일 불러오기
df = pd.read_csv('fruit2.csv', low_memory = False)

아래와 같은 코드들을 이용하면 기존의 데이터파일 표를 특정 칼럼만 남기거나,
특정 값을 포함/제외하는 행만을 추출하는 등 표의 모양을 원하는대로 변형할 수 있다.

 

data1 = df[["과일"]]
data2 = df[df['가격'] > 200]

모든 준비가 끝났다! 이제 데이터를 이용해 다양한 종류의 막대그래프를 그려보자.


1. 세로(수직) 막대그래프

첫번째로 x축이 과일의 종류, y축이 과일의 개수인 세로 막대그래프를 그려보자.

이를 위해 데이터에서 x축이 될 데이터의 리스트와 y축이 될 리스트를 뽑아줘야 한다.

x축은 과일의 종류로 두고 싶기 때문에, 먼저 우리가 가지고 있는 표의 '과일' 칼럼을 리스트로 뽑아보자.

 

fruit = df['과일'].dropna().values.tolist()

 

이제 fruit 변수는 데이터의 모든 과일 종류를 포함하는 리스트가 되었다.

.dropna( )는 비어있는 행을 제외시키는 옵션이다.

표의 행 중에서 '과일' 부분이 비어있는 경우 해당 행의 데이터는 fruit 리스트에 포함되지 않는다.

 

우리는 과일의 종류와 개수를 알고 싶기 때문에, 리스트 안에 몇가지 종류의 과일들이 각각 몇개씩 있는지 뽑아보자.

이를 위해 파이썬의 numpy 라이브러리가 필요하므로, 해당 라이브러리를 설치 한 뒤 import 해준다.

그 다음 np.unique 툴을 이용해 fruit 리스트 내부에 어떤 종류의 과일들이 각각 몇개씩 있는지를 계산한다.

 

pip install numpy
import numpy as np
fruit_name, fruit_number = np.unique(fruit, return_counts=True)

fruit_name은 모든 과일의 종류를, fruit_number는 각 과일 종류별 개수를 담고 있는 array가 되며
우리가 가진 데이터 파일 내부에는 딸기, 바나나, 사과가 각각 4개, 2개, 3개가 있음을 알 수 있다.

이제 fruit_name과 fruit_number를 각각 x축, y축으로 가지는 세로막대그래프를 그려보자.

 

plt.bar(fruit_name, fruit_number, width=0.8, color='green', alpha=0.5)
plt.title('과일의 개수와 종류')
plt.xlabel('< 과일 종류 >',fontsize=12)
plt.ylabel('< 개수 >',fontsize=12)
plt.rc('xtick', labelsize=12)
plt.rc('ytick', labelsize=12)
plt.rcParams["figure.figsize"] = (4,4)
plt.grid(axis='y',linestyle='--',alpha=0.5)
plt.savefig('과일의 개수와 종류.png',bbox_inches='tight')
 

plt.bar 는 세로 막대그래프를 그릴 수 있는 함수이다. 차례대로 x축, y축 값이 들어가며
width는 그래프 막대의 너비를 설정하는 변수이고, color는 막대의 색깔,
alpha는 막대의 투명도이다(0과 1사이의 숫자, 낮을수록 투명도해짐).

title은 그래프의 제목으로 위쪽에 표시되며,
xlabel과 ylabel은 각각 x축, y축의 이름으로 각 축 옆쪽에 표시된다
폰트 사이즈도 설정할 수 있으며 x축과 y축 눈금의 폰트 사이즈는
 plt.rc함수에서 x/ytick으로 조절하면 된다.

 

rcParams["figure.figsize"] 는 그래프의 전체적인 크기를 조정하는 툴이다. (가로, 세로) 로 길이를 입력하면 된다.

plt.grid는 그래프 배경에 눈금을 표시할 수 있는 툴이다.
나는 y축 값들의 기준 눈금만 표시하기 위해 
axis='y' 옵션을 설정해 주었고,
linestyle을 -- 로 두면 눈금을 점선으로 만들 수 있다. alpha는 눈금의 투명도를 의미한다.

 

plt.savefig를 이용하여 생성된 그래프 이미지를 저장할 수 있다.
bbox_inches 옵션을 사용하면 그래프를 저장할 때 알 수 없는 오류에 의해서 그래프가 잘리는 것을 방지할 수 있다.

 

저장된 그래프 이미지는 주피터 노트북 홈에서 확인 및 다운로드 받을 수 있다.

 

 

plt.text 함수를 포함하는 아래 내용을 추가하면 위 오른쪽 그래프처럼 막대 위에 y축 값을 표시할 수 있다.
이는 그래프의 수치값을 정확하게 확인하는 데에 용이하다.

 

for i, v in enumerate(x):
    plt.text(v, y[i], y[i],
    fontsize = 10, 
    horizontalalignment='center',
    verticalalignment='bottom')
plt.bar(fruit_name, fruit_number, width=0.8, color='green', alpha=0.5)
plt.title('과일의 개수와 종류')
plt.xlabel('< 과일 종류 >',fontsize=12)
plt.ylabel('< 개수 >',fontsize=12)
plt.rc('xtick', labelsize=12)
plt.rc('ytick', labelsize=12)
plt.rcParams["figure.figsize"] = (4,4)
plt.grid(axis='y',linestyle='--',alpha=0.5)

for i, v in enumerate(fruit_name):
    plt.text(v, fruit_number[i], fruit_number[i],
    fontsize = 10, 
    horizontalalignment='center',
    verticalalignment='bottom')

plt.savefig('과일의 개수와 종류.png',bbox_inches='tight')
 

아래 내용들을 추가하면 x축 또는 y축의 눈금 폰트를 기울기를 조절할 수 있다.
이는 눈금 라벨의 내용이 너무 길어서 라벨끼리 겹쳐 버리는 경우에 유용하다. n자리에 숫자를 넣어 사용하면 된다.

 

plt.xticks(rotation = n)
plt.yticks(rotation = n)
plt.xticks(rotation=12) 를 적용한 것과 적용하지 않은 것의 차이

2. 가로(수평) 막대그래프

두번째로 x축이 과일의 개수, y축이 과일의 종류인 가로 막대그래프를 그려보자.
아래처럼 세로 막대그래프에서 x축 라벨 값의 이름이 너무 길거나 그 개수가 많을 때에는 가로 막대그래프를 사용하는 것이 더 좋다.

 

그럼 세로 막대그래프를 그릴 때 사용한 데이터를 이용해 가로(수평) 막대그래프를 그려보자.

 

plt.barh(fruit_name, fruit_number, height=0.8, color='green', alpha=0.5)
plt.title('과일의 개수와 종류')
plt.xlabel('< 개수 >',fontsize=12)
plt.ylabel('< 과일 종류 >',fontsize=12)
plt.rc('xtick', labelsize=12)
plt.rc('ytick', labelsize=12)
plt.rcParams["figure.figsize"] = (4,4)
plt.grid(axis='x',linestyle='--',alpha=0.5)

for i, v in enumerate(fruit_number):
    plt.text(v+0.01, i, str(v), fontsize = 10)

plt.savefig('과일의 개수와 종류2.png',bbox_inches='tight')
 

가로 수평 막대그래프는 plt.barh 함수를 사용한다.
plt.bar 와는 반대로 y축, x축 값 순서대로 들어가며 width 대신 
height를 사용한다. 나머지 것들은 동일하며, annotation 방식이 조금 더 간편하다.

아래 왼쪽의 그래프가 위 코드의 실행 결과로 얻어지는 가로 막대그래프이다.
그런데 y축의 값이 위에서 아래로가 아닌, 아래에서 위로 가나다순 정렬이 되어 있는 것을 볼 수 있다.
위에서 아래로 가나다순 정렬이 되도록 하기 위해선 fruit_name과 fruit_number의 순서를 뒤집어 주어야 한다.

 

#array를 list로 변환 후 순서 reverse
fruit_name = fruit_name.tolist()
fruit_number = fruit_number.tolist()
fruit_name.reverse()
fruit_number.reverse()
 

array인 상태에서는 손쉽게 순서를 뒤집을 수 없으므로 먼저 두 array를 list로 변환해 준 다음,
.reverse( ) 를 이용하면 손쉽게 순서를 반대로 뒤집을 수 있다.
위 과정을 거친 다음 그래프를 다시 그리면 위의 오른쪽 그림처럼 y축이 위에서 아래로 가나다순 정렬된 그래프를 그릴 수 있다.


3. 다중 막대그래프 그리기

지금까지는 한 종류의 막대그래프만 좌표 위에 그리는 방법을 알아보았다.

이번에는 두가지 데이터의 그래프들을 서로 비교하기에 용이한 다중 막대그래프 그리는 방법을 알아보자.

 

1) 나란히 다중 막대그래프

먼저 두가지 종류의 막대그래프가 나란히 놓이는 경우이다.

아래 두가지 막대 그래프를 하나의 나란히 다중 막대그래프로 그려보자.

 

fruits = ['딸기','바나나','사과']
a = [4,2,3]
b = [3,5,1]
 
x = np.arange(len(fruits))

fig, ax = plt.subplots()
rects1 = ax.bar(x - width/2, a, width=0.4, label='강아지 농장', color = 'green'
                , alpha = 0.5, align='center')
rects2 = ax.bar(x + width/2, b, width=0.4, label='고양이 농장', color = 'hotpink'
                , alpha = 0.5, align='center')

ax.set_ylabel('< 개수 >', fontsize=12)
ax.set_xlabel('< 과일종류 >', fontsize=12)
ax.set_title('강아지/고양이 농장 과일의 개수와 종류', fontsize=12)
ax.set_xticks(x)
ax.set_xticklabels(fruits)
ax.legend(fontsize=12)

def autolabel(rects):
    for rect in rects:
        height = rect.get_height()
        ax.annotate('{}'.format(height),
                    xy=(rect.get_x() + rect.get_width()/2, height),
                    xytext=(0, 3),
                    fontsize = 10, 
                    textcoords="offset points",
                    ha='center', va='bottom')
        
autolabel(rects1)
autolabel(rects2)

plt.yticks(fontsize=12)
plt.xticks(fontsize=12)
plt.rcParams["figure.figsize"] = (8,6)
plt.grid(axis='y',linestyle='--',alpha=0.5)
plt.show()
 

나란히 다중 막대그래프를 그리는 것은 하나의 좌표평면에 여러개의 막대를 배치하는 원리이다.

즉 하나의 좌표평면에 막대 그래프를 두번 그리되, 두 막대 그래프가 나란히 겹치지 않게 놓일 수 있도록 그려질 위치를 조정해 주는 것이다.

먼저 하나의 공통된 좌표평면이 필요하기 때문에 fig, ax = plt.subplots( ) 로 공통좌표평면 fig를 정의해준다.

rects1과 rects2를 보면 x - width/2, x + width/2 라고 되어있는데 이걸로 막대 위치를 조절할 수 있다.

우리는 두개의 막대가 좌우로 나란히 놓이는 것을 원하기 때문에, 원래는 같은 위치 x에 같은 막대 두개가 놓이므로

x - width/2, x + width/2 처리를 해서 막대 하나는 왼쪽에, 다른 하나는 오른쪽에 놓이게 하는 것이다.

 

 

따라서 막대의 개수가 두개보다 많은 경우 그에 알맞게 한칸, 두칸씩 위치를 조절해주면 몇개가 되었든지 나란히 놓이게 할 수 있다.
annotation 역시 막대 바로 위에 숫자가 쓰여질 수 있도록 위치를 조정하면 된다. (autolabel 함수 내용 참고)

 

# 위에서 아래로 가나다순 배치를 위해 리스트 순서 뒤집기
fruits.reverse();a.reverse();b.reverse()

x = np.arange(len(fruits))
height = 0.4

fig, ax = plt.subplots()
rects1 = ax.barh(x+height/2, a, height, label='강아지 농장', color = 'green'
                 , alpha = 0.5, align='center')
rects2 = ax.barh(x-height/2, b, height, label='고양이 농장', color = 'hotpink'
                 , alpha = 0.5, align='center')

for i, v in enumerate(a):
    plt.text(v+0.05, i+height/2, str(v), fontsize = 10)
for i, v in enumerate(b):
    plt.text(v+0.05, i-height/2, str(v), fontsize = 10)

ax.set_xlabel('< 개수 >', fontsize=12)
ax.set_ylabel('< 과일 종류 >', fontsize=12)
ax.set_title('강아지/고양이 농장 과일의 개수와 종류', fontsize=12)
ax.set_yticks(x)
ax.set_yticklabels(fruits)
ax.legend(fontsize=12, loc='lower right')

plt.yticks(fontsize=12)
plt.xticks(fontsize=12)
plt.rcParams["figure.figsize"] = (6,8)
plt.grid(axis='x',linestyle='--',alpha=0.5)
plt.show()
 

가로 말고 세로로 나란히 다중 막대그래프를 그리는 방법 역시 동일하다.
bar 대신 barh를 사용하며 좌, 우가 아닌 위, 아래로 막대의 위치를 조정해주면 된다.
annotation 작업은 plt.text 가 있는 부분에서 이루어진다.

 

2) 누적 다중 막대그래프

누적 다중 막대 그래프란 하나의 막대에 여러개의 막대 정보가 담기는 그래프를 의미한다.
나란히 다중 막대 그래프는 두가지 그래프를 비교하기 용이했다면, 누적 다중 막대그래프는 두가지 그래프 값의 차이가 얼마나 되는지를
한눈에 살펴보기에 좋다. 아래 두 그래프를 두가지 형태의 누적 다중 막대그래프로 그려보자.

 

먼저 두 그래프를 완전히 겹치게 놓는 경우이다.
이는 하나의 그래프의 값들이 다른 그래프의 값들보다 모두 작거나 클때 사용하는 것이 좋다.
그렇지 않으면 둘 중 무조건 하나의 그래프가 앞에 놓이는 과정에서 다른 그래프가 앞 그래프에 가려져 잘 안보일 수 있기 때문.

 

plt.bar(fruits, b, width=0.8, color='hotpink', alpha=0.8, label='고양이 농장')
plt.bar(fruits, a, width=0.8, color='green', alpha=1, label='강아지 농장')

plt.title('강아지/고양이 농장 과일의 종류와 개수')
plt.ylabel('< 개수 >',fontsize=12)
plt.xlabel('< 과일 종류 >',fontsize=12)
plt.rc('xtick', labelsize=12)
plt.rc('ytick', labelsize=12)
plt.rcParams["figure.figsize"] = (5,5)

annotation(fruits,a)
annotation(fruits,b)

plt.grid(axis='y',linestyle='--',alpha=0.5)
plt.legend(fontsize=10, loc='upper left')
 

별다른 작업 없이 뒤에 올 그래프를 먼저 그리고, 앞에 올 그래프를 나중에 그리면
두가지 그래프가 겹쳐져 그려지게 된다. 쉽죠?

 

두번째는 하나의 그래프 위에 다른 그래프를 쌓아 올리는 방법이다.

즉 새로운 그래프의 막대 하나는 두 그래프에서 가져온 각 막대의 합이 된다.

 

plt.bar(fruits, a, width=0.8, color='green', alpha=1, label='강아지 농장')
plt.bar(fruits, b, width=0.8, color='hotpink', alpha=0.8, bottom=a, label='고양이 농장')

plt.title('강아지/고양이 농장 과일의 종류와 개수')
plt.ylabel('< 개수 >',fontsize=12)
plt.xlabel('< 과일 종류 >',fontsize=12)
plt.rc('xtick', labelsize=12)
plt.rc('ytick', labelsize=12)
plt.rcParams["figure.figsize"] = (5,5)

annotation(fruits,a)
c = [a[i]+b[i] for i in range(len(a))]
annotation(fruits,c)

plt.grid(axis='y',linestyle='--',alpha=0.5)
plt.legend(fontsize=10, loc='upper left')
 

아래쪽에 놓일 그래프를 먼저 그리고, 윗쪽에 놓일 그래프를 나중에 그려주면 된다.

윗쪽에 놓일 그래프를 그릴 때는 위에서 bottom=a 를 해준 것처럼 막대가 솟아오르는 위치를

먼저 그린 첫번째 그래프의 각 막대가 끝나는 지점으로 지정해 주어야 한다.

그리고 두번째 그래프를 쌓아올렸기 때문에 분홍색 막대 위에는 두 막대 길이의 '합'이 숫자로 나타나야 한다.

따라서 각 막대 길이의 합을 annotation 함수에 두번째 매개변수로 넣어줘야 하므로

c = [a[i]+b[i] for i in range(len(a))] 를 통해 a와 b의 각 값을 더한 새로운 리스트 c를 만들어

annotation(fruits,c) 로 넘겨주면 된다.


지금까지 주피터 노트북에서 파이썬을 이용해 여러 종류의 막대그래프를 그리는 방법을 알아보았다.

막대그래프 외에도 파이차트, 스캐터플롯 등 matplotlib으로 그릴 수 있는 그래프는 정말 많지만,

데이터를 정확하고 직관적으로 도식화할 수 있어 자주 사용되는 그래프는 막대그래프이기에 이를 중점적으로 다루었다.

matplotlib 라이브러리를 이용해 그릴 수 있는 더 다양한 그래프가 궁금하다면 아래 링크를 살펴보는 것을 추천한다.
(matplotlib.org)

 

또한 matplotlib 말고 seaborn 라이브러리를 이용해 그래프를 그리는것도 가능하다.

seaborn은 사용 방법이 조금 복잡하지만, matplotlib보다 훨씬 예쁘고 더 다양한 모양의 그래프를 그릴 수 있다.

seaborn으로 그릴 수 있는 다양한 그래프의 종류는 아래 링크에서 확인할 수 있다.
(seaborn.pydata.org)

 

대부분의 보고서를 작성할 때, 그래프와 함께 그래프의 내용이 정리된 표를 함께 첨부하는 것이 바람직하다.

즉, 표와 그래프는 거의 항상 함께 붙어다닌다고 해도 과언이 아니다.

그럼 다음 포스팅에서는 파이썬을 이용해 손쉽게 표를 그리는 방법을 알아보자.

 

 

주피터노트북(랩)에서 파이썬을 이용해 데이터를 도식화하는 방법을 알아보자.

대학교 행정실이나 국가 공공기관 등 에서는 데이터를 엑셀로 정리하는 경우가 많으므로,

이 방법은 한번만 잘 정리해두거나 기억해두면 두고두고 유용하게 써먹을 수 있다.

 

1. 엑셀 파일을 csv 파일로 변환하기

먼저 엑셀(xlsx) 파일을 파이썬에서 다루기 위해선 csv 파일로 변환해 주어야 한다.

csv 파일이란 엑셀 파일의 내용을 쉼표로 구분하는 파일이다.

따라서 csv 파일로 변환하게 되면 엑셀 파일을 텍스트편집기(메모장)에서도 열어볼 수 있다.

쉼표 외에 공백(prn)/tab(txt) 등으로 내용을 구분하는 파일 형식도 존재한다.

 

 
먼저 엑셀에서 표를 하나 작성해 준다 (fruit.xlsx)
 

 

그리고 파일을 저장할 때 'CSV UTF-8(쉼표로 분리)' 형식을 선택해 저장해준다.

비슷한 옵션으로 '쉼표로 구분된 값 (.csv)' 이 있는데 이걸 선택하면 파이썬에서 파일을 불러올 때 오류가 발생하므로
반드시 urf-8 이 들어간 옵션을 선택하자.

 

 

올바르게 저장이 되었다면 이렇게 파일 뒤에 .csv 확장자가 붙게 된다.

텍스트 편집기(메모장)로 해당 파일을 열어보면 엑셀 표에서 작성되었던 내용들이

쉼표로 구분되어 있는 것을 확인할 수 있다.


2. 주피터 노트북 시작하기

그럼 본격적으로 주피터 노트북에서 csv 파일을 열어보자.

먼저 주피터 노트북이란 구글 코랩처럼 인터넷에서 파이썬 설치 없이 손쉽게 파이썬 코딩을 할 수 있는 프로그램으로,

커맨드창이나 터미널창에서 설치할 수 있다. 자세한 설치 방법은 아래 링크 참고.

https://hello-bryan.tistory.com/8

주피터 노트북 설치를 마쳤으면 'jupyter notebook' 명령어를 통해 프로그램을 실행시킬 수 있다.

 

usernameui-MacBook:~ username$ jupyter notebook

 

프로그램이 실행되면 주피터 노트북 홈 화면이 새 창으로 열릴 것이다.

우측 상단의 New - Python3 를 눌러 새로운 파이썬 파일을 생성한다.

파이썬을 따로 설치한 적이 없어도 주피터 노트북을 통해 파이썬 파일 작성이 가능하는 점이 장점이다.

이 때문에 아이패드 같은 기기로도 간단한 파이썬 코딩이 가능하다.

 

새로운 파일이 생성되면 제목을 두번 클릭해 파일 제목을 설정할 수 있다.


3. numpy, pandas 라이브러리 설치 후 사용하기

csv파일을 열기 위해 필수적인 파이썬 라이브러리는 pandas이다.

주피터 노트북 파일에서 파이썬 명령어를 입력해 라이브러리를 설치하고 import 해주자.

 

pip install pandas
import pandas as pd
 

'import padas as pd' 는 앞으로 pandas pd라고 부르겠다는 의미이다.

pandas 라이브러리 툴을 사용할 때 예를들면 앞에 pandas.read_csv 이런 식으로 라이브러리 이름을 붙여줘야 하는데,
pandas를 as pd로 import 하게 되면 pandas 대신 pd.read_csv의 형식으로 툴을 사용할 수 있는 것이다.

 

그럼 아까 저장해 두었던 csv 파일을 주피터 노트북 홈 화면에서 업로드 한 다음,

pandas 라이브러리의 read_csv를 이용해 csv 파일을 읽어보자.

 

# csv파일 불러오기
df = pd.read_csv('fruit.csv', low_memory = False)
df

 

 

그럼 엑셀 표에서 작성했던 표를 그대로 주피터 노트북 화면에서 확인할 수 있다.

이처럼 쉼표로 구분된 csv 파일을 pandas로 열면 위와 같은 표 형태로 나타나게 되어 사용이 편리하다.

read_csv 에서 low_memory = False 옵션을 사용하는 이유는, 데이터가 큰 파일을 다룰 때 에러가 발생하는 것을 방지하기 위해서이다.
(내가 사용한 fruit.csv 파일은 크기가 작아서 안써도 상관은 없지만)

 

low_memory = True로 설정해두면 데이터 파일을 열 때 pandas씨 께서 각 칸에 들어있는 정보의 데이터타입이 무엇인지를 '일일이 체크'한다('번호' 칼럼의 1 은 int, '과일' 칼럼의 '딸기'는 str 등). 

하지만 low_memory = False로 설정해두면 데이터파일을 열 때 pandas씨 께서 각 칸에 들어있는 정보의 데이터타입이 무엇인지 일일이 체크하지 않고, '어림짐작한다'. 즉 더 큰 범주의 데이터타입으로 해당 컬럼의 모든 데이터타입을 통일시킨다.

 

아래는 같은 파일을 low_memory = True 로 파일을 오픈했을 때와
low_memory = False 로 오픈했을 때의 차이를 예시를 통해 나타낸 것이다.

 

 

지금까지 엑셀 파일을 csv 파일로 저장하고, 주피터 노트북에서 파이썬으로 csv 파일을 읽는 방법을 살펴보았다.

다음 포스팅에서는 파이썬을 이용해 csv 파일을 분석하고 그 내용을 그래프로 도식화하는 방법을 살펴보자.