🚢 titanic

[python] 항해일지 07. 함교에 올라 조종하기: streamlit

Floaty 2026. 6. 28. 10:00

벌써 항해일지의 마지막이네요. 마지막 시간에 시도해볼 건 streamlit 라이브러리입니다. 지금까지 만든 분석을 누구나 브라우저에서 클릭하며 탐색할 수 있는 웹앱으로 만들 수 잇는 것이 streamlit의 가장 큰 장점입니다. 파이썬 코드만으로 버튼, 슬라이더, 그래프가 있는 대시보드를 만듭니다. 

 

오늘 만들 대시보드는 이런 흐름으로 완성됩니다. 먼저 페이지 제목을 화면 상단에 올리고, 왼쪽 사이드바에 성별, 객실 등급 필터를 달아요. 사용자가 필터를 조작하면 그 조건에 맞게 전체 인원, 생존자 수, 생존율 카드가 실시간으로 바뀌고, 아래로 내려가면 객실 등급별 생존율 막대 그래프와 나이/요금의 상관관계를 보여주는 인터랙티브 산점도가 차례로 그려집니다. 원하면 체크박스를 눌러 필터링된 원본 데이터도 표로 확인할 수 있어요.

 

하나씩 차근차근 해봅시다. 

 

 

 

라이브러리 불러오기 & 페이지 기본 설정

import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import plotly.express as px
from utils.theme import set_plot_theme, get_palette

set_plot_theme()

st.set_page_config(                   # Streamlit 앱의 기본 설정을 지정하는 함수
    page_title="타이타닉 데이터 대시보드",  # 브라우저 탭에 표시될 페이지 제목
    layout="wide",                    # 화면 배치 방식(wide: 넓은 화면 레이아웃)
)

streamlit 앱의 제목과 화면 레이아웃을 설정해요. 화면에 내용을 그리기 전에 먼저 실행하는 것이 좋습니다.

 

 

 

데이터 불러오기

@st.cache_data  # 함수 실행 결과를 캐시에 저장하는 데코레이터
def load_data():
    return pd.read_csv("data/titanic.csv")


df = load_data()

타이타닉 CSV 파일을 읽어와서 데이터프레임으로 저장합니다.

 

