Matplotlib 基础教程 – wiki基地

Matplotlib 기초 튜토리얼

데이터 시각화는 데이터를 이해하고 분석 결과를 효과적으로 전달하는 데 필수적인 과정입니다. Python 생태계에서 Matplotlib는 가장 널리 사용되는 데이터 시각화 라이브러리 중 하나입니다. 유연하고 강력하며 다양한 종류의 그래프를 그릴 수 있는 기능을 제공합니다. 이 튜토리얼에서는 Matplotlib의 기본 개념부터 시작하여 간단한 그래프를 그리고 사용자 정의하는 방법까지 자세히 살펴보겠습니다.

1. Matplotlib란 무엇인가?

Matplotlib는 Python에서 정적, 애니메이션 및 대화형 시각화를 만들기 위한 포괄적인 라이브러리입니다. NumPy와 SciPy 같은 과학 계산 라이브러리와 잘 통합되어 있으며, 다양한 운영 체제와 그래픽 백엔드를 지원합니다.

Matplotlib는 크게 두 가지 인터페이스 스타일을 제공합니다.

  1. pyplot 인터페이스: MATLAB과 유사한 상태 기반의 인터페이스입니다. 간단한 플롯을 빠르게 생성할 때 편리하지만, 여러 개의 플롯을 관리하거나 복잡한 레이아웃을 다룰 때는 코드가 장황해질 수 있습니다. matplotlib.pyplot 모듈을 사용하여 plt라는 별칭으로 임포트하는 것이 관례입니다.
  2. 객체 지향(Object-Oriented, OO) 인터페이스: Matplotlib의 핵심 기능을 나타내는 FigureAxes 객체를 직접 다루는 방식입니다. 초기에는 조금 더 복잡해 보일 수 있지만, 그래프의 각 요소를 세밀하게 제어하고 복잡한 레이아웃을 구성할 때 훨씬 유용하며 코드의 가독성과 유지보수성을 높여줍니다.

이 튜토리얼에서는 두 가지 인터페이스를 모두 소개하지만, 특히 복잡한 그래프나 여러 개의 그래프를 다룰 때는 객체 지향 인터페이스를 사용하는 것이 권장됩니다.

2. 설치

Matplotlib는 파이썬 패키지 관리자인 pip 또는 Anaconda를 통해 쉽게 설치할 수 있습니다.

pip 사용 시:

bash
pip install matplotlib

Anaconda 사용 시:

bash
conda install matplotlib

3. Matplotlib 임포트하기

Matplotlib를 사용하기 위해서는 일반적으로 matplotlib.pyplot 모듈을 임포트합니다. 관례적으로 plt라는 별칭을 사용합니다.

python
import matplotlib.pyplot as plt
import numpy as np # 그래프 예제를 위해 numpy도 임포트합니다.

4. 기본 개념: Figure와 Axes

Matplotlib의 객체 지향 인터페이스를 이해하는 데 가장 중요한 두 가지 기본 구성 요소는 FigureAxes입니다.

  • Figure: 전체 창 또는 페이지를 나타냅니다. 이 Figure 안에 하나 이상의 Axes 객체가 포함될 수 있습니다. 제목, 전체 크기 등을 설정할 수 있습니다.
  • Axes: 실제 데이터를 표시하는 개별 플롯 영역입니다. Figure 객체 안에 위치하며, x축, y축, 데이터 플롯, 제목, 레이블, 범례 등 그래프의 대부분 요소가 Axes 객체에 속합니다. 혼동하기 쉽지만, 복수형인 ‘Axes’가 단일 플롯 영역을 의미합니다. (‘Axis’는 축 하나를 의미합니다.)

객체 지향 방식으로 그래프를 시작할 때 가장 흔하게 사용하는 함수는 plt.subplots()입니다. 이 함수는 Figure 객체와 하나 이상의 Axes 객체를 반환합니다.

python
fig, ax = plt.subplots() # 하나의 Figure와 하나의 Axes를 생성합니다.

만약 여러 개의 서브플롯을 만들고 싶다면 plt.subplots(nrows, ncols) 형태로 호출할 수 있으며, 이 경우 axAxes 객체의 NumPy 배열이 됩니다.

