파이썬 데이터 시각화 관련 첫 포스팅입니다! 🤗
이번 포스팅에서는 matplotlib 라이브러리로 레이아웃을 구성하는 방법에 대해 알아보도록 하겠습니다.
import matplotlib.pyplot as plt
plt.figure
fig = plt.figure()
plt.figure 메서드는 그래프를 그리기 위한 전체 영역을 확보합니다.
단, 영역만 확보할 뿐 아직 아무것도 그려지지는 않습니다.
이렇게 인스턴스화 한 figure 객체는 그래프를 그릴 수 있는 넓은 도화지라고 생각하면 됩니다.
fig.add_subplot
fig.add_subplot 메서드는 확보된 영역에 차트를 그릴 수 있는 영역인 ax 객체를 생성합니다.
전달 가능한 매개변수의 목록은 다음과 같습니다.
- nrows (fig 객체의 행 개수)
- ncols (fig 객체의 열 개수)
- index (fig 객체에서 subplot별 인덱스)
fig = plt.figure(figsize=(7, 7), facecolor='gray')
# ax1 = fig.add_subplot(311)과 동일합니다.
ax1 = fig.add_subplot(3, 1, 1)
# ax2 = fig.add_subplot(312)과 동일합니다.
ax2 = fig.add_subplot(3, 1, 2)
# ax3 = fig.add_subplot(313)과 동일합니다.
ax3 = fig.add_subplot(3, 1, 3)
위 예제코드는 3행1열 형태의 fig 객체를 인스턴스화합니다.
ax1, ax2, ax3은 각각 첫번째, 두번째, 세번째 subplot을 의미합니다.
fig2 = plt.figure(figsize=(7, 7), facecolor='linen')
ax1 = fig2.add_subplot(2, 2, 1)
ax2 = fig2.add_subplot(2, 2, 2)
ax3 = fig2.add_subplot(2, 1, 2)
fig2
변형된 차트 레이아웃을 구성할 수도 있습니다.
이때 필요한 점은 차트의 그리드 시스템을 바라보는 관점에 변화를 주는 것입니다.
위 예제코드를 실행하면 불규칙적인 레이아웃을 리턴합니다.
ax1, ax2는 그리드 시스템을 2행2열로 바라보지만 마지막 ax3는 2행1열 형태로 바라봅니다.
2행1열 중 두번째이므로 수평 방향으로 긴 차트 레이아웃이 나타나게 됩니다.
plt.subplots
# fig, (ax1, ax2) = plt.subplots(2, 1)
fig, axes = plt.subplots(2, 1, figsize=(7, 7), facecolor='linen')
plt.subplots는 앞서 정리한 plt.figure과 fig.add_subplot 메서드를 합친 메서드입니다.
한 가지 특징은 불규칙적인 차트 레이아웃을 구성할 수 없다는 점입니다.
다음 예제코드는 2행 1열의 레이아웃을 그립니다.
print(type(axes))
# <class 'numpy.ndarray'>
print(axes[0])
# Axes(0.125,0.53;0.775x0.35)
print(axes[1])
Axes(0.125,0.11;0.775x0.35)
위 코드에서 axes의 타입은 넘파이 배열(ndarray)입니다.
따라서 인덱싱을 통해 각 원소에 접근이 가능합니다.
fig, axes = plt.subplots(2, 2, figsize=(7, 7), facecolor='linen')
print(axes.shape)
# (2, 2)
print(axes)
# [[<Axes: > <Axes: >]
# [<Axes: > <Axes: >]]
for ax in axes.flat:
print(ax)
# Axes(0.125,0.53;0.352273x0.35)
# Axes(0.547727,0.53;0.352273x0.35)
# Axes(0.125,0.11;0.352273x0.35)
# Axes(0.547727,0.11;0.352273x0.35)
for idx, ax in enumerate(axes.flat):
print(idx, ax)
# 0 Axes(0.125,0.53;0.352273x0.35)
# 1 Axes(0.547727,0.53;0.352273x0.35)
# 2 Axes(0.125,0.11;0.352273x0.35)
# 3 Axes(0.547727,0.11;0.352273x0.35)
다음 예제코드는 2행2열 형태의 그래프 레이아웃을 생성합니다.
총 4개의 그래프를 그리는데 모든 그래프는 axes를 구성하게 됩니다.
이때 axes는 2차원 배열의 형태를 띕니다.
따라서 각 차트에 접근하기 위해서는 axes 배열을 평탄화하는 과정이 필요합니다.
2차원 배열을 1차원으로 바꾸기 위해 ndarray 객체의 flat 속성을 사용합니다.
plt.subplot2grid
💡 plt.subplot2grid(shape, loc, rowspan, colspan, fig)
plt.subplot2grid는 plt.subplots 메서드에 비해 복잡한 형태의 그래프 레이아웃을 그릴 수 있습니다.
한 가지 주의할 점은 매개변수 fig의 인수로 인스턴스화 한 fig 객체를 전달해야 한다는 점입니다.
각 매개변수의 의미를 살펴보겠습니다.
- shape (차트를 그릴 공간의 형태를 지정)
- loc (차트를 그릴 인덱스 또는 위치를 지정)
- rowspan (차트가 행 방향으로 차지할 칸 수)
- colspan (차트가 열 방향으로 차지할 칸 수)
fig = plt.figure(figsize=(7, 7), facecolor='lightgreen')
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=3, fig=fig)
ax2 = plt.subplot2grid((3, 3), (1, 0), colspan=2, fig=fig)
ax3 = plt.subplot2grid((3, 3), (1, 2), rowspan=2, fig=fig)
ax4 = plt.subplot2grid((3, 3), (2, 0), fig=fig)
ax5 = plt.subplot2grid((3, 3), (2, 1), fig=fig)
아래 예제코드는 3행3열 형태의 그래프 레이아웃을 그립니다.
예를 들면 ax1은 열 방향으로 3칸을 차지하고, ax2는 열 방향으로 2칸을 차지합니다.
참고로 loc 매개변수의 시작 인덱스는 0입니다.
# fig.add_subplot()
fig = plt.figure(figsize=(7, 7), facecolor='gray')
ax1 = fig.add_subplot(2, 1, 1)
ax2 = fig.add_subplot(2, 2, 3)
ax3 = fig.add_subplot(2, 2, 4)
# plt.subplot2grid()
fig2 = plt.figure(figsize=(7, 7), facecolor='lightgreen')
ax4 = plt.subplot2grid((2, 2), (0, 0), colspan=2, fig=fig2)
ax5 = plt.subplot2grid((2, 2), (1, 0), fig=fig2)
ax6 = plt.subplot2grid((2, 2), (1, 1), fig=fig2)
다음 예제코드는 fig.add_subplot과 plt.subplot2grid 메서드를 사용해서 동일한 레이아웃을 그립니다.
fig.add_axes
fig.add_axes 메서드를 사용하면 원하는 위치에 자유자재로 그래프를 그릴 수 있습니다.
우선 사용 가능한 매개변수의 목록을 살펴보겠습니다.
- left (왼쪽으로부터 떨어진 거리)
- right (오른쪽으로부터 떨어진 거리)
- width (가로 길이 비율)
- height (세로 길이 비율)
fig = plt.figure(figsize=(7, 7), facecolor='skyblue')
rect1 = [0.1, 0.1, 0.5, 0.5]
rect2 = [0.7, 0.1, 0.2, 0.5]
rect3 = [0.1, 0.7, 0.8, 0.2]
ax1 = fig.add_axes(rect1)
ax2 = fig.add_axes(rect2)
ax3 = fig.add_axes(rect3)
기본적인 메서드 사용법입니다.
fig = plt.figure(figsize=(7, 7), facecolor='skyblue')
left, bottom = 0.1, 0.1
spacing = 0.05
width1, height1 = 0.5, 0.5
width2 = 1 - (2*left + spacing + width1)
height2 = 1 - (2*bottom + spacing + height1)
rect1 = [left, bottom , width1, height1]
rect2 = [left, bottom + height1 + spacing, 1 - left*2, height2]
rect3 = [left + width1 + spacing, bottom, width2, height1]
ax1 = fig.add_axes(rect1)
ax2 = fig.add_axes(rect2)
ax3 = fig.add_axes(rect3)
바로 직전 코드를 개선한 코드입니다.
기준 수치를 변수로 선언하면 해당 변수의 값만 수정할 수 있기 때문에 그래프 레이아웃의 스케일을 다채롭게 구현할 수 있습니다.
fig = plt.figure(figsize=(7, 7), facecolor='skyblue')
left, bottom = 0.1, 0.1
spacing = 0.005
width1, height1 = 0.65, 0.65
width2 = 1 - (2*left + spacing + width1)
height2 = 1 - (2*bottom + spacing + height1)
rect1 = [left, bottom, width1, height1]
rect2 = [left + width1 + spacing, bottom, width2, height1]
rect3 = [left, bottom + height1 + spacing, width1, height2]
ax1 = fig.add_axes(rect1)
ax2 = fig.add_axes(rect2)
ax3 = fig.add_axes(rect3)
수치를 조절하면 다음 형태의 그래프 레이아웃도 구현이 가능합니다.
fig = plt.figure(figsize=(7, 7), facecolor='skyblue')
ax = fig.add_subplot(111)
ax_zoom = fig.add_axes([0.4, 0.4, 0.45, 0.45])
fig.add_axes 메서드의 장점으로, 중첩 레이아웃을 구현할 수 있습니다.
이때 ax를 선언하는 순서에 유의해야 합니다.
먼저 선언한 ax가 나중에 선언한 ax의 뒤에 위치하기 때문입니다.
마치며
이상으로 차트를 시각화하기 위한 사전 작업들에 대한 정리를 마치도록 하겠습니다.
- fig = plt.figure() 👉🏻 ax = fig.add_subplot() & ax = fig.add_axes() & ax = plt.subplot2grid(fig=fig)
- fig, axes = plt.subplots()
각 레이아웃 구성법의 장단점에 대해 숙지하고 상황에 따라 요구되는 바를 구현하면 좋을 것 같습니다.
다음 포스팅부터는 본격적으로 그래프를 시각화하는 기법들에 대해 알아보도록 하겠습니다.
'파이썬・ML > matplotlib・seaborn' 카테고리의 다른 글
matplotlib axes 조정하기(tight_layout, subplots_adjust) (0) | 2023.06.18 |
---|