혼자 공부하는 데이터 분석 with 파이썬 05-1 맷플롯립 기본 요소 알아보기

손지호·2024년 2월 3일
0
post-thumbnail

Figure 객체

Figure라는 모든 그래프 구성 요소를 담고 있는 최상위 객체가 있다. scatter() 함수로 산점도를 그릴 때 자동으로 피겨 객체가 생성된다! figuer() 함수로 명시적으로 피겨 객체를 만들어 활용하면 다양한 그래프 옵션을 조절할 수 있다.

import gdown

gdown.download('https://bit.ly/3pK7iuu', 'ns_book7.csv', quiet=False)

# 실습 데이터 불러오기
import pandas as pd

ns_book7 = pd.read_csv('ns_book7.csv', low_memory=False)
ns_book7.head()
>>> 번호	도서명	저자	출판사	발행년도	ISBN	세트 ISBN	부가기호	권	주제분류번호	도서권수	대출건수	등록일자
0	1	인공지능과 흙	김동훈 지음	민음사	2021	9788937444319	NaN	NaN	NaN	NaN	1	0	2021-03-19
1	2	가짜 행복 권하는 사회	김태형 지음	갈매나무	2021	9791190123969	NaN	NaN	NaN	NaN	1	0	2021-03-19
2	3	나도 한 문장 잘 쓰면 바랄 게 없겠네	김선영 지음	블랙피쉬	2021	9788968332982	NaN	NaN	NaN	NaN	1	0	2021-03-19
3	4	예루살렘 해변	이도 게펜 지음, 임재희 옮김	문학세계사	2021	9788970759906	NaN	NaN	NaN	NaN	1	0	2021-03-19
4	5	김성곤의 중국한시기행 : 장강·황하 편	김성곤 지음	김영사	2021	9788934990833	NaN	NaN	NaN	NaN	1	0	2021-03-19

산점도를 그려보자. 맷플롯립을 임포트하고 scatter() 함수로 '도서권수' 열을 x축, '대출건수' 열을 y축으로 그려진다. 투명도를 0.1로 지정하자.

import matplotlib.pyplot as plt

plt.scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1)
plt.show()
>>> 


그래프 크기 바꾸기: figsize 매개변수

figure() 함수를 사용하여 피겨 객체를 만들면 그래프 옵션을 조절할 수 있다. figsize 매개변수에 그래프의 크기를 튜플로 지정할 수 있다. 기본 그래프 크기는 (6,4)이고 각각 너비와 높이에 해당한다. 단위는 인치(inch)이다.

# figsize 매개변수를 (9,6)으로 지정하여 산점도를 크게 더 그려보자.
print(plt.rcParams['figure.figsize']) → 너비가 9인치, 높이가 6인치인 피겨 객체를 생성한다.
>>> [6.4, 4.8]

plt.figure(figsize=(9, 6))
plt.scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1)
plt.show()
>>> 


+ 기본 그래프 크기는 맷플롯립의 버전과 플랫폼에 따라 달라질 수 있다. 현재 설치된 맷플롯립의 기본 그래프 크기를 확인하려면 다음 명령 사용하자!

처음 그래프보다 그래프가 훨씬 커졌다!! plt.show() 함수가 호출되면 figure() 함수로 만들어진 피겨 객체는 자동으로 소멸된다. 그렇지만 9인치면 23센치미터에 가까운 길이인데 실제로 화면에 그려진 이미지는 이보다 작다. 화면상에 그려진 그래프의 실제 크기를 확인해보자.


그래프 실제 크기 확인하기

화면에 그려진 그래프에 마우스 오른쪽 버튼을 클릭하면 팝업 메뉴가 나타난다. [새 탭에서 이미지 열기]를 선택한 후 간단하게 모니터 화면에 실제로 자를 대고 그래프 크기를 확인해보자.

보통 컴퓨터 화면의 해상도를 말할 때 픽셀 수와 DPI를 사용한다. DPI는 dot per inch의 약자로 1인치를 몇 개의 점(픽셀(pixel))으로 표현하는지 나타낸다.
다시 말해 DPI에 따라 화면에 그려지는 그래프 크기가 달라진다. 맷플롯립의 기본 DPI는 72이다.