“`python
fig, axes = plt.subplots(nrows=2, ncols=2) # 2×2 그리드의 Axes 객체를 생성합니다.

axes는 axes[0, 0], axes[0, 1], axes[1, 0], axes[1, 1]로 접근 가능한 2차원 배열입니다.

“`

5. 첫 번째 그래프 그리기 (pyplot 인터페이스)

가장 간단하게 선 그래프를 그려보겠습니다. pyplot 인터페이스를 사용하면 몇 줄의 코드로 빠르게 결과를 확인할 수 있습니다.

“`python

데이터 생성

x = np.array([1, 2, 3, 4, 5])
y = np.array([2, 4, 6, 8, 10])

선 그래프 그리기

plt.plot(x, y)

그래프 보여주기

plt.show()
“`

이 코드는 xy 데이터를 사용하여 선 그래프를 그립니다. plt.plot() 함수는 기본적으로 선 그래프를 그리며, 다양한 옵션을 통해 선의 스타일, 색상, 마커 등을 지정할 수 있습니다. plt.show() 함수는 생성된 그래프를 화면에 표시합니다. 주피터 노트북이나 IPython 환경에서는 마지막 plt.show() 호출 없이도 그래프가 자동으로 표시되는 경우가 많습니다.

6. 첫 번째 그래프 그리기 (객체 지향 인터페이스)

동일한 그래프를 객체 지향 인터페이스로 그려보겠습니다.

“`python

데이터 생성

x = np.array([1, 2, 3, 4, 5])
y = np.array([2, 4, 6, 8, 10])

Figure와 Axes 객체 생성

fig, ax = plt.subplots()

Axes 객체에 선 그래프 그리기

ax.plot(x, y)

그래프 보여주기

plt.show()
“`

plt.subplots()figax를 얻은 후, ax.plot() 메서드를 사용하여 데이터를 그립니다. 이후 그래프에 대한 모든 설정(제목, 레이블, 눈금 등)은 ax 객체의 메서드를 호출하여 수행하게 됩니다.

7. 라인 스타일, 색상, 마커 설정

