컴퓨터와 책과 연필
블로그 프사

컴퓨터와 책과 연필

Kim Evergood

허접 개발자의 개인 블로그😘 문서화된 작업은 나의 얼굴. 문서화된 공부는 맞춤 교재.

게시글 썸네일

matplotlib.pyplot 기초 사용 정리

2025. 11. 18. Kim Evergood이가 씀.
import matplotlib.pyplot as plt

# 예시데이터용
import numpy as np
import pandas as pd

plt, Figure, Axes 대충 개괄

  • matplotlib.pyplot: 상태를 가진 전역 인터페이스이다. 관습적 줄임말: plt. 유래에 따라 MATLAB같은 인터페이스를 갖고 있다.
  • Figure: 도화지. Axes의 컨테이너이다. 관습적 변수이름: fig.
  • Axes: 개별 그림(사람이 ‘그래프 한 개’라 인식하는 것). 관습적 변수이름: ax.

그래프 한 개 그리기

정석적으로; 다음과 같이 그린다.

# 예시 데이터
x = [10, 20, 30, 40, 50] # np.ndarray, pd.Series 등도 됨.
y = [1, 5, 12, 25, 30]
fig, ax = plt.subplots()  # plt에서 fig, ax 개체를 얻는다.(Axes 한 개짜리 Figure)
ax.plot(x, y)             # ax에 그래프를 그린다.

plt.show()  #※ 주피터 노트북에서는 이를 생략해도; 그려지지 않은 활성 Figure를 자동으로 그림.
fig = plt.figure()     # plt에서 fig 개체를 얻는다.(Axes가 없는 빈 Figure)
ax = fig.add_subplot() # fig에 ax를 추가한다.
ax.plot(x, y)          # ax에 그래프를 그린다.

plt.show()

직접적으로 그림이 그려지는 곳은 Axes이다. 그러니까 그리기 함수들은 Axes의 함수이다. 그러나 편의상 대충 하나만 그려보기 편하게 plt에도 같은 함수들이 제공된다. 자동으로 현재 활성화된 Figure/Axes에 그것을 그린다.

plt.plot(x, y)
plt.show()

여러 그래프 그리기

격자

Figure 하나에 Axes 여럿을 포함한다.

# subplots에 격자 크기 인자 넣기
x = np.linspace(0, 10, 100)

fig, axs = plt.subplots(2, 2)  # 2x2 Axes의 격자가 있는 Figure

axs[0, 0].plot(x, np.sin(x))  # axs[r, c] 또는 axs[r][c]
axs[0, 1].plot(x, np.cos(x))
axs[1, 0].plot(x, x**2)
axs[1, 1].plot(x, np.exp(x))

plt.tight_layout()  # 그래프끼리 겹치므로 조정

plt.show()

# 한 줄이면 axs도 1차원임.
fig, axs = plt.subplots(1, 2)
axs.shape # (2, 1)이 아니라 (2, )이다.

axs[0].plot(x, y)
axs[1].plot(x, y)

plt.show()
# 빈 Figure에 여러 subplot 넣기.
fig = plt.figure()  # 빈 Figure
axs = []            # ax를 생성하며 여기에 넣어모으겠다.

# 3x5 격자에 ax를 채운다.
for i in range(15):
    ax = fig.add_subplot(3, 5, i+1)
    axs.append(ax)

docs - tight_layout

겹쳐그리기

그냥 한 ax에 그래프그리기 함수를 여러 번 호출한다.

fig, ax = plt.subplots()

ax.plot([1,2,3,5])
ax.plot([4,5,2,1])

plt.show()

대표적인 도표

plot: 선그래프

# 예시 데이터
x = [10, 20, 30, 40, 50]
y = [1, 5, 12, 25, 30]
plt.plot(y)  # 값을 배열 하나만 줌: 기본적으로 y로 해석하고 x=1,2,3,...로 취급됨.
plt.plot(x, y)  # (x, y)의 목록이 아니라 길이가 같은 x의 목록과 y의 목록을 줘야 한다.
plt.plot(x, y, 'bo')# 파란 점으로 그리기
              #'r+' : 빨간 십자로 그리기
              #'g-' : 녹색 선으로 그리기

docs

bar: 막대그래프

df = pd.DataFrame({
    '이름': ['김영', '민들레', '케이', '하하'],
    '성별': ['여자', '여자', '남자', '남자'],
    '점수': [10, 5, 3, 9],
})

