여러 개의 차트를 모아서 그리기

Author

Gabriel Yang

Plotly에서 여러 개의 차트를 모아서 그리기

데이터 분석을 하다 보면 여러 개의 차트를 한 화면에 동시에 보여줘야 할 때가 많습니다. 여러 데이터를 비교하거나, 다양한 관점에서 데이터를 분석할 때 이러한 기능은 매우 유용합니다.

Plotly는 이러한 작업을 손쉽게 할 수 있도록 subplots 기능을 제공합니다. 이번 글에서는 Plotly에서 여러 개의 차트를 한 번에 보여주는 방법을 살펴보겠습니다.

왜 여러 개의 차트를 한 번에 보여줘야 할까?

여러 개의 차트를 한 화면에 동시에 표시하는 이유는 다양합니다:

  1. 데이터 비교: 서로 다른 데이터셋을 직접 비교하거나, 동일한 데이터셋을 다른 시각화 방법으로 표현할 때 유용합니다.
  2. 복합 분석: 여러 변수나 측정치를 동시에 분석하여 데이터의 상관관계나 패턴을 발견할 수 있습니다.
  3. 스토리텔링: 데이터의 흐름이나 변화 과정을 시각적으로 효과적으로 전달할 수 있습니다.

Plotly에서 Subplots 사용하기

Plotly에서 여러 개의 차트를 한 번에 표시하기 위해 make_subplots 함수를 사용합니다. 이 함수는 원하는 레이아웃에 따라 여러 개의 차트를 배치할 수 있는 강력한 도구를 제공합니다.

1. 간단한 예제: 두 개의 차트를 가로로 나란히 배치하기

먼저, 가장 기본적인 예제로 두 개의 차트를 가로로 나란히 배치하는 방법을 살펴보겠습니다.

import plotly.graph_objs as go
from plotly.subplots import make_subplots

# 서브플롯 생성 (1행 2열)
fig = make_subplots(rows=1, cols=2)

# 첫 번째 차트: 선 그래프
fig.add_trace(
    go.Scatter(x=[1, 2, 3, 4, 5], y=[10, 15, 13, 17, 16], mode='lines', name='Line Plot'),
    row=1, col=1
)

# 두 번째 차트: 막대 그래프
fig.add_trace(
    go.Bar(x=['A', 'B', 'C', 'D'], y=[5, 7, 3, 8], name='Bar Plot'),
    row=1, col=2
)

# 그래프 출력
fig.show()

코드 설명

make_subplots(rows=1, cols=2)

  • 1행 2열의 서브플롯 레이아웃을 생성합니다. 즉, 두 개의 차트를 가로로 나란히 배치합니다.

add_trace()

  • 첫 번째 차트로는 선 그래프(Scatter), 두 번째 차트로는 막대 그래프(Bar)를 추가했습니다.

  • 각각의 차트를 어느 행과 열에 배치할지 rowcol 인자를 통해 지정합니다.

2. 다양한 레이아웃의 서브플롯 만들기

make_subplots를 사용하면 원하는 레이아웃에 따라 여러 개의 차트를 배치할 수 있습니다. 예를 들어, 2x2 그리드로 4개의 차트를 배치하는 방법은 다음과 같습니다.

import plotly.graph_objs as go
from plotly.subplots import make_subplots

# 서브플롯 생성 (2행 2열)
fig = make_subplots(rows=2, cols=2, subplot_titles=("Line Plot", "Bar Plot", "Scatter Plot", "Line Chart"))

# 첫 번째 차트: 선 그래프
fig.add_trace(
    go.Scatter(x=[1, 2, 3, 4, 5], y=[10, 15, 13, 17, 16], mode='lines', name='Line Plot'),
    row=1, col=1
)

# 두 번째 차트: 막대 그래프
fig.add_trace(
    go.Bar(x=['A', 'B', 'C', 'D'], y=[5, 7, 3, 8], name='Bar Plot'),
    row=1, col=2
)

# 세 번째 차트: 스캐터 플롯
fig.add_trace(
    go.Scatter(x=[10, 20, 30, 40], y=[2, 4, 6, 8], mode='markers', name='Scatter Plot'),
    row=2, col=1
)

# 네 번째 차트: 선 그래프
fig.add_trace(
    go.Scatter(x=['X', 'Y', 'Z'], y=[50, 30, 20], name='Line Chart'),
    row=2, col=2
)

# 그래프 레이아웃 업데이트 (타이틀 설정)
fig.update_layout(title_text="Multiple Subplots Example")

# 그래프 출력
fig.show()

코드 설명

subplot_titles:

  • 각 서브플롯에 제목을 추가하여 차트의 내용을 명확히 합니다.

4개의 차트 추가:

  • 선 그래프, 막대 그래프, 스캐터 플롯, 파이 차트를 각각의 서브플롯에 배치했습니다.

update_layout:

  • 전체 그래프의 크기와 타이틀을 설정하여 레이아웃을 조정합니다.

3. 공유된 축을 사용하는 서브플롯

경우에 따라 여러 차트가 동일한 축을 공유하는 것이 유용할 수 있습니다. 예를 들어, 동일한 X축을 공유하는 여러 개의 차트를 세로로 배치하려면 다음과 같이 할 수 있습니다:

