본문 바로가기
데이터 분석/시각화

[Matplotlib] gridspec을 이용하여 여러 Axes 배치하기(feat. subplot)

by 부자 꽁냥이 2022. 6. 17.

안녕하세요~ 꽁냥이에요. 데이터 시각화를 하다 보면 하나의 화면 속에 여러 그림을 그려야 할 때가 있습니다. 이때에는 각 그림을 어떻게 배치할 것인가가 중요합니다. Matplotlib에서는 각 그림을 어떻게 배치하느냐는 결국 Axes를 어떻게 배치하느냐를 결정하는 것과 같습니다. 왜냐하면 Axes안에 그림이 그려지니까요.

 

Matplotlib에서는 gridspec이라는 것이 있는데요. 이를 이용하면 여러 Axes를 자기가 원하는 대로 배치할 수 있습니다.

 

이번 포스팅에서는 Matplotlib의 gridspec을 이용하여 여러 Axes를 배치하는 방법에 대해서 알아보겠습니다. 여기서 다루는 내용은 다음과 같습니다.

 

1. Gridspec 기본 사용법

2. 여러 Gridspec을 이용한 복잡한 배치


   1. Gridspec 기본 사용법

여기서는 Matplotlib에서 제공하는 GridSpec 객체 기본 사용법을 알아보겠습니다. GridSpec은 배치하려는 행과 열 개수를 인자로 받습니다.

 

먼저 Axes 12개를 4X3 형태로 배치하려고 한다면 아래와 같이 사용하면되는 것입니다.


GridSpec(nrows=4, ncols=3)


이제 코드를 통해서 알아보겠습니다.

 

import warnings
warnings.filterwarnings('ignore')
import matplotlib.pyplot as plt

from matplotlib.gridspec import GridSpec

fig = plt.figure(figsize=(12,18), facecolor='white')

nrows = 4 ## 행 개수
ncols = 3 ## 열 개수
gs = GridSpec(nrows=nrows, ncols=ncols) ## 또는 fig.add_gridspec(nrows=nrows, ncols=ncols)
row_idx = 0 
for i in range(nrows*ncols):
    col_idx = i%ncols
    ax = fig.add_subplot(gs[row_idx, col_idx])
    ax.set_title(f'({row_idx+1}, {col_idx+1})')
    if col_idx == 2:
        row_idx += 1
        
gs.tight_layout(fig) ## 서로 겹치지 않으면서 공간을 효율적으로 활용하게함.
plt.show()

 

line 11

GridSpec 객체를 생성했습니다. 이띠 fig.add_gridspec을 사용할 수도 있습니다. 이에 대해선 아래에서 다룹니다.

 

line 15

GridSpec 객체를 생성했다고 해서 Axes의 배치를 직접 볼 수 있는 것은 아닙니다. 이를 보기 위해선 add_subplot에 앞에서 생성한 GridSpec객체를 인자로 넘겨줘야 합니다. 이때 GridSpec 객체에서 인덱싱을 통해 Axes를 원하는 위치에 배치할 수 있습니다.

 

위 코드를 실행하면 아래와 같이 Axes가 배치된 것을 알 수 있어요.

 

위와 같은 배치의 경우 굳이 GridSpec을 이용하지 않고도 아래 코드를 통해 구현할 수 있습니다.

 

fig = plt.figure(figsize=(12,18), facecolor='white')

nrows = 4
ncols = 3

for i in range(nrows*ncols):
    ax = fig.add_subplot(nrows, ncols, i+1)
    row_idx = i//ncols
    col_idx = i%ncols
    ax.set_title(f'({row_idx+1}, {col_idx+1})')
plt.tight_layout()
plt.show()

 


   2. 여러 Gridspec을 이용한 복잡한 배치

앞에서 GridSpec 객체를 생성하는 방법에는 add_gridspec을 이용할 수도 있다고 했습니다. 이는 여러 GridSpec을 추가하여 복잡합 배치를 하는데 사용됩니다.

 

아래 코드는 왼쪽엔 3X1 배치, 오른쪽엔 2X2 배치를 합쳐놓은 Axes들의 배치입니다. 

 