성별별점수평균 = df.groupby(['성별'])['점수'].mean()
plt.bar(
    성별별점수평균.index,
    성별별점수평균
)

hist: 히스토그램

x = [1,0,5,4,4,3,5,7,9,8,4,5,6,6,5]

fig, axs = plt.subplots(1, 2, figsize=(5,2))

axs[0].hist(
    x,
    bins=5,           # 각 bin은 n등분된 영역
#   bins=[0,4,5,6,9], # 각 bin의 경계 값
)

axs[1].hist(
    x,
    bins=5,
    range=(0, 15) # 이 범위를 n등분. bins가 배열이면 효과 X
#   range=None    # 자동. x의 최소, 최대
)

plt.show()

docs

scatter: 산점도

x = [2,1,4,5,3,2,9,7,2,4,9,4,5,8,9,7]
y = [8,7,5,4,6,8,2,4,5,6,7,2,1,5,3,4] # 둘의 길이 같아야 함.

plt.scatter(x, y)
plt.scatter(
    x,
    y,
    s=10, # 점의 크기
    color='#f0f' # 빛깔
)

docs

boxplot: 상자수염

plt.boxplot(
    df['수학점수']
)
plt.boxplot(
    df[['수학점수', '영어점수', '과학점수']]
)
plt.xticks([1, 2, 3], ['수학', '영어', '과학'])

imshow: 히트맵, 이미지

# 랜덤값 표시
img = np.random.rand(10, 12)

plt.imshow(img)
# MNIST 이미지 표시
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

fig, axs = plt.subplots(4, 6)

for i in range(4):
    for j in range(6):
        axs[i, j].imshow(train_images[i*6+j])
        axs[i, j].set_title(train_labels[i*6+j])
        axs[i, j].set_axis_off()

plt.tight_layout()

plt.show()

크기

fig, axs = plt.subplots(
    2,
    3,
    figsize=(6, 3)  # figure의 크기 설정
)

제목

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

x = np.linspace(0, 10, 100)

axs[0].plot(x, np.sin(x))
axs[0].set_title("사인")     # ax의 제목

axs[1].plot(x, np.exp(x))
axs[1].set_title("지수함수") # ax의 제목

fig.suptitle("여러 가지 함수", fontsize=16)  # figure 제목

plt.tight_layout()

plt.show()

축 삭제

# plt에서
plt.imshow(image)
plt.axis('off')
# ax에서
fig, axs = plt.subplots(1, 2)

axs[0].imshow(images[0])
axs[1].imshow(images[1])
axs[0].set_axis_off()
axs[1].set_axis_off()

딱지

# plt 하나

x = [10, 20, 30, 40, 50]
y = [1, 5, 12, 25, 30]

plt.plot(x, y)

plt.title('제목 123')
plt.xlabel('x축 딱지')  # 축에 딱지 붙이기
plt.ylabel('y축 딱지')  # 축에 딱지 붙이기

plt.show()

스타일

print(plt.style.available)# 가용 스타일 목록

plt.style.use('ggplot')
plt.style.use('seaborn-v0_8')

왠지 스타일을 바꿀 때마다 폰트를 다시 설정해줘야 한다.

Tips

한글 폰트 설정
# 나눔고딕으로 설정
plt.rcParams['font.family'] ='NanumGothic'
plt.rcParams['axes.unicode_minus'] = False

자세히: 한글 나오게 폰트 설정

눈금이 너무 많음
x = [f'{x_str}' for x_str in np.arange(100)]  # x의 각 항목은 의미상 수를 나타내지만 데이터타입은 문자열이다.
y = np.arange(100)

fig, ax = plt.subplots(1, 2, figsize=(6, 2))

ax[0].plot(x, y)  # 문자열이므로 카테고리로 취급되어 축에 모든 x가 다 그려진다.

ax[1].plot(np.asarray(x, int), y)  # x를 float, int 등 수로 바꾸면 plt에서 눈금을 자동 조절한다.

plt.show()

참고

matplotlib 로고

쓸데는 없지만…. #

fig, ax = make_logo(height_px=550, lw_bars=3.5, lw_grid=2.5, lw_border=5,
          rgrid=[1, 3, 5, 7])
fig.savefig("matplotlib-logo.png", dpi=100, bbox_inches='tight', pad_inches=0.2)
728x90

카테고리 다른 글