[Python] 데이터 시각화 - Matplotlib
데이터 시각화 - Matplotlib
0. Matplotlib
- 파이썬의 대표적인 과학 계산용 그래프 라이브러리입니다.
- 판다스에 연계되어있어 사용하기 편리합니다.
Matplotlib 라이브러리는 보통 아래와 같은 코드로 불러옵니다.
#기본 import 라이브러리
import matplotlib as mpl # 기본 설정 만지는 용도
import matplotlib.pyplot as plt # 그래프 그리는 용도
import matplotlib.font_manager as fm # 폰트 관련 용도
- 한글 폰트 설정
Matplotlib는 기본적으로 한글 폰트를 지원하지 않기 때문에 따로 설정해주어야 합니다.
1) matplotlib에서 사용할 수 있는 폰트를 담아두는 위치를 찾아 해당 위치에 사용할 한글폰트 ttf파일을 넣어줍니다.
일반적으로 나눔고딕 폰트를 많이 사용합니다.
print(mpl.matplotlib_fname())
2) 변경된 내용이 인식될 수 있도록 아래 경로에 있는 fontlist 파일을 삭제해줍니다.
print(mpl.get_cachedir())
3) matplotlib의 기본 설정을 한글 폰트로 바꿔주는 코드를 실행합니다.
#한글 폰트 설정
plt.rc('font', family='NanumGothic')
#-기호 깨짐 현상 방지를 위한 설정
plt.rc('axes', unicode_minus=False)
- 그래프 기본 구성
그래프는 기본적으로 배경(figure)과 축(axes)으로 구성되어 있습니다.
plt.figure: 축과 그래픽, 텍스트, 레이블을 표시하는 모든 객체를 포함하는 컨테이너
plt.axes: 눈금과 레이블이 있는 테두리 박스
plt.figure() #도화지를 만들고
plt.axes() #축을 그 위에 그립니다.
1. Line graph
x축과 y축에 대응하는 값을 넣어주면 각 점을 선으로 연결해서 선 그래프를 그려줍니다.
plt.plot(x, y)
x = [0, 2, 4, 6, 8]
y = [1, 2, 3, 4, 5]
plt.plot(x, y); # x축과 y축에 대응하는 값을 넣으면 선으로 연결해줌
#세미콜론을 넣으면 주소를 출력하지 않음
선 위에 입력한 각각의 점을 도형으로 찍어주는 marker 옵션을 이용할 수 있습니다.
지정할 수 있는 값들은 's', 'o', '^' 등이 있습니다.
마커와 관련된 추가적인 옵션들은 다음과 같습니다.
markersize, ms : 마커사이즈
markeredgecolor, mec: 마커 선 색깔
markeredgewidth, mew: 마커 선 굵기
markerfacecolor, mfc: 마커 내부 색깔
plt.plot(x, y, marker='s'); #선 위에 각각의 점을 'square'로 찍어줌
선의 종류를 지정해주는 linestype 옵션도 사용할 수 있습니다.
'-'(solid), '--'(dashed), '-.'(dashdot), '.'(dotted) 등으로 선의 종류를 선택할 수 있습니다.
plt.plot(x, y, linestyle = 'dashed'); #linestype = '--'와 동일
그래프를 작성하는 코드를 여러개 넣고 동시에 실행하면 한 도화지에 해당 그래프들이 모두 그려지게 됩니다.
그래프마다 옵션을 다르게 두고 어떻게 그려지는지 하나의 도화지에서 확인해볼 수 있습니다.
#30개의 수를 랜덤으로 선정하고 누적합을 그래프로 나타냄
plt.plot(np.random.randn(30).cumsum(), linestyle='--', marker='^') #파란색 그래프
plt.plot(np.random.randn(30).cumsum(), linestyle='--', marker='x') #노란색 그래프
plt.plot(np.random.randn(30).cumsum(), linestyle='--') #초록색 그래프
그래프의 색을 지정해주는 옵션도 존재합니다.
color 옵션을 통해 지정할 수 있으며 약자나 full name, 컬러코드를 통해 지정할 수 있습니다.
plt.plot(np.random.randn(30).cumsum(), color='g') # 자체적으로 지정한 컬러의 약자
plt.plot(np.random.randn(30).cumsum(), color='green') # full name
plt.plot(np.random.randn(30).cumsum(), color='#DC7761') # 컬러코드로도 표현할 수 있습니다
지금까지 사용했던 옵션들을 모두 한꺼번에 적용한 그래프를 그려봅니다.
plt.plot(np.random.randn(30).cumsum(), 'r^-')
#marker, color, linestyle을 한꺼번에 지정해줘도 알아서 인식해서 그래프를 그려줌
2. Scatter Plot
산점도는 데이터의 좌표를 점으로 표현하는 그래프로서, 두 변수 사이의 관계를 확인할 때 적절합니다.
plt.scatter에도 plot에서 사용했던 marker와 color 옵션을 동일하게 사용할 수 있습니다.
plt.scatter(x, y)
x1 = [2, 3, 4]
y1 = [5, 5, 5]
x2 = [1, 2, 3, 4, 5]
y2 = [2, 3, 2, 3, 4]
y3 = [6, 8, 7, 8, 7]
plt.scatter(x1, y1)
plt.scatter(x2, y2, marker = 'v', color = 'r')
plt.scatter(x2, y3, marker = '^', color = 'm')
plt.title('Scatter Plot Example')
plt.show()
iris데이터를 불러와서 변수간의 관계를 산점도로 간단하게 시각화해 보겠습니다.
#데이터 불러오기
import seaborn as sns
iris = sns.load_dataset('iris')
#데이터셋을 종별로 분류
iris1 = iris[iris['species'] == 'setosa']
iris2 = iris[iris['species'] == 'virginica']
iris3 = iris[iris['species'] == 'versicolor']
#sepal_length와 sepal_width의 관계를 종별로 나눠서 시각화
plt.scatter(iris1['petal_length'], iris1['petal_width'], marker = '^', color = 'r')
plt.scatter(iris2['petal_length'], iris2['petal_width'], marker = 's', color = 'g')
plt.scatter(iris3['petal_length'], iris3['petal_width'], color = 'b')
petal_length가 길어질수록 petal_width도 넓어지는 관계가 존재하는 것을 확인할 수 있습니다.
또한 종별로 petal_length와 petal_width에 뚜렷한 차이가 존재함을 대략적으로 확인할 수 있습니다.
3. Bar Graph
바 그래프는 범주형 변수에서 각각의 범주가 나타난 빈도를 표시하기에 적합한 그래프입니다.
x축에 있는 값들을 y축에 있는 숫자(빈도)만큼의 막대로 보여줍니다.
plt.bar(x, y)
#데이터 생성
x1 = [1, 3, 4, 5, 6, 7, 9]
y1 = [4, 7, 2, 4, 7, 8, 3] #빈도를 표시
x2 = [2, 4, 6, 8, 10]
y2 = [5, 6, 2, 6, 2]
plt.bar(x1, y1)
x1 = [1, 3, 4, 5, 6, 7, 9]
y1 = [4, 7, 2, 4, 7, 8, 3]
x2 = [2, 4, 6, 8, 10] #6에는 두 값이 모두 들어가기 때문에 바그래프가 겹치게 됨
y2 = [5, 6, 2, 6, 2]
plt.bar(x1, y1, color='b')
plt.bar(x2, y2, color='g');
4. Histogram
바 그래프는 연속형 변수의 분포를 나타낼 수 있는 그래프입니다.
bin 옵션을 통해 막대(구간)의 수를 정할 수 있습니다.
plt.hist(x, y)
n = np.random.randn(1000) #랜덤 함수로 숫자 1000개 선정
plt.hist(n)
plt.hist(n, bins = 50); #구간의 개수를 50개로 지정
plt.hist(n, cumulative = True, bins = 20); #누적그래프
5. Stack Plot
idxes = [ 1, 2, 3, 4, 5, 6, 7, 8, 9]
arr1 = [23, 40, 28, 43, 8, 44, 43, 18, 17]
arr2 = [17, 30, 22, 14, 17, 17, 29, 22, 30]
arr3 = [15, 31, 18, 22, 18, 19, 13, 32, 39]
plt.stackplot(idxes, arr1, arr2, arr3, colors= ['r', 'g', 'b'])
plt.title('Stack Plot Example')
6. Pie Chart
labels = 'S1', 'S2', 'S3'
sections = [56, 66, 24]
colors = ['c', 'g', 'y']
plt.pie(sections, labels=labels, colors=colors,
startangle=90, #첫 조각의 시작 각도
explode = (0, 0, 0.1), # 틈새 설정
autopct = '%1.2f%%' # autopercent - 소수점 둘째짜리까지 비율 출력
)
plt.axis('equal')
plt.title('Pie Chart Example')
plt.show()
7. 그래프 꾸미기 옵션
1) 축 지정
plt.xlim(시작지점, 끝지점)
plt.ylim(시작지점, 끝지점)
plt.axis([x_min, x_max, y_min, y_max])
위 옵션들로 그래프의 x축과 y축의 범위를 지정할 수 있습니다.
plt.plot(np.random.randn(30).cumsum())
plt.xlim(0, 10); # x축의 범위
plt.ylim(0, 10); # y축의 범위
plt.axis('tight')를 사용하면 그래프가 가득 차도록 축을 알아서 조정하여 보여줍니다.
plt.axis('equal')을 사용하면 그래프가 대칭처럼 보이도록 축을 조정해줍니다.
plt.plot(np.random.randn(30).cumsum())
plt.axis('tight')
2) 레이블 지정
그래프의 제목을 지정하거나, x축과 y축의 이름을 지정해줄 수 있습니다.
또한 각 점이나 선에도 무엇을 의미하는지 이름을 달아줄 수 있습니다.
plt.plot(np.random.randn(30).cumsum())
plt.title('제목') #제목
plt.xlabel('x축') #x축 이름
plt.ylabel('y축'); #y축 이름
plt.plot(np.random.randn(30).cumsum(), label='A') #각 라인에 label을 달아줍니다.
plt.plot(np.random.randn(30).cumsum(), label='B')
plt.plot(np.random.randn(30).cumsum(), label='C')
plt.plot(np.random.randn(30).cumsum(), label='d')
plt.plot(np.random.randn(30).cumsum(), label='e')
plt.title('범례를 달아준 그래프')
plt.xlabel('x축')
plt.ylabel('y축')
plt.legend() # 범례를 통해 라인의 label을 보여줍니다
점이나 선에 label을 달아 명시해줄 경우 plt.legend()를 통해 범례를 달아줄 수 있습니다.
범례의 위치는 loc이라는 옵션을 통해 'upper', 'lower', 'left', 'right'로 지정할 수 있고,
frameon = True, False 라는 옵션을 통해 범례의 테두리 유무를 지정할 수 있습니다.
3) fill_between & alpha
fill_between은 선 아래의 영역을 채워주는 옵션입니다.
alpha를 지정하면 도형의 투명도를 조정할 수 있습니다.
n = np.random.randn(100)
x = range(100)
plt.plot(x, n)
plt.fill_between(x, n, -3, where = (n > -3), alpha = 0.4)
8. 그래프 여러개 그리기
하나의 도화지에 여러개의 그래프를 나누어 그리는 옵션은 plt.subplot으로 지정할 수 있습니다.
plt.subplot(row, column, index)
각 그래프를 그리기 전에 subplot을 통해 그래프가 들어갈 좌표를 넣어주시면 됩니다.
#가로에 2개, 세로에 2개의 그래프 그리기
plt.subplot(2, 2, 1)
plt.plot(np.random.randn(30).cumsum(), 'g--')
plt.subplot(2, 2, 2)
plt.plot(np.random.randn(30).cumsum(), 'r')
plt.subplot(2, 2, 3)
plt.plot(np.random.randn(30).cumsum(), '^-')
plt.subplot(2, 2, 4)
plt.plot(np.random.randn(30).cumsum(), 's--', color = 'orange')
그래프를 여러개 그릴 때 축을 공유하여 그리고싶다면
plt.subplot(row, column, index, sharex = 기준 subplot)
#x축을 공유하여 그래프 그리기
ax1 = plt.subplot(2,1,1)
plt.plot(np.random.randn(30).cumsum(), 'g--')
plt.xticks(visible = False) #축을 동일하게 사용하기 때문에 위 그래프의 축을 가림
ax2 = plt.subplot(2,1,2, sharex = ax1)
plt.plot(np.random.randn(30).cumsum(), 's--', color = 'orange');