05-1 맷플롯립 기본 요소 알아보기
Figure 객체
Figure(피겨): 모든 그래프 구성 요소를 담고 있는 최상위 객체
→ scatter() 함수로 산점도를 그릴 때 자동으로 피겨 객체가 생성
지난 실습 데이터 ns_book7.csv 파일 다운
import gdown
gdown.download('https://bit.ly/3pK7iuu', 'ns_book7.csv', quiet=False)
판다스를 임포트하여 판다스 데이터프레임으로 불러오고, head() 메서드로 상위 5개 행 출력
import pandas as pd
ns_book7 = pd.read_csv('ns_book7.csv', low_memory=False)
ns_book7.head()
맷플롯립을 임포트한 후 투명도를 0.1로 지정하고 scatter() 함수로 '도서권수' 열을 x축, '대출건수'열을 y축으로 그리기
import matplotlib.pyplot as plt
plt.scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1)
plt.show()
- 그래프 크기 바꾸기: figsize 매개변수
figsize 매개변수에 그래프의 크기를 튜플로 지정할 수 있다.
→ 기본 그래프 크기는 (6, 4)이고 각각 너비와 높이에 해당
figsize 매개변수를 (9, 6)으로 지정하여 산점도 크게 그리기
plt.figure(figsize=(9, 6))
plt.scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1)
plt.show()
- 그래프 실제 크기 확인하기
DPI(dot per inch): 1인치를 몇 개의 점(픽셀)으로 표현하는지 나타낸다.
→ DPI에 따라 화면에 그려지는 그래프 크기가 달라진다.
맷플롯립의 기본 DPI는 72이므로 다음처럼 두 픽셀 값을 72로 나누어 figsize 매개변수에 전달
plt.figure(figsize=(900/72, 600/72))
plt.scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1)
plt.show()
타이트 레이아웃: 그래프 주변에 공백을 최소화
→ 사용하지 않으려면 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()
원래대로 타이트한 레이아웃으로 되돌아가기
%config InlineBackend.print_figure_kwargs = {'bbox_inches': 'tight'}
- 그래프 크기 바꾸기: dpi 매개변수
DPI 기본값인 72에서 144로 두 배 늘리기
plt.figure(dpi=144)
plt.scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1)
plt.show()
*인치당 칙셀 수가 두 배로 늘어나기 때문에 그래프 안의 모든 구성 요소도 함께 커진다.
rcParams 객체
: 맷플롯립 그래프의 기본값을 관리하는 객체
- DPI 기본값 바꾸기
: 기본 그래프 해상도를 높이기 위해서
figure 객체의 DPI 기본값을 100으로 바꾸기
plt.rcParams['figure.dpi'] = 100
- 산점도 마커 모양 바꾸기
산점도 그래프 마커 기본값 확인하기: rcParams 객체 속성 scatter.marker로 지정
plt.rcParams['scatter.marker']
마커 별 모양으로 지정하기
plt.rcParams['scatter.marker'] = '*'
산점도가 별 모양으로 그려지는지 확인
plt.scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1)
plt.show()
기본값을 수정하는 대신 scatter() 함수의 marker 매개변수로 마커 모양 지정
→ rcParams 객체의 scatter.marker 속성에 지정된 기본값을 무시하고 매개변수에 지정된 값 사용
marker 매개변수를 '+'로 설정
plt.scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1, marker='+')
plt.show()
여러 개의 서브플롯 출력하기
: 하나의 피겨 객체 안에는 여러 개의 서브플롯을 담을 수 있다.
서브플롯: 맷플롯립의 Axes 클래스의 객체
*하나의 서브플롯은 두 개 이상의 축 포함
*일반적으로 2차원 그래프의 수평축을 x축, 수직축을 y축으로 부른다.
*레이블: 축의 이름을 나타낸다.
- 서브플롯 그리기: 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()
*subplots() 함수는 피겨 객체와 각 서브플롯을 나타내는 Axes 객체의 배열을 반환
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')
axs[1].hist(ns_book7['대출건수'], bins=100)
axs[1].set_title('histogram')
axs[1].set_yscale('log')
fig.show()
- 서브플롯을 가로로 나란히 출력하기
: subplots() 함수에 행과 열을 지정하면 원하는 서브플롯 개수의 피겨를 만들 수 있다.
subplots(1, 2)와 같이 써서 하나의 행에 두 개의 열을 가진 피겨 만들기
: set_title() 메서드로 각 서브플롯의 이름을 지정하고 set_xlabel() 메서드와 set_ylabel() 메서드를 사용해 두 서브플롯의 축 이름 지정
fig, axs = plt.subplots(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()
정리
함수/메서드 | 기능 |
matplotlib.pyplot.figure() | 피겨 객체를 만들어 반환한다. |
matplotlib.pyplot.subplots() | 피겨와 서브플롯을 생성하여 반환한다. |
Axes.set_xscale() | 서브플롯의 x축 스케일을 지정한다. |
Axes.set_yscale() | 서브플롯의 y축 스케일을 지정한다. |
Axes.set_title() | 서브플롯의 제목을 설정한다. |
Axes.set_xlabel() | 서브플롯의 x축 이름을 지정한다. |
Axes.set_ylabel() | 서브플롯의 y축 이름을 지정한다. |
05-2 선 그래프와 막대 그래프 그리기
선 그래프: 데이터 포인트 사이를 선으로 이은 그래프
막대 그래프: 데이터 포인트의 크기를 막대 높이로 나타내는 그래프
→ 한 축을 따라 어떤 데이터의 변화를 살펴보는데 용이하다.
연도별 발행 도서 개수 구하기
:ns_book7 데이터프레임에서 연도별 발행 도서 개수와 주제별 도서 개수 구하기
데이터 다시 다운
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()
value_counts() 메서드: 데이터프레임의 한 열에서 이 메서드를 호출하면 고유한 값의 등장 횟수를 계산
'발행년도'열에서 value_counts() 메서드를 호출하여 반환된 결과 출력
count_by_year = ns_book7['발행년도'].value_counts()
count_by_year
*반환된 count_by_year는 판다스의 시리즈 객체
*첫 번째 열이 인덱스이고 두 번째 열이 값에 해당
연도를 시간순으로 배치하기 위해 sort_index() 메서드를 사용하여 인덱스 순서대로 데이터 정렬
count_by_year = count_by_year.sort_index()
count_by_year
count_by_year 객체에서 index 속성이 2030년보다 작거나 같은 데이터만 뽑기
count_by_year = count_by_year[count_by_year.index <= 2030]
count_by_year
주제별 도서 개수 구하기
: '주제분류번호'열에는 도서관에서 책을 분류하는 기준인 십진분류 코드가 기입되어 있다
→ '주제분류번호'열의 첫 번째 문자를 기준으로 도서 카운트하면 주제별 도서 개수를 구할 수 있다.
'주제분류번호'의 첫 번째 문자만 선택할 수 있다면 value_counts() 메서드를 적용
→ 이 열에는 NaN이 포함되어 있으므로 값이 NaN이라면 -1을 반환하는 함수를 만들어 걸러내야 한다.
'주제분류번호'열의 값을 받아 첫 번째 문자를 반환하는 kdc_1st_char() 함수를 선언한 후 apply() 메서드에 넣어 데이터프레임에 적용
import numpy as np
def kdc_1st_char(no):
if no is np.nan:
return '-1'
else:
return no[0]
count_by_subject = ns_book7['주제분류번호'].apply(kdc_1st_char).value_counts()
count_by_subject
선 그래프 그리기
: plot() 함수의 첫 번째 매개변수에는 x축의 값, 두 번째 매개변수에는 y축에 해당하는 값 전달
그래프 해상도를 높이기 위해 맷플롯립의 기본 DPI를 100으로 바꾸기
import matplotlib.pyplot as plt
plt.rcParams['figure.dpi'] = 100
plot() 함수의 두 매개변수에 count_by_year의 연도(index)와 도서 개수(values)을 각각 지정하여 선 그래프 그리기
: 서브플롯을 사용하지 않을 때는 그래프 제목은 title() 함수, x축 이름과 y축 이름은 각각 xlabel() 함수와 ylabel() 함수를 사용하여 지정
plt.plot(count_by_year.index, count_by_year.values)
plt.title('Books by year')
plt.xlabel('year')
plt.ylabel('number of books')
plt.show()
- 선 모양과 색상 바꾸기
: plot() 함수는 linestyle 매개변수를 제공
*linestyle 매개변수 기본값은 실선을 나타내는 '-'이다.
이외에도
- 실선 '-'
- 점선 ':'
- 쇄선 '-.'
- 파선 '--'
*또한 color 매개변수에 색상을 지정할 수 있다.
마커는 점으로, 선은 점선을 사용한 선 그래프를 빨간색으로 그리기
: 시리즈 객체 그대로 plot() 함수에 전달 → 자동으로 인덱스를 x축의 좌표로 사용하여 그래프를 그린다.
plt.plot(count_by_year, marker='.', linestyle=':', color='red')
plt.title('Books by year')
plt.xlabel('year')
plt.ylabel('number of books')
plt.show()
*plot() 함수의 매개변수에 지정한 마커, 선 모양, 색깔을 하나의 문자열로 합쳐서 선 그래프의 포맷으로 나타낼 수 있다.
ply.plot(count_by_year, '.:r')
별 모양 마커와 실선을 사용한 선 그래프를 녹색으로 그리기
plt.plot(count_by_year, '*-g')
plt.title('Books by year')
plt.xlabel('year')
plt.ylabel('number of books')
plt.show()
- 선 그래프 눈금 개수 조절 및 마커에 텍스트 표시하기
xticks() 함수: x축 눈금 지정
1947년부터 2030년까지 10년씩 건너뛰면서 x축의 눈금을 표시하기 위해 xticks() 함수 매개변수에 파이썬 range() 함수 사용
→ 슬라이스 연산자(:)를 사용해 5개씩 건너뛰면서 count_by_year의 값을 선택
*items() 메서드를 사용하면 인덱스와 값을 감싼 튜플을 얻을 수 있다.
annotate() 함수: 그래프에 값 표시
첫 번째 매개변수에 그래프에 나타낼 문자열을 지정하고, 두 번째 매개변수에 문자열이 나타날 x, y 좌표를 튜플로 지정
plt.plot(count_by_year, '*-g')
plt.title('Books by year')
plt.xlabel('year')
plt.ylabel('number of books')
plt.xticks(range(1947, 2030, 10))
for idx, val in count_by_year[::5].items():
plt.annotate(val, (idx, val))
plt.show()
xtyest 매개변수: 텍스트 위치 조절
마커 위치에서 x축은 1만큼, y축은 10만큼 떨어지게 지정하기
plt.plot(count_by_year, '*-g')
plt.title('Books by year')
plt.xlabel('year')
plt.ylabel('number of books')
plt.xticks(range(1947, 2030, 10))
for idx, val in count_by_year[::5].items():
plt.annotate(val, (idx, val), xytext=(idx+1, val+10))
plt.show()
textcoords 매개변수: 상대적인 위치를 포인트나 픽셀 단위로 지정
→ textcoords 매개변수에 포이느 단위의 상대 위치를 나타내는 'offset points'를 지정
plt.plot(count_by_year, '*-g')
plt.title('Books by year')
plt.xlabel('year')
plt.ylabel('number of books')
plt.xticks(range(1947, 2030, 10))
for idx, val in count_by_year[::5].items():
plt.annotate(val, (idx, val), xytext=(2, 2), textcoords='offset points')
plt.show()
막대 그래프 그리기
: bar() 함수 사용
→ x축의 값과 막대 높이에 해당하는 y축의 값을 전달
annotate() 함수로 y축의 값을 표시할 때 텍스트 위치를 xytest=(0, 2)로 지정
plt.bar(count_by_subject.index, count_by_subject.values)
plt.title('Books by subject')
plt.xlabel('subject')
plt.ylabel('number of books')
for idx, val in count_by_subject.items():
plt.annotate(val, (idx, val), xytext=(0, 2), textcoords='offset points')
plt.show()
- 텍스트 정렬, 막대 조절 및 색상 바꾸기
텍스트 위치 조절: annotate() 함수의 ha 매개변수레 'center' 지정
택스트 크기 조절: fontsize 매개변수
텍스트 색깔: color 매개변수
막대 두께 조절: width 매개변수 (기본값 0.8)
plt.bar(count_by_subject.index, count_by_subject.values, width=0.7, color='blue')
plt.title('Books by subject')
plt.xlabel('subject')
plt.ylabel('number of books')
for idx, val in count_by_subject.items():
plt.annotate(val, (idx, val), xytext=(0, 2), textcoords='offset points',
fontsize=8, ha='center', color='green')
plt.show()
- 가로 막대 그래프 그리기
: barh() 함수
막대 두께 나타내는 매개변수: height 매개변수
*x축과 y축의 이름 바꿔서 써야한다.
plt.barh(count_by_subject.index, count_by_subject.values, height=0.7, color='blue')
plt.title('Books by subject')
plt.xlabel('number of books')
plt.ylabel('subject')
for idx, val in count_by_subject.items():
plt.annotate(val, (val, idx), xytext=(2, 0), textcoords='offset points',
fontsize=8, va='center', color='green')
plt.show()
*가로 막대 그래프에서는 텍스트를 막대 중앙에 정렬할 때 va 매개변수 사용
*기본 값은 'baseline'으로 텍스트 밑면을 막대 중앙에 맞춘다.
*위로 정렬하는 'top'과 아래로 정렬하는 'bottom'
이미지 출력하고 저장하기
# 노트북이 코랩에서 실행 중인지 체크합니다.
import sys
if 'google.colab' in sys.modules:
# 샘플 이미지를 다운로드합니다.
!wget https://bit.ly/3wrj4xf -O jupiter.png
- 이미지 읽기
: imread() 함수 → 파일 이름을 전달하면 이미지를 읽어 넘파이 배얼을 반환해준다.
img = plt.imread('jupiter.png')
img.shape
*반환된 배열의 크기 (이미지 높이, 너비, 채널) 의미
- 이미지 화면에 출력하기
: imshow() 함수
plt.imshow(img)
plt.show()
*imshow() 함수는 피겨 크기에 상관없이 기본적으로 원본 이미지의 가로세로 비율 유지
축과 눈금을 표시하지 않으려면 axis() 함수를 'off'로 지정
plt.figure(figsize=(8, 6))
plt.imshow(img)
plt.axis('off')
plt.show()
- 이미지 저장하기
: imsave() 함수 사용
*첫 번째 매개변수는 저장할 파일이름이고, 두 번째 매개변수는 이미지가 저장된 넘파이 배열
*파일 이름의 확장자를 사용해 자동으로 이미지를 변환해준다.
plt.imsave('jupiter.jpg', arr_img)
그래프를 이미지로 저장하기
: savefig() 함수 사용
*첫 번째 매개변수는 저장할 이미지의 파일 이름
*dpi 매개변수에는 그래프를 저장할 때 사용할 DPI를 따로 지정할 수 있다.
*rcParam['savefig.dpi']로 DPI를 지정할 수 있다.
*기본값은 'figure'로 피겨에서 설정한 DPI를 따른다.
plt.rcParams['savefig.dpi']
마지막에 그린 가로 막대 그래프를 savefig() 함수로 저장하기
*show() 함수가 호출되면 피겨 객체가 자동으로 소멸되므로 show() 함수 이전에 savefig() 를 호출해야 한다.
plt.barh(count_by_subject.index, count_by_subject.values, height=0.7, color='blue')
plt.title('Books by subject')
plt.xlabel('number of books')
plt.ylabel('subject')
for idx, val in count_by_subject.items():
plt.annotate(val, (val, idx), xytext=(2, 0), textcoords='offset points',
fontsize=8, va='center', color='green')
plt.savefig('books_by_subject.png')
plt.show()
저장된 파일 불러서 다시 출력
pil_img = Image.open('books_by_subject.png')
plt.figure(figsize=(8, 6))
plt.imshow(pil_img)
plt.axis('off')
plt.show()
정리
함수/메서드 | 기능 |
matplotlib.pyplot.plot() | 선 그래프를 그린다. |
matplotlib.pyplot.title() | 그래프 제목을 설정한다. |
matplotlib.pyplot.xlabel() | x축 이름을 지정한다. |
matplotlib.pyplot.ylabel() | y축 이름을 지정한다. |
matplotlib.pyplot.xticks() | x축의 눈금 위치와 레이블을 지정한다. |
matplotlib.pyplot.annotate() | 지정한 좌표에 텍스트를 출력한다. |
matplotlib.pyplot.bar() | 세로 막대 그래프를 그린다. |
matplotlib.pyplot.barh() | 가로 막대 그래프를 그린다. |
matplotlib.pyplot.imread() | 이미지 파일을 넘파이 배열로 읽어들인다. |
matplotlib.pyplot.imshow() | 이미지를 출력한다. |
matplotlib.pyplot.imsave() | 넘파이 배열을 이미지 파일로 저장한다. |
matplotlib.pyplot.savefig() | 그래프를 이미지로 저장한다. |
'혼자 공부하는 데이터 분석' 카테고리의 다른 글
7장 검증하고 예측하기 (0) | 2023.06.11 |
---|---|
6장 복잡한 데이터 표현하기 (0) | 2023.06.08 |
4장 데이터 요약하기 (0) | 2023.05.29 |
3장 데이터 정제하기 (0) | 2023.05.22 |
2장 데이터 수집하기 (0) | 2023.05.14 |
댓글