figsize 매개변수는 인치 단위로 값을 지정해야 한다. 인치 값은 먼저 원하는 픽셀 값을 정한 다음 픽셀 값을 DPI로 나누면 구할 수 있다. 예를 들어 900 X 600 픽셀 크기의 그래프를 그리고 싶다고 가정해보자. 맷플롯립의 DPI 기본값은 72이므로 다음처럼 두 픽셀 값을 72로 나누어 figsize 매개변수에 전달한다.

print(plt.rcParams['figure.dpi'])
>>>100.0

plt.figure(figsize=(900/72, 600/72))
plt.scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1)
plt.show()
>>>


그래프가 훨씬 크게 그려진다!!
그래프에서 마우스 오른쪽 버튼을 클릭하면 팝업 메뉴가 나타나는데 [이미지를 다른 이름으로 저장...]을 선택하여 이미지를 다운로드한다. 그리고 다운로드한 이미지 파일에서 마우스 오른쪽 버튼을 클릭한 후 [속성] - [자세히]를 클릭하면 픽셀 크기를 확인할 수 있다.

하지만 900x600 픽셀보다 조금 작다. 코랩 노트북은 기본적으로 맷플롯립 그래프를 출력할 때 그래프 주변에 공백을 최소화하는 타이트(tight) 레이아웃을 사용하기 때문이다.

# 타이트 레이아웃 사용하지 않으려면 맷플롯립 그래프를 그릴 때 bbox_inches 옵션을 None으로 지정한다.
%config InlineBackend.print_figure_kwargs = {'bbox_inches': None}
plt.figure(figsize=(900/72, 600/72))
plt.scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1)
plt.show()
>>> 


이미지 다운로드하여 다시 픽셀을 확인해보면 900x600인 것을 확인할 수 있다.

원하는 크기의 이미지를 얻었지만, 사실 노트북에서는 그래프 주변에 공백이 많으면 출력된 그래프와 코드를 나란히 놓고 보기 불편하다. 크기를 조정하는 방법을 알았으니 원래대로 타이트한 레이아웃으로 되돌아가자.

%config InlineBackend.print_figure_kwargs = {'bbox_inches': 'tight'}

그래프 크기 바꾸기: dpi 매개변수

이번에는 figsize 매개변수는 기본값 그대로 두고 dpi 매개변수를 지정해보자.

# DPI 기본값 72에서 두 배인 144로 늘리기.
plt.figure(dpi=144)
plt.scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1)
plt.show()
>>>

dpi 매개변수를 두 배로 늘리면 인치당 픽셀 수가 두 배로 늘어나기 때문에 그래프가 두 배 커진다. 또한 그래프 안의 모든 구성 요소도 함께 커진다. x축과 y축의 숫자가 커졌고, 데이터 포인트를 나타내는 동그라미 마커(marker)의 크기도 커졌다.


rcParams 객체

rcParams는 맷플롯립 그래프의 기본값을 관리하는 객체이다. 앞서 figure 객체의 figsize와 dpi 기본값을 확인할 때 사용해봤다. rcParams 객체는 객체에 담긴 값을 출력하는 것뿐만 아니라 새로운 값으로 바꿀 소도 있다. 이렇게 하면 이후에 그려지는 모든 그래프에 바뀐 설정이 적용된다.


DPI 기본값 바꾸기

먼저 기본 그래프 해상도를 높이기 위해 DPI 기본값을 바꾸어준다. figure 객체의 DPI 기본값을 100으로 바꾸려면 다음과 같이 작성한다.

plt.rcParams['figure.dpi'] = 100

산점도 마커 모양 바꾸기

산점도 그래프의 마커 기본값을 확인하려면 rcParams 객체의 속성을 scatter.marker로 지정한다. 객체를 그냥 출력하면 기본값인 동그라미를 나타내는 'o'가 출력된다.

