소개
데이터 시각화에서는 단일 그림 (figure) 에 여러 개의 플롯 (plot) 을 표시하는 것이 유용한 경우가 많습니다. 이를 통해 서로 다른 데이터셋 간 또는 동일한 데이터의 서로 다른 뷰 간의 비교를 쉽게 할 수 있습니다. Matplotlib 은 서브플롯 (subplots) 을 사용하여 이러한 그림을 생성하는 강력하고 편리한 방법을 제공합니다.
서브플롯을 생성하는 가장 일반적인 방법은 plt.subplots() 함수를 사용하는 것입니다. 이 함수는 단일 호출로 그림과 서브플롯 그리드를 생성하며, Figure 객체와 각 개별 서브플롯을 나타내는 Axes 객체의 배열을 반환합니다.
이 실습에서는 다음을 배우게 됩니다.
- 여러 개의 서브플롯을 포함하는 그림 생성하기
- 특정 서브플롯에 데이터 플롯하기
- 플롯이 겹치지 않도록 레이아웃 조정하기
- 더 명확한 비교를 위해 서브플롯 간 축 공유하기
WebIDE 에서 Python 스크립트를 작성하고 실행하게 됩니다. 이 환경은 대화형 GUI 창을 지원하지 않으므로, 플롯을 이미지 파일로 저장하고 편집기에서 직접 확인하게 됩니다.
plt.subplots() 를 사용하여 그림 (figure) 과 축 (axes) 생성하기
이 단계에서는 한 행과 두 열로 배열된 두 개의 빈 서브플롯을 포함하는 그림을 생성하는 것으로 시작합니다. 이는 다중 플롯 시각화를 구축하는 기초 단계입니다.
plt.subplots() 함수를 사용할 것입니다. plt.subplots(nrows, ncols)를 호출하면 두 가지 항목이 반환됩니다.
Figure객체: 모든 것이 그려지는 전체 창 또는 페이지입니다. 일반적으로fig라는 변수에 할당합니다.Axes객체의 배열: 각Axes객체는 그리드의 서브플롯 중 하나를 나타냅니다. 인덱스로 접근할 수 있습니다.(1, 2)그리드의 경우 이 배열을ax1및ax2두 변수로 언패킹 (unpack) 할 수 있습니다.
코드를 작성해 보겠습니다. 왼쪽에 있는 파일 탐색기에서 main.py 파일을 열고 다음 내용을 추가하세요. 이 스크립트는 필요한 라이브러리를 가져오고, 두 개의 서브플롯이 있는 그림을 생성하고, 이를 plot1.png라는 이미지 파일로 저장합니다.
import matplotlib.pyplot as plt
import numpy as np
## 그림 및 서브플롯 세트 생성
## 1 행, 2 열
fig, (ax1, ax2) = plt.subplots(1, 2)
## 그림을 파일로 저장
## 파일은 /home/labex/project 디렉토리에 생성됩니다.
plt.savefig('plot1.png')
print("Figure saved as plot1.png")
이제 터미널에서 스크립트를 실행하여 플롯을 생성합니다.
python3 main.py
터미널에서 다음과 같은 출력을 볼 수 있습니다.
Figure saved as plot1.png
plot1.png라는 새 파일이 파일 탐색기에 나타납니다. 이 파일을 더블 클릭하여 두 개의 빈 서브플롯이 있는 첫 번째 그림을 확인하세요.