여기서 `@st.cache_data라는 낯선 문법이 등장해요. 이게 바로 데코레이터라는 녀석입니다. `@`가 붙으면 데코레이터라고 보면 됩니다. 데코레이터는 함수의 기능을 수정하거나 확장할 때 쓰는 문법이에요. `@st.cache_data`는 그 중에서도 캐시 관련 데코레이터인데 한 번 실행한 함수의 결과를 저장해뒀다가 같은 함수를 다시 호출하면 코드를 새로 실행하지 않고 저장된 결과를 바로 돌려줍니다. 덕분에 앱이 새로고침될 때마다 파일을 반복해서 읽지 않아도 되고 속도도 빨라져요.

 

 

 

대시보드 제목 출력

# Streamlit 앱에 큰 제목을 출력하는 함수
st.title("타이타닉 생존자 데이터 대시보드")

앱 상단에 대시보드 제목을 표시합니다. 

 

 

 

사이드바 필터 만들기

st.sidebar.header("필터") # 사이드바에 섹션 제목을 표시하는 함수

sex_filter = (
    st.sidebar.multiselect(         # 여러 값을 선택할 수 있는 드롭다운 필터를 만드는 함수
        "성별 선택",                  # 사용자에게 보여줄 필터 이름
        options=df["sex"].unique(), # 선택 가능한 값 목록: ['male', 'female']
        default=df["sex"].unique(), # 기본으로 선택되어 있을 값: 모든 성별이 선택됨
    )
)

pclass_filter = st.sidebar.multiselect(
    "객실 등급 선택",
    options=sorted(df["pclass"].unique()), # 선택 가능한 값 목록: 선택 가능한 객실 등급 목록
    default=sorted(df["pclass"].unique()), # 기본으로 선택되어 있을 값: 모든 객실 등급이 선택됨
)

# isin(): 특정 컬럼 값이 선택된 목록 안에 포함되는지 확인하는 pandas 함수
filtered = df[df["sex"].isin(sex_filter) & df["pclass"].isin(pclass_filter)]

사용자가 성별과 객실 등급을 선택할 수 있도록 사이드바에 필터를 만듭니다. 선택된 조건에 따라 이후 지표와 그래프에 사용할 데이터가 달라져요.

 

 

 

주요 지표 표시

col1, col2, col3 = st.columns(3)

col1.metric(        # 숫자 지표를 카드 형태로 보여주는 함수
    "전체 인원",      # 지표 이름
    len(filtered),  # 표시할 값
)
col2.metric("생존자 수", int(filtered["survived"].sum()))
col3.metric("생존율", f"{filtered['survived'].mean() * 100:.1f}%")

필터링된 데이터를 기준으로 전체 인원, 생존자 수, 생존율을 계산해 카드 형태로 보여줍니다.

 

`metric()`은 지표 이름과 값, 이렇게 두 가지 인자를 받는 함수입니다. 그래서 값 자리에 `f"생존자 수: {int(filtered['survived'].sum())}"`처럼 이름까지 같이 넣어버리면 안 됩니다. 이름은 첫 번째 인자 자리에, 값은 두 번째 인자 자리에 따로 넣어줘야 카드가 제대로 렌더링됩니다.

 

 

 

객실 등급별 생존율 시각화

# 본문 안에 작은 제목을 출력하는 함수
st.subheader("객실 등급별 생존율")

# plt.subplots(): matplotlib 그래프 영역을 생성하는 함수
fig, ax = plt.subplots(figsize=(6, 4))

sns.barplot(  # 그룹별 수치형 값의 평균을 막대그래프로 보여주는 함수
    data=filtered,  # 그래프에 사용할 데이터프레임
    x="pclass",  # x축: 그룹 변수
    y="survived",  # y축: 수치형 변수
    color=get_palette(1)[0],  # 막대 색상
    ax=ax,  # 그래프를 그릴 matplotlib 축 객체
)

# st.pyplot(): matplotlib 그래프를 Streamlit 화면에 출력하는 함수
st.pyplot(fig)

필터링된 데이터를 기준으로 객실 등급별 평균 생존율을 막대 그래프로 보여줍니다. seaborn 그래프는 matplotlib Figure 위에 그린 뒤 streamlit에 출력합니다. 

 

 

 

원본 데이터 표시

# st.checkbox(): 체크 여부를 True/False로 반환하는 체크박스 위젯
if st.checkbox("원본 데이터 보기"):
    # st.dataframe(): pandas DataFrame을 Streamlit 화면에 표로 출력하는 함수
    # 스크롤, 정렬 등 기본적인 인터랙션 가능
    st.dataframe(filtered)

체크박스를 선택하면 필터링 된 원본 데이터를 표 형태로 보여줍니다. 

 

 

 

나이와 요금의 관계를 plotly 산점도로 시각화

st.subheader("나이 vs 요금 (인터랙티브)")

dead_color, survived_color = get_palette(2)
fig2 = px.scatter(  # 두 수치형 변수의 관계를 산점도
    filtered,
    x="age",           # x축: 수치형 변수
    y="fare",          # y축: 수치형 변수
    color="survived",  # 점 색상을 구분할 기준 변수
    color_discrete_map={0: dead_color, 1: survived_color},
    hover_data=["sex", "pclass", "who"],  # 마우스를 올렸을 때 추가로 보여줄 컬럼 목록
)

st.plotly_chart(               # plotly 그래프를 streamlit 화면에 출력하는 함수
    fig2,                      # 출력할 plotly figure 객체
    use_container_width=True,  # True이면 화면 너비에 맞게 그래프 크기를 자동 조정
)

나이와 요금의 관계를 점으로 표시하고, 생존 여부에 따라 색상을 다르게 보여줍니다. plotly 그래프는 마우스 허보, 확대/축소 등 인터랙티브 기능을 쓸 수 있어서 seaborn이나 matplotlib보다 탐색하는 재미가 있어요.