plt.rcParams['scatter.marker']
>>> 'o'

마커를 별 모양으로 그리려면 값을 다음과 같이 '*'로 지정해준다.

plt.rcParams['scatter.marker'] = '*'

# 별 모양으로 그려지는지 확인!
plt.scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1)
plt.show()
>>>

하지만 여러 개의 산점도가 있고, 산점도마다 마커를 다르게 그려야 한다면 매번 scatter.marker 설정을 바꾸어야 하기에 너무 번거롭다. 이럴 때 기본값 수정하는 것 대신 scatter() 함수의 marker 매개변수로 마커의 모양을 지정하면 된다. 이렇게 하면 rcParams 객체의 scatter.marker 속성에 지정된 기본값을 무시하고 marker 매개변수에 지정된 값을 사용한다.

marker 매개변수를 '+'로 설정하여 덧셈 기호를 마커로 사용하면 다음과 같다.

plt.scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1, marker='+')
plt.show()


+ 맷플롯립 마커 옵션 : https://matplotlib.org/stable/api/markers_api.html#module-matplotlib.markers

성공!!!! 이처럼 객체의 기본값을 바꾸지 않아도 맷플롯립의 함수에서 제공하는 매개변수를 사용하면 그래프 설정 중 일부를 바로 바꿀 수 있다.


여러 개의 서브플롯 출력하기

하나의 피겨 객체 안에는 여러 개의 서브플롯(subplot) 을 담을 수 있다. 서브플롯이란 맷플롯립의 Axes 클래스의 객체를 말하며 하나의 서브플롯은 두 개 이상의 축(axis)을 포함한다. 일반적으로 2차원 그래프의 수평축을 x축이라고 부르고 수직축을 y축으로 부른다. 3차원 그래프라면 세 개의 축이 있다. 각 축에는 눈금 또는 틱(tick)이 표시된다. 또한 축의 이름을 나타내는 레이블(label)이 있다.
[294 그림삽입]


서브플롯 그리기: subplots() 함수

서브플롯 정의하려면 subplots() 함수에 원하는 서브플롯 개수를 지정하면 된다.
subplots() 함수로 두 개의 서브플롯을 그리고 싶다면 매개변수에 2를 넣어준다. 그 다음 이 배열의 원소에서 각각 scatter() 함수와 hist() 함수를 호출한다. 첫 번째 그래프인 산점도의 x축은 '도서권수' 열이고 y축은 '대출건수' 열이다. 두 번째 그래프는 히스토그램으로 x축은 '대출건수' 열이고 y축은 대출건수의 빈도에 해당한다. 이때 히스토그램의 y축은 로그 스케일로 지정해 주자.

fig, axs = plt.subplots(2)

axs[0].scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1)

axs[1].hist(ns_book7['대출건수'], bins=100)
axs[1].set_yscale('log')

fig.show()
>>>


+figure 클래스 객체인 fig에 Axis 클래스 객체인 axs[0], axs[1]을 서브플롯으로 추가한다고 생각하자.

산점도와 히스토그램이 두 개의 그래프가 위아래로 나누어져 그려졌다. 그런데 피겨 크기의 기본값인 (6,4) 안에서 두 개의 서브플롯을 배치하기 때문에 각 그래프의 높이가 많이 줄어버렸다.

subplots() 함수도 피겨 크기를 지정할 수 있는 figsize 매개변수를 제공한다. 피겨 크기를 (6,8)로 지정하여 높이를 조절해보자. 또한 set_title() 메서드를 사용해서 각 그래프에 제목도 넣어보자.

fig, axs = plt.subplots(2, figsize=(6, 8))

axs[0].scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1)
axs[0].set_title('scatter plot')
# 'set_title' : 서브플롯의 제목을 넣는다.

axs[1].hist(ns_book7['대출건수'], bins=100)
axs[1].set_title('histogram')
axs[1].set_yscale('log')

fig.show()
>>>