plot() 함수는 선의 모양을 다양하게 설정할 수 있는 매개변수를 제공합니다.

  • color: 선의 색상 (‘red’, ‘blue’, ‘green’, ‘#FF5733’ 등)
  • linestyle: 선의 스타일 (‘-‘, ‘–‘, ‘-.’, ‘:’)
  • marker: 데이터 포인트에 표시할 마커 스타일 (‘o’, ‘s’, ‘^’, ‘*’)
  • linewidth: 선의 두께
  • markersize: 마커의 크기

pyplot 또는 객체 지향 인터페이스 모두 동일한 매개변수를 사용합니다.

“`python
x = np.linspace(0, 10, 100) # 0부터 10까지 100개의 균등 간격 데이터 생성
y1 = np.sin(x)
y2 = np.cos(x)

fig, ax = plt.subplots()

다양한 스타일 적용

ax.plot(x, y1, color=’blue’, linestyle=’-‘, label=’sin(x)’)
ax.plot(x, y2, color=’red’, linestyle=’–‘, marker=’o’, markersize=5, label=’cos(x)’)

plt.show()
“`

plot() 함수의 세 번째 매개변수로 포맷 문자열을 사용하여 색상, 마커, 선 스타일을 짧게 지정할 수도 있습니다. 예: 'r--o'는 ‘빨간색(–) 선에 o 마커’를 의미합니다.

python
fig, ax = plt.subplots()
ax.plot(x, y1, 'b-', label='sin(x)') # 파란색 실선
ax.plot(x, y2, 'ro--', label='cos(x)') # 빨간색 점선에 원 마커
plt.show()

8. 산점도 그리기

데이터 포인트의 분포를 확인하기 위해 산점도를 그릴 수 있습니다. plt.scatter() 또는 ax.scatter() 함수를 사용합니다.

“`python

무작위 데이터 생성

np.random.seed(0)
x = np.random.rand(50)
y = np.random.rand(50)
colors = np.random.rand(50) # 색상 값을 위한 데이터
sizes = 1000 * np.random.rand(50) # 크기 값을 위한 데이터

fig, ax = plt.subplots()

산점도 그리기

scatter = ax.scatter(x, y, c=colors, s=sizes, alpha=0.7, cmap=’viridis’) # c: 색상, s: 크기, alpha: 투명도, cmap: 컬러맵

컬러바 추가 (산점도에 사용된 색상 데이터의 의미를 설명)

fig.colorbar(scatter, ax=ax, label=’Color Value’)

plt.show()
“`

scatter() 함수는 c 매개변수로 각 점의 색상을, s 매개변수로 각 점의 크기를 지정할 수 있습니다. alpha는 투명도를 조절합니다. cmap은 색상 값을 어떤 컬러맵으로 표현할지 지정합니다.

9. 제목, 축 레이블, 범례 추가

그래프를 명확하게 이해하기 위해서는 제목, 축 레이블, 범례가 필수적입니다.

  • 제목: plt.title() 또는 ax.set_title()
  • x축 레이블: plt.xlabel() 또는 ax.set_xlabel()
  • y축 레이블: plt.ylabel() 또는 ax.set_ylabel()
  • 범례: plt.legend() 또는 ax.legend() (각 plot() 또는 scatter() 호출 시 label 매개변수를 지정해야 합니다.)

“`python
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

fig, ax = plt.subplots()

ax.plot(x, y1, label=’sin(x)’)
ax.plot(x, y2, label=’cos(x)’)

제목, 축 레이블 추가

ax.set_title(‘Sine and Cosine Functions’)
ax.set_xlabel(‘X-axis’)
ax.set_ylabel(‘Y-axis’)

범례 추가

ax.legend()

plt.show()
“`

10. 축 범위 및 눈금 설정

그래프의 특정 영역을 확대하거나 축의 최소/최대 값을 설정하려면 축 범위를 조절해야 합니다. 또한, 축 눈금의 위치나 레이블을 사용자 정의할 수 있습니다.

  • 축 범위 설정: plt.xlim(), plt.ylim() 또는 ax.set_xlim(), ax.set_ylim()
  • 축 눈금 설정: plt.xticks(), plt.yticks() 또는 ax.set_xticks(), ax.set_yticks()
  • 축 스케일 변경 (선형, 로그 등): plt.xscale(), plt.yscale() 또는 ax.set_xscale(), ax.set_yscale()

“`python
x = np.linspace(0, 10, 100)
y = np.sin(x)

fig, ax = plt.subplots()

ax.plot(x, y)

y축 범위를 -1.5에서 1.5로 설정

ax.set_ylim(-1.5, 1.5)

x축 눈금을 특정 위치에 설정 (0, pi, 2*pi, …)

ax.set_xticks(np.arange(0, 11, 2)) # 0부터 10까지 2 간격으로 눈금 설정

x축 눈금 레이블을 문자열로 설정

ax.set_xticklabels([‘0’, ‘2’, ‘4’, ‘6’, ‘8’, ’10’]) # 위 set_xticks와 함께 사용

ax.set_title(‘Sine Function with Adjusted Y-limit and X-ticks’)
ax.set_xlabel(‘X’)
ax.set_ylabel(‘sin(X)’)

plt.show()
“`

11. 여러 개의 서브플롯 생성

하나의 Figure 안에 여러 개의 그래프를 나란히 표시하고 싶을 때 서브플롯 기능을 사용합니다.

plt.subplot() 사용 (pyplot 인터페이스):

plt.subplot(nrows, ncols, index) 형태로 사용합니다. index는 1부터 시작하며, 그래프가 그려질 서브플롯의 위치를 지정합니다 (왼쪽 위부터 오른쪽으로 순서대로 번호가 매겨집니다).

“`python

데이터 생성

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.tan(x)
y4 = x**2

2×2 그리드 생성

plt.figure() # 새로운 Figure 생성 (필수는 아니지만 명시적으로)

plt.subplot(2, 2, 1) # 왼쪽 위
plt.plot(x, y1)
plt.title(‘sin(x)’)

plt.subplot(2, 2, 2) # 오른쪽 위
plt.plot(x, y2, ‘r–‘)
plt.title(‘cos(x)’)

plt.subplot(2, 2, 3) # 왼쪽 아래
plt.plot(x, y3, ‘g.-‘)
plt.title(‘tan(x)’)
plt.ylim(-5, 5) # tan 함수는 범위 제한 필요

plt.subplot(2, 2, 4) # 오른쪽 아래
plt.plot(x, y4, ‘k:’)
plt.title(‘x^2’)

plt.tight_layout() # 서브플롯 간 간격 자동 조절
plt.show()
“`

이 방식은 각 서브플롯을 그릴 때마다 plt.subplot()을 호출하여 현재 활성 상태인 Axes를 변경하는 방식입니다.

plt.subplots() 사용 (객체 지향 인터페이스):

plt.subplots(nrows, ncols)를 사용하여 Figure와 Axes 객체의 배열을 얻는 방식입니다. 이 방식이 더 유연하고 객체를 직접 다루기 때문에 복잡한 서브플롯 관리에 유리합니다.

“`python

데이터는 위와 동일

2×2 그리드 Axes 생성

fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(8, 6)) # Figure 크기 지정 가능

axes는 2차원 NumPy 배열이므로 인덱싱으로 접근

axes[0, 0].plot(x, y1)
axes[0, 0].set_title(‘sin(x)’)

axes[0, 1].plot(x, y2, ‘r–‘)
axes[0, 1].set_title(‘cos(x)’)

axes[1, 0].plot(x, y3, ‘g.-‘)
axes[1, 0].set_title(‘tan(x)’)
axes[1, 0].set_ylim(-5, 5)

axes[1, 1].plot(x, y4, ‘k:’)
axes[1, 1].set_title(‘x^2’)

plt.tight_layout()
plt.show()
“`

이 방식은 각 Axes 객체(axes[i, j])의 메서드를 호출하여 해당 서브플롯에 그림을 그립니다. axes가 1차원 배열이 되는 경우(plt.subplots(1, 2) 또는 plt.subplots(2, 1)), 인덱싱은 axes[0], axes[1] 등으로 이루어집니다. 하나의 서브플롯만 만들 경우(plt.subplots()), ax는 단일 Axes 객체이므로 ax.plot()와 같이 사용합니다.

12. 그래프 저장하기

생성한 그래프를 파일로 저장하려면 plt.savefig() 함수를 사용합니다.

“`python
x = np.array([1, 2, 3, 4, 5])
y = np.array([2, 4, 6, 8, 10])

fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_title(“Sample Plot”)

현재 Figure를 파일로 저장

plt.savefig(‘sample_plot.png’) # PNG 형식으로 저장

plt.savefig(‘sample_plot.pdf’) # PDF 형식으로 저장

plt.savefig(‘sample_plot.jpg’, dpi=300) # JPG 형식, 해상도 300dpi로 저장

파일 저장 후에도 plt.show()를 호출하여 화면에 표시 가능

plt.show()
“`

savefig() 함수는 파일 경로와 이름을 첫 번째 인자로 받습니다. 파일 확장자에 따라 형식이 결정됩니다 (png, jpg, pdf, svg 등). dpi 매개변수를 사용하여 해상도를 조절할 수 있으며, bbox_inches='tight'를 사용하면 그래프 주변의 여백을 최소화하여 저장할 수 있습니다.

13. 다양한 그래프 유형 (간단 소개)

Matplotlib는 선 그래프와 산점도 외에도 다양한 종류의 그래프를 지원합니다. 몇 가지 기본적인 그래프 유형을 소개합니다.

  • 막대 그래프 (Bar Plot): 범주형 데이터의 빈도나 값을 비교할 때 사용합니다. plt.bar() 또는 ax.bar().

    python
    categories = ['A', 'B', 'C', 'D']
    values = [23, 45, 56, 12]
    fig, ax = plt.subplots()
    ax.bar(categories, values)
    ax.set_title('Bar Chart Example')
    plt.show()

  • 히스토그램 (Histogram): 연속형 데이터의 분포를 보여줄 때 사용합니다. plt.hist() 또는 ax.hist().

    python
    data = np.random.randn(1000) # 표준 정규 분포 데이터 1000개
    fig, ax = plt.subplots()
    ax.hist(data, bins=30) # 데이터를 30개의 구간으로 나누어 빈도 계산
    ax.set_title('Histogram Example')
    ax.set_xlabel('Value')
    ax.set_ylabel('Frequency')
    plt.show()

  • 파이 차트 (Pie Chart): 전체에 대한 각 범주의 비율을 보여줄 때 사용합니다. plt.pie() 또는 ax.pie().

    python
    sizes = [15, 30, 45, 10]
    labels = ['A', 'B', 'C', 'D']
    fig, ax = plt.subplots()
    ax.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=90)
    ax.set_title('Pie Chart Example')
    plt.show()

