make_subplots 기초
지윤의 노트북에는 탭이 너무 많았습니다. 매출 차트, 비중 차트, 지역 비교, 상관관계. 발표 때 탭을 하나씩 전환하면서 설명하다가 교수님께 지적받은 기억이 있었습니다.
"한 화면에 보여줘야 한다고."
Plotly에는 make_subplots()라는 함수가 있습니다. 여러 차트를 격자 형태로 배치해서 하나의 figure로 만들어주는 도구입니다.
기본 구조
make_subplots()는 plotly.subplots 모듈에서 가져옵니다. Plotly Express나 Graph Objects와 달리 별도로 import해야 합니다.
# 새 파일: subplot_basic.pyfrom plotly.subplots import make_subplotsimport plotly.graph_objects as go# 2행 2열 격자 만들기fig = make_subplots(rows=2, cols=2)# 각 위치에 trace 추가fig.add_trace( go.Scatter(x=[1, 2, 3], y=[4, 5, 6], name="선 그래프"), row=1, col=1)fig.add_trace( go.Bar(x=["A", "B", "C"], y=[10, 20, 15], name="막대 그래프"), row=1, col=2)fig.add_trace( go.Scatter(x=[1, 2, 3], y=[10, 8, 12], mode="markers", name="산점도"), row=2, col=1)fig.add_trace( go.Bar(x=["X", "Y", "Z"], y=[5, 15, 10], name="또 다른 막대"), row=2, col=2)fig.update_layout(title_text="2x2 서브플롯 기본 예시")fig.show()
rows=2, cols=2로 2행 2열 격자를 만들었습니다. 그리고 add_trace()를 호출할 때 row와 col로 위치를 지정합니다. 좌표는 1부터 시작합니다.
제목 붙이기
각 서브플롯에 개별 제목을 붙이려면 subplot_titles 파라미터를 사용합니다. 순서는 왼쪽에서 오른쪽, 위에서 아래 방향입니다.
fig = make_subplots( rows=2, cols=2, subplot_titles=("1분기 매출", "카테고리 비중", "지역별 비교", "상관관계"))
축 공유
여러 서브플롯이 같은 X축 또는 Y축 범위를 공유해야 할 때는 shared_xaxes와 shared_yaxes를 사용합니다. 시계열 데이터에서 특히 유용합니다.
fig = make_subplots( rows=2, cols=1, shared_xaxes=True, # X축 공유 (같은 시간 범위) shared_yaxes=False)
간격 조절
서브플롯 사이의 간격은 vertical_spacing과 horizontal_spacing으로 조절합니다. 값은 0에서 1 사이의 비율입니다. 기본값은 0.3 정도인데, 차트가 많으면 좁아 보일 수 있습니다.
fig = make_subplots( rows=2, cols=2, vertical_spacing=0.15, # 행 사이 간격 (기본보다 좁게) horizontal_spacing=0.1 # 열 사이 간격)
실전: 2x2 그리드에 4개 차트 배치
지윤의 캡스톤 팀 데이터를 기반으로 2x2 대시보드를 만들어봅니다. 분기별 매출 추이, 팀별 기여도, 지역별 실적 비교, 항목 간 상관관계를 한 화면에 담습니다.
# 새 파일: dashboard_2x2.pyfrom plotly.subplots import make_subplotsimport plotly.graph_objects as go# 샘플 데이터quarters = ["1Q", "2Q", "3Q", "4Q"]sales = [120, 145, 132, 178]categories = ["기획", "개발", "디자인", "QA"]contributions = [30, 40, 20, 10]regions = ["서울", "경기", "인천", "부산", "대구"]performance = [85, 72, 68, 91, 77]items_x = [10, 20, 15, 30, 25, 18]items_y = [22, 38, 29, 55, 47, 34]# 2x2 서브플롯 생성fig = make_subplots( rows=2, cols=2, subplot_titles=( "분기별 매출 추이", "팀별 기여도", "지역별 실적", "투입 vs 산출 상관관계" ), vertical_spacing=0.15, horizontal_spacing=0.1)# (1, 1) 선 그래프: 분기별 매출fig.add_trace( go.Scatter( x=quarters, y=sales, mode="lines+markers", name="매출", line=dict(color="#1B3A5C", width=2), marker=dict(size=8) ), row=1, col=1)# (1, 2) 원형 차트: 팀별 기여도fig.add_trace( go.Pie( labels=categories, values=contributions, name="기여도", hole=0.3 ), row=1, col=2)# (2, 1) 막대 그래프: 지역별 실적fig.add_trace( go.Bar( x=regions, y=performance, name="실적", marker_color="#4A90D9" ), row=2, col=1)# (2, 2) 산점도: 상관관계fig.add_trace( go.Scatter( x=items_x, y=items_y, mode="markers", name="상관관계", marker=dict(size=10, color="#E67E22") ), row=2, col=2)fig.update_layout( title_text="캡스톤 프로젝트 중간발표 대시보드", height=700, showlegend=False)fig.show()
실행해보면 네 개의 차트가 격자 형태로 깔끔하게 배치됩니다. showlegend=False로 범례를 숨겼는데, 각 차트의 제목만으로 충분히 의미가 전달되기 때문입니다.
지윤은 결과 화면을 보며 처음으로 안도의 한숨을 쉬었습니다. 탭 네 개가 화면 하나로 줄어들었습니다.