y축이 훨씬 잘 보여서 그래프의 특징이 더 잘 들어난다!! 게다가 그래프 위에 제목이 있어 어떤 그래프를 그린 것인지 더 잘 알 수 있다.


서브플롯을 가로로 나란히 출력하기

서브플롯의 두 그래프를 가로로 날나히 놓으려면 어떻게 해야할까?? subplots() 함수에 행과 열을 지정하면 원하는 서브플롯 개수의 피겨를 만들 수 있다. 사실 subplots() 함수의 첫 번째 매개 변수는 서브플롯 행의 개수이고 두 번째 매개변수 열의 개수이다.
[297 그림삽입]
그래서 앞서 작성해 본 subplots(2)에서 2는 행을 의미한다. 두 번째 매개변수를 지정하지 않아 열에 기본값 1이 적용되엉 세로로 놓인 두 개의 서브플롯이 만들어진 것이다!

그럼 subplots(1,2)와 같이 써서 하나의 행에 두 개의 열을 가지 피겨를 만들어보자. set_title() 메서드로 각 서브플롯의 이름을 지정하고 set_xlabel() 메서드set_ylabel() 메서드를 사용해 두 서브플롯의 축 이름도 각각 지정해보자.

fig, axs = plt.subplots(1, 2, figsize=(10, 4))
# '(1, 2, figsize=(10, 4)' : 

axs[0].scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1)
axs[0].set_title('scatter plot')
axs[0].set_xlabel('number of books')
axs[0].set_ylabel('borrow count')

axs[1].hist(ns_book7['대출건수'], bins=100)
axs[1].set_title('histogram')
axs[1].set_yscale('log')
axs[1].set_xlabel('borrow count')
axs[1].set_ylabel('frequency')

fig.show()
>>>


가로로 나란히 놓였고, x축, y축 이름도 생겼다!!


정리

  • 피겨는 맷플롯립의 그래프 요소를 모두 담고 있는 최상위 객체. 맷플롯립으로 그래프를 그릴 때 자동으로 피겨가 생성되고, 그래프가 그려진 후 삭제된다. 명시적으로 피겨 객체를 만들면 다양한 옵션을 제어할 수 있다.
  • rcParams는 맷플롯립 그래프의 기본값을 관리하는 객체이다. 객체에 담긴 값만 출력하는 것뿐만 아니라 새로운 값으로 바꿀 수도 있다. 이후에 그려지는 모든 그래프에 바뀐 설정이 적용된다.
  • 은 그래프에서 데이터 좌표를 표현한다. 2차원 그래프는 2개의 축을 가지며 3차원 그래프는 3개의 축을 가진다. 맷플롯립에서는 Axis 클래스로 축 객체를 다룬다. 두 개 이상의 Axis 객체로 이루어진 Axes 객체는 그래프가 그려질 영역을 표현한다.
  • 마커는 그래프에 데이터 포인트를 표시하는 방법이다. 맷플롯립의 기본 마커는 동그라미를 나타내는 'o'이다. rcParams 객체나 scatter() 함수의 marker 매개변수로 마커를 바꿀 수 있다.
  • 서브플롯은 피겨 안에 포함된 그래프 영역이다. 보통 Axes 객체를 일컫는다. subplots() 함수로 여러 개의 서브플롯과 서브플롯을 포함하는 피겨를 만들 수 있다.

핵심 함수와 메서드

  • Matplotlib.pyplot.figure() : 피겨 객체를 만들어 변환한다.
  • Matplotlib.pyplot.subplot() : 피겨와 서브플롯을 생성하여 반환한다.
  • Axes.set_xscale() : 서브플롯의 x축 스케일을 지정한다.
  • Axes.set_yscale() : 서브플롯의 y축 스케일을 지정한다.
  • Axes.set_title() : 서브플롯의 제목을 지정한다.
  • Axes.set_xlabel() : 서브플롯의 x축 이름을 지정한다.
  • Axes.set_ylabel() : 서브플롯의 y축 이름을 지정한다.
profile
초보 중의 초보. 열심히 하고자 하는 햄스터!

0개의 댓글