14. 스타일 적용

Matplotlib는 미리 정의된 다양한 스타일을 제공하여 그래프의 전체적인 모양을 쉽게 변경할 수 있습니다. plt.style.use() 함수를 사용합니다.

어떤 스타일이 있는지 확인하려면 plt.style.available 속성을 확인하세요.

python
print(plt.style.available)

몇 가지 스타일을 적용해 보겠습니다.

“`python
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

‘seaborn-v0_8-darkgrid’ 스타일 적용

plt.style.use(‘seaborn-v0_8-darkgrid’)

fig, ax = plt.subplots()
ax.plot(x, y1, label=’sin(x)’)
ax.plot(x, y2, label=’cos(x)’)
ax.set_title(‘Styled Plot (seaborn-darkgrid)’)
ax.legend()

plt.show()

스타일 재설정 또는 다른 스타일 적용 가능

plt.style.use(‘default’) # 기본 스타일로 돌아가기

fig, ax = plt.subplots()
ax.plot(x, y1, label=’sin(x)’)
ax.plot(x, y2, label=’cos(x)’)
ax.set_title(‘Styled Plot (default)’)
ax.legend()

plt.show()
“`

스타일을 사용하면 최소한의 코드로도 미적으로 개선된 그래프를 얻을 수 있습니다.