import plotly.graph_objs as go
from plotly.subplots import make_subplots

# 서브플롯 생성 (3행 1열, X축 공유)
fig = make_subplots(rows=3, cols=1, shared_xaxes=True, vertical_spacing=0.1)

# 첫 번째 차트: 선 그래프
fig.add_trace(
    go.Scatter(x=[1, 2, 3, 4, 5], y=[10, 15, 13, 17, 16], mode='lines', name='Line Plot 1'),
    row=1, col=1
)

# 두 번째 차트: 선 그래프
fig.add_trace(
    go.Scatter(x=[1, 2, 3, 4, 5], y=[20, 25, 23, 27, 26], mode='lines', name='Line Plot 2'),
    row=2, col=1
)

# 세 번째 차트: 선 그래프
fig.add_trace(
    go.Scatter(x=[1, 2, 3, 4, 5], y=[30, 35, 33, 37, 36], mode='lines', name='Line Plot 3'),
    row=3, col=1
)

# 그래프 레이아웃 업데이트 (타이틀 설정)
fig.update_layout(height=600, width=600, title_text="Shared X-Axes Subplots Example")

# 그래프 출력
fig.show()

코드 설명

shared_xaxes=True:

  • 세 개의 차트가 동일한 X축을 공유하도록 설정합니다.

vertical_spacing=0.1:

  • 서브플롯 간의 수직 간격을 조정하여 시각적인 간격을 설정합니다.

4. 서브플롯 병합하기

이제 서브플롯 공간을 병합하여 특정 영역을 더 크게 사용하는 방법을 살펴보겠습니다. make_subplots에서는 specs라는 인자를 사용하여 특정 서브플롯 공간을 병합할 수 있습니다.

열(column) 병합 방식

다음 예시에서는 2x2 레이아웃에서 왼쪽 상단의 서브플롯이 두 칸을 차지하도록 병합해보겠습니다.

import plotly.graph_objects as go
from plotly.subplots import make_subplots

# 2x2 서브플롯 생성 및 병합 설정
fig = make_subplots(
    rows=2, cols=2,
    specs=[[{"colspan": 2}, None],  # 첫 번째 서브플롯이 두 칸을 차지
           [{}, {}]]                # 두 번째 행은 병합하지 않음
)

# 데이터 추가
fig.add_trace(go.Scatter(x=[1, 2, 3], y=[4, 5, 6]), row=1, col=1)
fig.add_trace(go.Scatter(x=[1, 2, 3], y=[7, 3, 5]), row=2, col=1)
fig.add_trace(go.Scatter(x=[1, 2, 3], y=[4, 8, 3]), row=2, col=2)

# 그래프 출력
fig.show()

설명

  • specs 인자는 각 서브플롯의 배치와 크기를 정의합니다.
  • {"colspan": 2}: 첫 번째 서브플롯이 첫 번째 행의 두 칸을 모두 차지하도록 설정합니다.
  • None: 첫 번째 행의 두 번째 칸을 비워둡니다(병합된 상태).
  • 두 번째 행은 [{},{},]로 정의되어 있으며, 이 행에는 두 개의 서브플롯이 별도로 배치됩니다.

결과적으로, 왼쪽 상단의 서브플롯은 전체 상단 행을 차지하게 되어 더 넓은 그래프 영역을 가집니다.

5. 행(row) 병합 방식

다음 예시에서는 2x2 레이아웃에서 왼쪽의 서브플롯 두 칸을 차지하도록 병합해보겠습니다.

import plotly.graph_objects as go
from plotly.subplots import make_subplots

# 2x2 서브플롯 생성 및 병합 설정
fig = make_subplots(
    rows=2, cols=2,
    specs=[[{"rowspan": 2}, {}],  # 첫 번째 서브플롯이 두 행과 두 열을 차지
           [None, {}]]
)

# 데이터 추가
fig.add_trace(go.Scatter(x=[1, 2, 3], y=[4, 5, 6]), row=1, col=1)
fig.add_trace(go.Scatter(x=[1, 2, 3], y=[4, 5, 6]), row=1, col=2)
fig.add_trace(go.Scatter(x=[1, 2, 3], y=[4, 5, 6]), row=2, col=2)

# 그래프 출력
fig.show()

설명

  • {"rowspan": 2, "colspan": 2}: 첫 번째 서브플롯이 열의 2칸을 차지하도록 설정합니다.
  • None: 두 번째 행의 첫 번째 칸을 비워둡니다(병합된 상태).
  • 각 행의 두 번째 열은 [{},{},]로 정의되어 있으며, 이 행에는 두 개의 서브플롯이 별도로 배치됩니다.
  • None으로 채워진 나머지 부분은 병합된 상태를 나타냅니다.

이 예제에서는 하나의 큰 서브플롯이 전체 2x2 그리드를 차지합니다.

결론

Plotly의 subplots 기능을 사용하면 여러 개의 차트를 한 화면에 동시에 표시할 수 있어, 데이터 분석과 비교를 한층 더 효율적으로 수행할 수 있습니다.

다양한 레이아웃 옵션과 축 공유 기능을 활용하면, 복잡한 데이터도 쉽게 시각화하고 이해할 수 있습니다.