ax1.plot() 를 사용하여 첫 번째 서브플롯에 플로팅하기
이 단계에서는 생성한 특정 Axes 객체 중 하나에 플롯을 그리는 방법을 배우게 됩니다. 각 Axes 객체는 plot(), bar(), scatter() 등과 같이 메인 plt 인터페이스의 함수와 유사한 자체 플로팅 메서드를 가지고 있습니다.
ax1 변수로 표현되는 첫 번째 서브플롯에 간단한 사인파 (sine wave) 를 플롯할 것입니다. 또한 set_title() 메서드를 사용하여 이 서브플롯에 제목을 추가할 것입니다.
main.py 파일을 다음 코드로 업데이트하세요. NumPy 를 사용하여 데이터를 생성한 다음 ax1에 플롯하는 코드를 추가합니다.
import matplotlib.pyplot as plt
import numpy as np
## 데이터 생성
x = np.linspace(0, 2 * np.pi, 400)
y = np.sin(x ** 2)
## 그림 및 서브플롯 세트 생성
fig, (ax1, ax2) = plt.subplots(1, 2)
## 첫 번째 서브플롯 (ax1) 에 플롯
ax1.plot(x, y)
ax1.set_title('Sine Wave')
## 그림을 새 파일로 저장
plt.savefig('plot2.png')
print("Figure saved as plot2.png")
이제 터미널에서 업데이트된 스크립트를 실행합니다.
python3 main.py
다음 출력을 볼 수 있습니다.
Figure saved as plot2.png
plot2.png라는 새 파일이 이제 프로젝트 디렉토리에 있습니다. 결과를 보려면 파일을 엽니다. 왼쪽 서브플롯에는 사인파 플롯이 포함되어야 하며, 오른쪽 서브플롯은 비어 있어야 합니다.

ax2.plot() 를 사용하여 두 번째 서브플롯에 플로팅하기
이 단계에서는 두 번째 서브플롯에 플롯을 추가하여 그림을 완성합니다. 이전 단계와 동일한 과정이지만, 이번에는 ax2 객체에서 plot() 메서드를 호출합니다.
사인파와 비교하기 위해 두 번째 서브플롯에 코사인파 (cosine wave) 를 플롯할 것입니다. 또한 제목도 지정합니다.
두 번째 축에 플롯을 포함하도록 main.py 파일을 수정하세요.
import matplotlib.pyplot as plt
import numpy as np
## 데이터 생성
x = np.linspace(0, 2 * np.pi, 400)
y1 = np.sin(x ** 2)
y2 = np.cos(x ** 2)
## 그림 및 서브플롯 세트 생성
fig, (ax1, ax2) = plt.subplots(1, 2)
## 첫 번째 서브플롯 (ax1) 에 플롯
ax1.plot(x, y1)
ax1.set_title('Sine Wave')
## 두 번째 서브플롯 (ax2) 에 플롯
ax2.plot(x, y2, 'tab:orange')
ax2.set_title('Cosine Wave')
## 그림을 새 파일로 저장
plt.savefig('plot3.png')
print("Figure saved as plot3.png")
위 코드에서 ax2.plot() 호출에 'tab:orange'를 추가하여 선 색상을 변경함으로써 플롯을 시각적으로 구분했습니다.
터미널에서 스크립트를 다시 실행합니다.
python3 main.py
출력은 다음과 같습니다.
Figure saved as plot3.png
이제 plot3.png를 엽니다. 나란히 두 개의 플롯이 있는 완성된 그림을 볼 수 있습니다. 하지만 제목이나 축 레이블이 약간 빽빽하게 보일 수 있습니다. 다음 단계에서 이를 수정할 것입니다.

plt.tight_layout() 를 사용하여 서브플롯 레이아웃 조정하기
이 단계에서는 제목과 레이블이 겹치는 것을 방지하기 위해 서브플롯 간의 간격을 자동으로 조정하는 방법을 배우게 됩니다. Matplotlib 는 이를 위한 간단한 함수인 plt.tight_layout()을 제공합니다.
이 함수는 그림의 모든 아티스트 (제목, 레이블, 플롯 자체 등) 의 경계 상자를 검사하고 서브플롯 매개변수를 조정하여 모든 것이 겹치지 않고 깔끔하게 맞도록 합니다. 플롯을 저장하거나 표시하기 직전에 호출하는 것이 좋습니다.
스크립트에 plt.tight_layout()을 추가해 보겠습니다. main.py를 다음과 같이 업데이트하세요.
import matplotlib.pyplot as plt
import numpy as np
## 데이터 생성
x = np.linspace(0, 2 * np.pi, 400)
y1 = np.sin(x ** 2)
y2 = np.cos(x ** 2)
## 그림 및 서브플롯 세트 생성
fig, (ax1, ax2) = plt.subplots(1, 2)
## 첫 번째 서브플롯 (ax1) 에 플롯
ax1.plot(x, y1)
ax1.set_title('Sine Wave')
## 두 번째 서브플롯 (ax2) 에 플롯
ax2.plot(x, y2, 'tab:orange')
ax2.set_title('Cosine Wave')
## 겹침 방지를 위해 레이아웃 조정
plt.tight_layout()
## 그림을 새 파일로 저장
plt.savefig('plot4.png')
print("Figure saved as plot4.png")
변경된 부분은 plt.tight_layout() 줄이 추가된 것뿐입니다. 이제 스크립트를 실행합니다.
python3 main.py
출력:
Figure saved as plot4.png
plot4.png를 열고 plot3.png와 비교해 보세요. 두 서브플롯 간의 간격이 최적화되어 더 깔끔하고 전문적인 그림을 볼 수 있을 것입니다.