fig = plt.figure(figsize=(20,15), facecolor='white')

## Left
gs1_nrows = 3
gs1_ncols = 1

# GridSpec 객체 생성
gs1 = fig.add_gridspec(nrows=gs1_nrows, ncols=gs1_ncols, left=0, right=0.5)

row_idx=0
for i in range(gs1_nrows*gs1_ncols):
    col_idx = i%gs1_ncols
    ax = fig.add_subplot(gs1[row_idx, col_idx])
    ax.set_title(f'Left({row_idx+1}, {col_idx+1})')
    if col_idx == gs1_ncols-1:
        row_idx += 1

## Right
gs2_nrows = 2
gs2_ncols = 2

# GridSpec 객체 생성
gs2 = fig.add_gridspec(nrows=gs2_nrows, ncols=gs2_ncols, left=0.53, right=1)

row_idx = 0 
for i in range(gs2_nrows*gs2_ncols):
    col_idx = i%gs2_ncols
    ax = fig.add_subplot(gs2[row_idx, col_idx])
    ax.set_title(f'Right({row_idx+1}, {col_idx+1})')
    if col_idx == gs2_ncols-1:
        row_idx += 1

plt.show()

 

여기서는 left, right를 이용하여 왼쪽 부분과 오른쪽 부분의 가로 차지 비율을 설정했습니다. 여기서 left, right 작동 방식은 다음 그림과 같습니다. 이때 gs2의 left 값인 0.53과 gs1의 right값인 0.5의 차이 0.03은 여백이라고 생각하면 됩니다. 또한 left 값은 그림의 왼쪽 시작점이고 right는 그림의 오른쪽 마지막 점이라고 할 수 있습니다. 따라서 하나의 gridspec에서 left 값은 항상 right 값보다 작거나 같아야 합니다. 안 그러면 에러 나요~

 

 

이번엔 위쪽에 1X3 배치, 아래쪽에 2X2 배치를 합쳐서 배치하는 코드를 살펴보겠습니다.

 

fig = plt.figure(figsize=(10,8), facecolor='white')

## Top
gs1_nrows = 1
gs1_ncols = 3
gs1 = fig.add_gridspec(nrows=gs1_nrows, ncols=gs1_ncols, bottom=0.6, top=1)

row_idx = 0 
for i in range(gs1_nrows*gs1_ncols):
    col_idx = i%gs1_ncols
    ax = fig.add_subplot(gs1[row_idx, col_idx])
    ax.set_title(f'Top ({row_idx+1}, {col_idx+1})')
    if col_idx == gs1_ncols-1:
        row_idx += 1

## Bottom
gs2_nrows = 2
gs2_ncols = 2
gs2 = fig.add_gridspec(nrows=gs2_nrows, ncols=gs2_ncols, bottom=0, top=0.5, 
                       hspace=0.3)

row_idx = 0 
for i in range(gs2_nrows*gs2_ncols):
    col_idx = i%gs2_ncols
    ax = fig.add_subplot(gs2[row_idx, col_idx])
    ax.set_title(f'Bottom({row_idx+1}, {col_idx+1})')
    if col_idx == gs2_ncols-1:
        row_idx += 1

plt.show()

 

여기에서는 bottom, top을 이용하여 높이를 차지하는 비율을 조절했습니다. 원리는 left, right와 비슷합니다.

 


이번 포스팅에서는 GridSpec을 이용하여 여러 Axes를 배치하는 방법을 알아보았습니다. 사실 시각화 결과를 볼 때에는 하나의 결과를 보는 것이 아니라 여러 결과를 한 번에 보는 것이 결과를 종합적으로 더 빠르게 판단할 수 있습니다. 이번 포스팅에서 다룬 내용은 이렇게 여러 그림을 한 번에 그리는 데 있어서 유용하게 사용할 수 있으므로 꼭 알아두세요~!!

 

다음에도 좋은 내용으로 찾아뵙겠다는 말을 전하며 이상 포스팅 마치겠습니다.


 

댓글


맨 위로