15. Figure와 Axes 객체 활용의 장점

튜토리얼 전반에 걸쳐 객체 지향(fig, ax = plt.subplots()) 방식을 사용하는 것이 더 좋다고 언급했습니다. 그 이유는 다음과 같습니다.

  • 명확성: 어떤 객체(Figure 또는 특정 Axes)에 작업을 수행하는지 코드를 통해 명확하게 알 수 있습니다. 이는 특히 서브플롯이 많거나 복잡한 레이아웃을 다룰 때 중요합니다.
  • 유연성: Axes 객체는 그래프의 모든 요소를 제어하는 다양한 메서드를 가지고 있습니다. 이 메서드들은 Figure 객체나 다른 Axes 객체의 상태에 영향을 받지 않고 해당 Axes에만 독립적으로 적용됩니다.
  • 프로그래밍 용이성: 여러 개의 Axes 객체를 배열 형태로 관리할 수 있으므로 반복문 등을 사용하여 여러 서브플롯에 동일한 작업을 적용하기 편리합니다.
  • 재사용성: Figure나 Axes 객체를 변수에 저장하고 필요에 따라 다시 사용할 수 있습니다.

간단한 한두 개의 그래프를 빠르게 그릴 때는 pyplot 인터페이스가 편리할 수 있지만, 데이터 분석 파이프라인의 일부로 그래프를 생성하거나, 복잡한 시각화를 만들거나, 코드를 재사용할 계획이라면 객체 지향 인터페이스를 사용하는 것을 강력히 권장합니다.

마무리

이 튜토리얼에서는 Matplotlib의 기본 개념, 설치 및 임포트 방법, Figure와 Axes의 역할, pyplot 및 객체 지향 인터페이스를 사용한 기본 그래프(선 그래프, 산점도) 그리기, 제목/레이블/범례 추가, 축 범위/눈금 설정, 여러 개의 서브플롯 생성, 그래프 저장, 그리고 몇 가지 다른 그래프 유형과 스타일 적용 방법까지 살펴보았습니다.

Matplotlib는 매우 강력하고 유연한 라이브러리이므로 이 튜토리얼에서 다룬 내용은 기본적인 기능의 일부에 불과합니다. 더 깊이 있는 학습을 위해서는 Matplotlib 공식 갤러리(Gallery)를 둘러보며 다양한 그래프 예제 코드를 참고하거나, 공식 문서를 통해 특정 함수나 객체의 자세한 사용법을 익히는 것이 좋습니다.

데이터 분석 및 시각화 여정에서 Matplotlib가 유용한 도구가 되기를 바랍니다!

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部