sharex=True 또는 sharey=True 를 사용하여 축 공유하기
이 단계에서는 공통 축을 공유하는 서브플롯을 만드는 방법을 배우게 됩니다. 이는 x 축 또는 y 축 스케일이 동일한 데이터셋을 비교할 때 특히 유용합니다. 축이 공유되면 한 서브플롯에서 확대/축소 또는 이동하면 다른 서브플롯도 자동으로 업데이트됩니다. 또한 중복되는 눈금 레이블을 제거하여 그림을 깔끔하게 만드는 데 도움이 됩니다.
plt.subplots()에 sharex=True 또는 sharey=True 인수를 전달하여 축 공유를 활성화할 수 있습니다.
이를 시연하기 위해 새 스크립트를 만들어 보겠습니다. 프로젝트 디렉터리에 shared_axes.py라는 파일을 만들고 다음 코드를 추가하세요. 이 예제는 동일한 x 축을 공유하는 두 개의 서브플롯을 수직으로 쌓아 (nrows=2, ncols=1) 만듭니다.
import matplotlib.pyplot as plt
import numpy as np
## 데이터 생성
t = np.arange(0.01, 5.0, 0.01)
s1 = np.exp(t)
s2 = np.sin(2 * np.pi * t)
## x 축을 공유하는 그림과 두 개의 서브플롯 생성
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)
## 첫 번째 서브플롯에 플롯
ax1.plot(t, s1, 'tab:blue')
ax1.set_ylabel('Exponential')
## 두 번째 서브플롯에 플롯
ax2.plot(t, s2, 'tab:orange')
ax2.set_ylabel('Sinusoidal')
ax2.set_xlabel('time (s)')
## 레이아웃 조정
plt.tight_layout()
## 그림 저장
plt.savefig('plot5.png')
print("Figure saved as plot5.png")
이제 터미널에서 이 새 스크립트를 실행합니다.
python3 shared_axes.py
출력:
Figure saved as plot5.png
plot5.png를 엽니다. 아래쪽 서브플롯 (ax2) 에만 x 축 눈금 레이블이 있는 것을 알 수 있습니다. 이는 sharex=True가 깔끔한 모양을 만들기 위해 내부 x 축 레이블을 자동으로 숨기기 때문입니다. 두 플롯 모두 x 축을 따라 완벽하게 정렬되어 비교하기 쉽습니다.

요약
실험을 완료하신 것을 축하드립니다! Matplotlib 에서 서브플롯을 생성하고 관리하는 필수적인 기술들을 익히셨습니다.
이번 실험에서 연습한 내용은 다음과 같습니다:
plt.subplots()를 사용하여 서브플롯 그리드가 있는 그림을 생성했습니다.- 개별
Axes객체에 접근하고 해당 메서드를 사용하여 데이터를 플롯했습니다. - 특정 서브플롯에 제목을 추가했습니다.
plt.tight_layout()을 사용하여 간격을 자동으로 조정하고 요소 겹침을 방지했습니다.sharex=True를 사용하여 서브플롯의 축을 공유하여 더 명확한 데이터 비교와 깔끔한 그림을 만들었습니다.
이러한 기술들은 복잡하고 유익한 데이터 시각화를 만드는 데 기본이 됩니다. 이제 단일하고 일관된 보기에서 여러 데이터셋을 효과적으로 비교하는 그림을 만들 수 있습니다.



